Vue.js Progressive Framework 


Vue.js の作者Evan氏によるVue.jsの紹介スライドで触れられていた「Progressive Framework」の概念が非常に刺さる所があったのでVue.jsの紹介と合わせて、まとめておきます。

## 本家資料

本稿は下記Evan氏によるスライド資料をベースに、独自解釈のもと意訳したり加筆したりして作成したものです。

Progressive Framework についての解説

https://docs.google.com/presentation/d/1WnYsxRMiNEArT3xz7xXHdKeH1C-jT92VxmptghJb5Es/edit#slide=id.p

2.0の流れも含めたVue.jsの紹介

https://docs.google.com/presentation/d/1zQ3Frm3DxSw_qY-KEuykkIUREO-ueFbOyMd1Kd8nqKE/edit#slide=id.g6109b7d18_017


## Progressive Framework

### 道具と道具のコスト

フレームワークはアプリケーションの複雑さを解決するために設計されているが、一方で道具は道具固有の複雑さを持っている。

技術選択においては、このアプリケーション固有の複雑さと、道具の複雑さとに向き合わなければならない。

複雑なアプリケーションに対して、簡素な道具を以って挑むのは効果が薄いし、簡単なアプリケーションに複雑な道具を持ち出すのは大げさに感じる。

これは最近のフロントエンド辛いとかの流れでもよく見られる、技術選択の問題で、要は「仕事を始める前に適切なツールを選択しなければ」ならないという問題でもある。

おそらく今セカイには、jQuery から始まり、Riot、React、Vue.js、Backbone、Angular、Ember、Meteorと様々なJSフレームワークが存在している。

エンジニアはこれらのフレームワークの特性(Sponsorではなく)を良く理解して、適切な道具の選択を行わなければならない。

### Scalabilityの問題

適材適所とはいえ、Scalabilityの問題が無視できないケースも多々ある。

一般的にアプリケーションのScalabilityという時「拡張性」と解釈されるケースも多いが、その実Scalabilityは一方通行ではなく、その方向性は多岐に渡る。

- アプリケーションの成長・肥大化に対応するScalablity
- メインプロジェクトから分離した小プロジェクトへのスピンオフに対応するScalablity
- アプリケーションのクローンによるマルチ展開に対応するScalablity

アプリケーションのコードは、基本的なビジネスロジックの範囲内で、その規模や背景を問わず柔軟に多方面に活用可能であることが望ましい。

### Progressive Framework

[Progressive](http://ejje.weblio.jp/content/progressive) とは進歩的、進行性の、という意味の単語である。

アプリケーションがProgressiveな変化要求を持つ時、それに答えるフレームワークもまた、Progressiveでなければならない。

Vue.js は それ自体は、小規模なWebサイト上のガジェットから、小規模のSPAの制作を支えるViewライブラリでしか無いが、
vue-routerやvue-validation,vuex などの周辺コンポーネントを組み合わせることで、大規模なWebアプリ開発のニーズまでサポートする統合的な環境を提供する。

このシンプルなViewライブラリから、コンポーネントを組み合わせたVue周辺環境によるフルスタックフレームワークまでの柔軟性こそが、「Progressive」なFrameworkとしてVue.jsが有用である所以と言える。

### Vue.jsの5つの領域

[スライド](https://docs.google.com/presentation/d/1WnYsxRMiNEArT3xz7xXHdKeH1C-jT92VxmptghJb5Es/edit#slide=id.g5fc474681_041)では、Vue.jsの適用領域を主に5つのレイヤーにわけて、説明している。

- Declative Rendering
- Component System 
- Client-Side Routing 
- Large Scale State Management 
- Build System

## Declative Rendering

JS上の変数(状態)とView(HTML)とを1:1で紐付ける、宣言的なViewライブラリ。Vue.jsの基本機能に相当する。

Viewライブラリとしての動作は十分に高速で、覚えるべき文法も非常にシンプル。画面の記述には従来通りのHTMLを使用可能で、補助的に数点のVue.js拡張属性を用いる。

Vue.js の基本構文は非常にシンプルであるため、jQueryなどで基本的なJS操作を理解している人であれば誰でも簡単に始める事が出来る。

````
<html>
<head>
	<script src="vue.js">
	<script>
		new Vue({
			el: "#app",
			data: {
				messege: "hello world"
			}
		})
	
	</script>

</head>
<body id="app">
	{{message}} // ここにhello world が埋め込まれる
</body>
</html>
````

APIとの通信などで小規模なサイトガジェットを作成したり、簡単なフォームのハンドリングを行うにはこのレベルでも十分有意義に活用することが出来る。

この辺りからVue.jsを始める人はVue.js の公式ガイドからスタートすると良い。日本語で丁寧な解説があるため、無理なく学習をスタートできる 。 

https://jp.vuejs.org/guide/

## Component

コンポーネントは、WebにおけるVue.js利用が少し複雑化し、モジュール単位での分離や小規模な再利用のニーズが出てきた際に活用できる。

Vue.jsのコンポーネントは、Vue.jsメインの記述とほぼAPI的に変わる所が無いため、Vue.jsの基本的な書き方さえ理解していれば、すぐに始める事が出来る。

コンポーネントとDOMのひも付けには、カスタムタグまたは属性を用いた方式が利用可能で、コンポーネント間の値の受け渡しや入力値バリデーションもサポートする。

Componentを活用することでVue.jsの利用領域は格段に向上する。再利用可能なコンポーネントは、コードの設計に大きな可能性をもたらし、後述するRoutingやflux等の複雑な実装においても、View構成の最小単位として柔軟に様々な場面で活用される。

コンポーネントの利用に関しても日本語ドキュメントで丁寧な解説があるため、概念の理解にそう苦労することはなさそう。

https://jp.vuejs.org/guide/components.html


## Client-Side Routing 

Webサイトから、SPAなどの小規模な「Webアプリ」と呼ぶべき領域に入った時、Viewライブラリの他に、ルーティングやバリデーション等の機能が必要になってくる。

Vue.jsは本体とは別に公式のリポジトリで、ルーティングや、バリデーション等のコンポーネントを提供している。

vue-router 

https://github.com/vuejs/vue-router


vue-validator

https://github.com/vuejs/vue-validator

Vue.js はもとより様々なサードパーティライブラリと組み合わせて利用できるように設計されているが、
Vue.jsのプラグインとして開発されているこれらの公式コンポーネントは、他のコンポーネントと比べて比較的スムーズに利用する事ができる。

Vue.jsのプラグイン仕様自体は外部に開かれているため、公式に提供されるプラグインだけでなく、サードパーティ製のプラグインも自由に利用する事が出来る。

Vue.js に関連するライブラリやプラグインの一覧は

https://github.com/vuejs/awesome-vue#libraries--plugins

でまとめて紹介されている。

## Large Scale State Management 

中規模〜大規模なWebアプリケーション開発には、コンポーネント・モジュール間の依存管理や、抽象度の管理、汎用的な再利用性などの関心が高まってくる。

JSフレームワーク界隈では(Reactを中心に)fluxという考え方が話題となっているが、Vue.jsでもfluxベースのアプリ設計を支援するツールが提供されている。

vuex はVue.js向けのflux風実装であり、複雑なfluxの概念が、 Actions Mutations Store VueComponent の４層に再構築されている。

- Store : Component間で管理するApplicationの変数(状態)
- Mutations : Storeを変更するSetterとしてのイベント
- Action : Mutationイベントを発行する様々な関数
- ViewComponent : ViewComponent自体は特別な操作を加えること無く、通常通り利用可能

![https://raw.githubusercontent.com/vuejs/vuex/master/docs/en/vuex.png](https://raw.githubusercontent.com/vuejs/vuex/master/docs/en/vuex.png)

vuex ではStateの中央管理と変化の予測に強い焦点があてられている。vuexで重要なことは、これらはあくまでコンポーネント間で共有されるべきStateに関心を当てたものであるということで、コンポーネントに閉じた状態や変数については従来通りのViewComponentと同じく、Component内部の変数として記述することが出来る。

Vuex は Vue.js で大規模なアプリケーションを構築する上で非常に重要な概念であるが、Vuex を構築するStore/Mutations/ActionはVue.jsに依存すること無く、またViewComponentもVuexに依存する事無く開発を行えるというのが魅力の１つと言える。

ソース、ドキュメントは下記より

https://github.com/vuejs/vuex

## Build System

Vue.js では、継続的な開発を支えるための様々な開発ツールが提供されている。

vue-cli はVue.jsアプリケーションのシンプルなスキャフォルドとして利用可能で、Webpackやbrowserifyを利用した開発環境をコマンドラインで簡単にセットアップする事が出来る。

https://github.com/vuejs/vue-cli

vue-loaderはWebpackユーザのためのカスタムローダで、`.vue`拡張子のファイルを単一のコンポーネントとしてWebpackからビルドすることができるようになる。

riot.js 等の一部フレームワークで利用されている様なHTML/CSS/JSを全て１つのファイルで記述して単一ファイルでコンポーネントを管理する、と言ったニーズに対応可能。

単一ファイルコンポーネントでも、JADEやSCSS,Stylus,Babelと言ったAlt言語が利用可能で、またscript要素やstyle要素を利用しているため、基本HTMLとして解釈させておけばIDE上で困るケースも少ない設計となっている。

https://github.com/vuejs/vue-loader

開発者向けのChrome拡張機能も用意されている。

各種コンポーネントのデバッグや、Vuex 周りのStore変遷履歴がスナップショットで取れるなど開発に役立つ機能は大きい。

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
hogehoge

## その他

速度についてはベンチマークが公開されており、一般的なWebサイト・Webアプリ開発では十分実用的なものと思われる。

https://github.com/vuejs/vue/tree/next/benchmarks

他のフレームワークと比べて特筆すべき点としては、日本語の公式ドキュメント資料が充実している点が挙げられる。公式のドキュメントが平易な表現で始まっているため、Vue.jsのとっつきやすさと合わせて、初学者の助けになっている。

日本語のSlack チャンネルも開設されていて、イベントの情報やVue.js本体のリリース情報などが日々共有されている。

https://vuejs-jp-slackin.herokuapp.com/

## Progressive Frameworkのメリット

Vue.jsはjQueryの次のステップとして、多くの人におすすめできるくらい、小さな学習コストしか要求しないにも関わらず、その一方で大規模開発等においても適用可能な柔軟性を持っている。

HTMLの記述に独自DSLを使用する様な文化と比べ、Vue.jsは多くのユーザが最初の一歩を踏み出せるように設計されている。

これは既に言語学習済みの人にとっては見えにくいかも知れないが、現場で導入する上では大きなメリットと言える。
特に分業やチーム作業を行う際に、Componentの記述方法さえ理解できていれば、fluxライクな大規模アプリのコードを記述することが出来るというのは、メリットが大きい。
もちろんテンプレートはHTMLで記述できるため、デザイナが制作したHTMLはそのまま利用できる。

逆にVue.jsを現場に導入したものの、周辺コンポーネントの存在に気づかず、大規模開発のニーズを受けて別の大きなフレームワークに流れる…という例はよく目にする。
Vue.js ＝　Progressive Frameworkという認識が広まる中で、Vue.jsに「HTML/JSで記述可能なごく小さなViewライブラリ」と「fluxベースの開発にもたえる大規模開発向けフレームワーク」の2つの顔があるという認識が広まってくれるとありがたい。

公式プラグインは本体と非常に密な関係で開発が進められており、Vue.js 2.0 のリリースにおいても周辺コンポーネントの2.0対応はスムーズに進められている。
Vue.js はそれ本体だけでなく、周辺のコンポーネントまで合わせた Vue.js + αという認識で理解を進めると、このフレームワークの本質が見えてくるのかも知れない。

## v2.0.0

v2.0.0 では仮想DOMの仕組みが導入され、副作用としてSSRが利用可能になる。

ややこしい事は抜きにして、 **「より高速」** になった Vue.jsが **「v1とほとんど変わらないAPIで」** 利用可能という話を聞けば、凄さを理解してもらえるかもしれない。

仮想DOMといってもVue.jsの手軽さは変わらない。むしろVue.js v1のコードは多くの場合、ほとんどの改修を加えずにv2へと移行できる。
少し前の aplha.8 リリースの頃の記事ではあるものの、[Vue.js のv1とv2を全く同じコードで動かしてパフォーマンス検証してみた記事](http://qiita.com/mikakane/items/78614572d964420e7e31)もあるので、詳しくはそちらを確認してもらいたい。

Vue.js 同様、HTMLベース+Vue.jsの独自属性で記述した画面は、Vue.jsの機能によって自動的に仮想DOMに置き換えられる。仮想DOMのために独自DSLを覚えなければならない時代はもう過去の話のようだ。

ともかく、私も含め仮想DOMが一体何の事かわからないおそらく大半のユーザにとってはv2は、「ちょっと早くなった」程度の認識でv1とほぼ同様に扱う事が出来る。周辺コンポーネントの準備もほぼ揃っている状況。

SSRの話はあくまでオプション的に利用可能、というだけでそれによって従来からのVue.jsの利用のスタイルが何か変わるというわけではない。必要なければ無視してしまっても一向に問題ない。

今まで通りの使い方を軸に、「新しい課題」に対して「新しいステップ」で課題を解決出来るのがProgressive Framework の利点とも言える。

とはいえ、Vue.js 2.0 によるSSRを試しておきたい人も居ると思うので、サンプルのリポジトリを下記に掲載しておく。

https://github.com/vuejs/vue-hackernews-2.0