普段はRailsのサブセットとしてのJavaScript(CoffeeScript)しか書いておらず、この手の話は浅学のため、ご指摘などコメントいただけると幸いです
1. 予備知識
Prototype
既存のオブジェクトを拡張することで機能を提供するライブラリ。
例えばArray
やString
、またグローバルな名前空間のうち、Class
やHash
といった汎用性のある名前を利用している。
このため名前の衝突が生じやすいという問題があった。
- https://ja.wikipedia.org/wiki/Prototype_JavaScript_Framework
- http://gihyo.jp/dev/feature/01/prototype/0001
jQuery
WebブラウザのためのJavaScriptを容易に記述できるライブラリ。
実装をjQuery
($
)という名前空間に集約することで、Prototypeにおける衝突の問題を解決している。
大規模アプリケーション開発
JavaScriptにおける大規模なアプリケーション開発の場合、実装をMV*に分割する必要性が生じる。
この分割を進めると、モジュール間の依存関係が生まれる。
しかし、JavaScript単体にはこれを解決するモジュールシステムは存在しなかった。
このための解決策として、後述するCommonJSが登場する。
2. モジュールシステムのためのAPI仕様
CommonJS
JavaScriptでサーバサイドを開発するために生まれた標準APIの仕様。
元々ServerJSという名前だったが、後にその他の分野にも適用可能なものになりCommonJSに改めた。
CommonJSにはファイル操作など様々なAPIの仕様が策定されているが、その中でモジュールに関するものもある。
「module
やexports
でモジュールを定義し、require
で読み込みこれを利用する」といった、現在主流になっている仕様を策定している。
AMD
Asynchronous Module Definitionの名のとおり、モジュールの非同期定義に関するAPI仕様。
当初CommonJSはブラウザ環境を考慮していなかったが、AMDはこれを考慮し、遅延読み込みに対応した。
元々はCommonJSで策定が進められていたが、後に切り離された。
API仕様の各実装
Node.jsのrequire
CommonJSのモジュールAPIの仕様に従った実装(だった)。
現在はCommonJSの仕様の枠を超え、Node.js独自の実装も行なわれている。
CommonJSの仕様を広めるきっかけになる。
Browserify
CommonJSのモジュールAPIの仕様に従って書かれたJavaScriptを、ブラウザ上で動作可能にしたモジュールシステム。
require
に指定されたモジュールを、読み込むのではなく事前にビルドすることで問題を解決する。
またこの際、依存関係も同時に解決する。
RequireJS
AMDのモジュールAPIの仕様に従った実装。
依存関係の解決は、Browserifyと異なり、ビルド時ではなく実行時に行なう。
WebPack
RequireJSやBrowserifyよりも後発のモジュールシステム。
ビルドプロセスで依存関係を解決するが、CommonJSとAMDの両方のスタイルをサポートする。
JavaScriptだけでなく、スタイルシートや画像などのアセット全般を扱うことができ、またさまざまなオプションも設定できる。
ES6のモジュール
ES6ではモジュールシステムに関する仕様が策定されている。
CommonJSの仕様に近く、export
でモジュールを定義し、import
で読み込む。
JavaScriptの標準仕様となることから、将来的にES6のモジュールに置き換わることが予想される。
3. モジュールに関する現状の実装指針
ES6のモジュールシステムを見据えつつ、BrowserifyかWebPackで目的に合った方を採用すればよい。
- http://qiita.com/mizchi/items/6b569cc75dbcc26a1f15
- http://tsuchikazu.net/javascript-module/
- http://qiita.com/megane42/items/2ab6ffd866c3f2fda066
4. 備考
パッケージ管理システム
npm
Node Package Managerの名のとおり、Node.jsにおけるパッケージ管理ツール。
Rubyでいうところのgem
。
Node.jsはブラウザに依存しないプラットフォームであるため、npmで公開されているパッケージもこれに準じている(ものが多い)。
ただし、npmは公式にフロントエンドのパッケージも登録することを呼びかけており、後述するbowerの利用は衰退するものと思われる。
- http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging
- https://twitter.com/mizchi/status/663982889705410560
bower
ブラウザ環境のためのパッケージ管理ツール。
Node.jsにおけるnpmの、ブラウザ環境バージョンのようなもの。
npmパッケージのひとつで、Twitterが開発。