はじめに
これまでの連載で、Vue.jsの基礎文法やコンポーネントを学習し、Vue Routerを使ってシングルページアプリケーションの基本的な実装を行いました。連載最終回である今回は、より現場を意識した実践的なアプリケーションの開発について紹介します。
これまでの連載ではVue.jsの気軽に使えるメリットや本質的な機能を理解してもらうために、ES5のJavaScriptを使い、各種のコマンドラインツールなしで解説してきました。より実践向きな高度なアプリケーション開発になるため、ES2015以降のJavaScriptを使用し、エディタ、コマンドラインや開発を補助するライブラリなどの様々なツールを活用しながら学習していきます。
vue-cliによるアプリケーション開発
前準備
開発にnpm(Node.js)を利用します。Node.jsは日本語公式サイトを参考にインストールしてください。npmはNode.jsのパッケージマネージャで、Node.jsをインストールすると標準でインストールされます。Node.jsは執筆時点の最新安定バージョンのv6.9.2を使用します。
vue-cli
vue-cliとは、Vue.js向けのアプリケーション開発環境をセットアップする公式のコマンドラインツールです。
JavaScriptでアプリケーションを構築する場合、モジュール化、バンドラー/プリプロセッサによるビルド、JavaScriptの静的構文チェック(Lint)、単体テストやE2Eテストなどが必要になります。これらを満たした開発環境のセットアップは長期的なメンテナンスと開発の生産性を考えると必須とも言えますが、自分で一から用意するのはかなりの手間で、徒労感の伴う作業となるでしょう。この面倒なアプリケーション開発環境のセットアップを担ってくれるのがvue-cilと呼ばれるコマンドラインツールです。これによりすぐにVue.jsアプリケーションの開発に着手できます。
vue-cliのインストール
では、さっそくvue-cliを使ってVue.jsのアプリケーション開発環境を整えてみましょう。まずは、npmでvue-cliをインストールします。
インストールが完了したら、vueコマンドが使用できるようになります。試しに以下のvue-cliのバージョンを確認するコマンドを実行してみましょう。
本稿では執筆時点での最新バージョンである2.6.0を使用します。
アプリケーションプロジェクトの作成
vue-cliのインストールが完了したら、テンプレートを利用してアプリケーション開発環境をセットアップします。Vue.jsは公式にVue.jsアプリケーションプロジェクトテンプレートをいくつか提供しています。最も人気のwebpackプロジェクトテンプレートを使用し、vue-cli-gihyo-exampleという名前でアプリケーションプロジェクトを作成することにします。
上記コマンドを実行すると、コマンドライン上でプロジェクト名やLint、テストなどのセットアップの有無を対話的に問われます。今回は以下のように設定します(Authorの部分はコマンドライン実行環境によって変わります)。
入力が完了すると下記の内容が出力され、vue-cli-gihyo-exampleというディレクトリにVue.jsアプリケーションプロジェクトがセットアップされます。
出力されたメッセージには、開発を始めるために実行するべきコマンドと、webpackプロジェクトテンプレートの公式ドキュメントの参照先URLが出力されます。
アプリケーションの開発を開始する
Vue.jsアプリケーションプロジェクトのセットアップが完了したので、前節のvue-cliによるセットアップにおいて出力された内容に従って進めてみます。
npm install
でVue.jsアプリケーション開発に必要な依存モジュールのインストールが完了します。
次にnpm run dev
で動作確認のための開発用サーバが起動すると、ブラウザが起動し図1の内容が表示されるのを確認できるはずです。
最小限に動作するアプリケーションの雛形となるコードが生成されています。以降は、これをベースにして開発していきます。
単一ファイルコンポーネントによるモジュール化
vue-cliでVue.jsアプリケーションプロジェクトをセットアップし開発の準備ができました。
単一ファイルコンポーネントとは
早速実践として開発の紹介に入りたいところですが、ここではvue-cliを使った開発では理解の欠かせない単一ファイルコンポーネントについて紹介します。
vue-cliでセットアップしたVue.jsアプリケーションプロジェクトでは、コンポーネントのモジュール管理は単一ファイルコンポーネント(Single File Components)で行います。
単一ファイルコンポーネントとは、.vue
拡張子ファイル内に定義したコンポーネントで、以下の例のような要素で構成されたHTMLベースのシンタックスのものです。
<template>
タグ: コンポーネントにおいてUIのセマンティックな構造をテンプレートとして定義する要素です。HTMLの他、Mustache記法、v-ifなどのVue.jsで提供する文法がそのまま利用可能です。
<style>
タグ: コンポーネントにおいてUIの見た目を制御する要素です。CSSを使用して定義することができます。
<script>
タグ: コンポーネントにおいてUIの振る舞いを制御する要素です。JavaScriptを使用することができ、連載第3回で解説した同じ作法でコンポーネント定義が必要です。
単一ファイルコンポーネントの例を以下に示します。
従来のWeb標準の技術構成(HTML, CSS, JavaScript)でコンポーネントを定義することができるので学習コストはほぼありません。単一ファイルコンポーネントはその名の通り、1つのファイルに1つしかコンポーネントを定義できません。
第3回で、Vue.component/componentsオプション
によるUIをコンポーネント化する仕組みを紹介しましたが、この仕組みとexport/import(commonJSの場合はrequire)
を使用することによりモジュール化は可能です。
しかしながら、単一ファイルコンポーネントは先の例の通り、要素を役割ごとに明確に区分してファイルごとに定義できるため、保守性と再利用性の高いコンポーネントの実装ができる点でより優れていると言えるでしょう。
vue-cliによりセットアップされたアプリケーションプロジェクトでは、標準で単一ファイルコンポーネントを利用するための環境がセットアップされています。使わない理由はありません。
単一ファイルコンポーネントの使用方法
単一ファイルコンポーネントは、バンドルツールとして、webpackならvue-loader、browserifyの場合はvueifyを使って最終的にVue.jsのVue.component/componentsオプション
に登録可能なオブジェクトに変換します。このため、コンポーネントの利用方法は従来と変わりません。以下は、単一ファイルコンポーネントを使用する例です。
単一ファイルコンポーネントのその他機能
その他に、単一ファイルコンポーネントは以下のような開発をより効率化する機能を提供しています。
- BabelによるES2015以降のJavaScript
- スコープ付きCSS(Scoped CSS)
- PostCSSによるCSSプロセッサ
- CSS ModulesによるCSSのモジュール化
- プリプロセッサ(Pre-Processor)による多言語(Pug/SaSS/CoffeeScriptなど)による単一ファイルコンポーネントの使用
- ホットリロード(Hot Reload)による開発時のライブリロード
これらを使用することでさらに生産性と再利用性の高いコンポーネントのモジュール化が可能になります。詳細についてはドキュメント(vue-loader)を参照してください。
単一ファイルコンポーネントの作成
単一ファイルコンポーネントについて簡単ですが解説しました。vue-cliでセットアップしたVue.jsアプリケーションプロジェクトをベースに開発できる状態になったので、実際に単一ファイルコンポーネントを実装してみましょう。先ほど単一ファイルコンポーネントの解説で使用した単純なメッセージを表示するコンポーネントを少し改造して、以下のようなmsg
プロパティ経由でメッセージが表示し、デフォルトメッセージを持ったHelloコンポーネントを実装します。
vue-cliによってHelloコンポーネントとしてセットアップされているので、このコンポーネントの実装内容を先の今回の実装のものに置き換えます。エディタでsrc/components/Hello.vue
を開いて置き換えて保存してください。その結果、ブラウザには図2のような画面が出力されるかと思います。
'こんにちは!'というメッセージがVue.jsのロゴの下に表示されるのをブラウザで確認できましたでしょうか?表示内容が初期のものと変わっていることを確認できたと思います。これは、アプリケーションのコード変更を検知して更新するホットリロードと呼ばれるもので、本稿でセットアップしたwebpackアプリケーションプロジェクトの開発環境に含まれています。リロードの手間がなくなり、開発生産性を大きく高めてくれます。
さて、Helloコンポーネントはmsg
プロパティに文字列値を設定するとその文字列値が表示される仕様になっているので、ここでmsg
プロパティに文字列値を設定してみましょう。エディタで、src/App.vue
を開いて内容をtemplateタグの実装内容を以下のように変更してください。
この結果、図3のように'ようこそ!'というメッセージがVue.jsのロゴの下に表示されるのを確認できるかと思います。
単一ファイルコンポーネント作成を体験することができました。初期にセットアップされているコンポーネントで単一ファイルコンポーネントを実装していきました。新規にコンポーネントを作成する場合は、アプリケーションプロジェクトとしてセットアップされたコードが管理されるsrc
ディレクトリ配下に、新規に.vue
ファイルを作成してコンポーネントを実装するとよいでしょう。
テスト
実際のアプリケーション開発においては単体テスト、E2Eテストをすることでアプリケーションが正しく動作しているかどうか検証を行います。単体テストとE2Eテストの環境が今回は既にセットアップされているのですぐに着手できます。Vue.jsにおけるコンポーネントの単体テストを試してみましょう。
このコマンドを実行すると、セットアップされたKarma、webpackおよびPhantomJSといったツールや実行環境によってtest/unit/
配下にある単体テストコードが実行されテスト結果が出力されます。以下はその内容のテスト結果の部分抜粋です。
テストが失敗していることがわかります。これは、vue-cliによって初期セットアップされたHelloコンポーネントの単体テストの実行結果です。解説にあたってHelloコンポーネントの実装内容を変更したので、それにともなってテストが失敗しています。
ここで変更したHelloコンポーネントの動作内容を検証する単体テストを実装してみましょう。エディタでtest/unit/specs/Hello.spec.js
を開いて以下のように単体テストを実装します。
上記の単体テストコードは、本稿のvue-cliでセットアップされたMochaとChaiという単体テスト向けのライブラリを使用しています。
いくつかDOMを操作するブラウザ環境に依存したコードが入っていますが、それ以外はNode.jsでも実行できるシンプルな単体テストになっていて難しくはありません。Helloコンポーネントは単一ファイルコンポーネントで実装されており、オブジェクトに変換されるので、公式ドキュメントに従って上記の単体テストの実装のようにコンポーネントをインポートして、動作を検証するコードを実装するだけです。
単体テストを実装したので、npm run unit
コマンドで検証してみましょう。以下に抜粋するような検証がパスしているテスト結果が出力されることを確認できましたでしょうか?
今回は単体テストのみでしたが、Nightwatchを利用したE2Eテストも可能になっています。今回は解説しませんが、こちらも初期のテストコードがtest/e2e/specs
配下にセットアップされているので、こちらにテストを実装してアプリケーションの動作検証をするとよいでしょう。
デバッグ
JavaScriptによるフロントエンドのアプリケーション開発においてデバッグにはいろいろ方法がありますが、そのうちの1つとしてコンソール出力(console.log)による、いわゆるプリントデバッグがあります。しかしながら、Vue.jsにおいてはコンポーネントの組合せによってツリー構造をもったUIとしてアプリケーションが構築されるため、この方法では非常に非効率です。Vue.jsは公式にvue-devtoolsというGoogle Chrome向けに拡張機能を提供しています。これを利用するとデバッグの効率が大きく上昇するでしょう。
本稿で作成しているアプリケーションをvue-devtoolsでデバッグしているときの画面の様子は図4のようになります。
上記のようにvue-devtoolsは、Web開発者がよく使用するDevtoolsに統合されておりVue.jsのコンポーネントをツリー形式でグラフィカルに確認することができます。また、コンポーネントの状態値(コンポーネントオプションのprops/data)の値も確認することができるため大変便利です。Vuexにも対応しているので、Vuexのstoreのデバッグも対応可能です。vue-devtoolsを利用してVue.jsアプリケーションのデバッグの生産性を高めることをお勧めします。
ビルド
単一ファイルコンポーネントを実装し、単体テストによるコンポーネントの動作検証、デバッグを学びました。いよいよリリースするためにビルドを行います。
一般にJavaScriptによるフロントエンドエンドのアプリケーションはビルドにwebpackやbrowserifyなどのツールを使用します。これらを使うことでJavaScriptはもちろん、HTML、CSSそして画像/フォントなどのアプリケーションの動作に必要なリソース一式をリリース可能なアセットとしてバンドリングできます。こういったリソースのバンドリングはいかにツールを使ったとしても、Babelなどのトランスパイラの設定、JavaScriptコードのミニファイ化/ソースマップ出力、警告メッセージをはじめとするデバッグコードの除去などの諸々の設定が必要になります。多くの場合は大変な作業です。
vue-cliで生成したVue.jsアプリケーションプロジェクトは、こういったビルドに必要なための設定作業がほぼゼロになるようになっています。具体的には、ビルド設定ファイルおよびビルドスクリプトをwebpack/browserifyのツールに応じてbuild
ディレクトリ配下に出力します。このため設定作業の必要はなく、すぐビルドできます。
それでは以下のコマンドでビルドしてみましょう。
ビルド結果内容をビルドが完了し、結果が出力されます(出力メッセージ内容は実行環境によって異なります)。
上記コマンドで、アプリケーションのリソース一式がビルドされたアセットはdist
ディレクトリに出力されます。こうしてビルドされたアセットを、Vue.jsアプリケーションとしてHTTPサーバにデプロイして配信可能になります。
さらに高度なアプリケーションを開発するためのその他の機能
Vue.jsにはこれまでの連載や今回紹介したvue-cli、単一コンポーネントの他にも、以下のような多くの高度な機能が利用できます。
- スロット
- トランジション
- カスタイムディレクティブ
- ミックスイン
- プラグイン
- 描画関数
- サーバサイドレンダリング
この中から、スロットとトランジションをピックアップして簡単に紹介します。
スロット
スロットを利用してコンポーネントに対して外部からコンテンツを挿入できます。以下はスロットを使ったModalコンポーネントの例です。
名前付きスロット(named slot)を利用して、モーダルのヘッダー、ボディ、フッターの各コンテンツ部分に外部から挿入できるようにしています。このModalコンポーネントを使用したコンテンツの挿入は以下です。
上記の例では、h3要素にslot
属性として"header"が指定されているので、Modalコンポーネントは定義された名前付きslotの"header"にこのコンテンツが挿入して描画します。このようにslotを利用することで再利用可能なコンポーネントを作成できます。
トランジション
要素が挿入、削除されるタイミングで遷移効果を与えるアニメーションを制御できます。以下は、transition
コンポーネントを使ったトランジションの例です。
Vue.jsのトランジションは、上記のようにトランジション対象となる要素をラップして使用します。CSSを使ったトランジションの定義も必要です。
上記では、要素が挿入されたときのCSSトランジション、要素が削除されたときのCSSトランジションを使用したトランジションクラスを定義しています。本稿で詳しく説明しませんが、このようなトランジションクラスは、Vue.jsのトランジションクラスの命名規則に従って定義する必要があります。Vue.jsのトランジションでは、要素の挿入・削除時にハンドリングして、これらCSSトランジションが定義されたトランジションクラスを対象となる要素のclass属性に適用することで、トランジションを実現しています。
以上、これまでのスロットとトランジションにおいて掲載した例をModalコンポーネントとして実装したものを、以下のjsfiddleに掲載しておきます。
スロットとトランジションの詳細や解説しなかったその他の機能については、日本語公式ドキュメントにて詳細を確認してください。
おわりに
最終回では、vue-cliを使ったアプリケーション開発について紹介しました。
vue-cliというVue.jsアプリケーションプロジェクトのテンプレートを生成するツールを利用することで、さまざまなツールの設定や開発環境のセットアップを簡略化して、すぐに開発に着手することを実感できたのではないでしょうか。
今回学習用に作成したアプリケーションプロジェクトは筆者のレポジトリに公開しています。参考にしてください。
本連載記事によって、Vue.jsのアプリケーションの作成ができるようにはなりました。Vue.jsの全てについて解説出来たわけではありません。さらにVue.jsは日々進化を続けています。ぜひ、日本語公式ドキュメントを読んで理解を深め、知識をアップデートしてください。
本連載の執筆メンバーで運営するSlackを使った日本人向けのVue.jsユーザーコミュニティもVue.jsを学ぶうえでは力になるはずです。こちらから登録できます。こちらのコミュニティでは、Vue.jsでわからないことの質問と回答、Vue.jsの事例や最新情報の共有が盛んに行われており、Vue.jsユーザー同士でコミュニケーションできる場となっております。興味がある方は、ぜひ登録してください。
それではご愛読ありがとうございました。