従来からの JavaScript の書き方だと「定義」するときにグルーバル環境を汚染してしまう課題があった。
window.Hoge
みたいに書いてしまう問題。
回避策はたくさんあるけど、人によって書き方が異なると「使う」ときに大変。
特に複数のライブラリが依存し合うスクリプトの場合、読み込み順序に気を配る必要がある。
こうした "Definition" と "Dependency References" の課題を解決する方法のひとつとして
AMD (Asynchronous Module Definition) がある。
- AMD
- WHY AMD?
- Toward JavaScript Standards: CommonJS and AMD
- Writing Modular JavaScript With AMD, CommonJS & ES Harmony
ライブラリコードを書くときは define
で定義し、
それを使うときは require
で依存性を解決する。
この作法に則ってないライブラリを使うときはそれなりに工夫が必要だったりする。
define
, require
の基本はだいたい一緒。
JavaScript 以外のリソース (テンプレートとなるテキストなど) を読み込む場合や、
AMD 非対応のスクリプトを読み込むときの設定などがちょっと違う。
いずれにしても、プロダクション環境に配置するときはビルドした最適化版を配置する。 Closure Compiler や r.js などを使う。
jQuery now supports the AMD API. Note that jQuery 1.7 is not a script loader itself; it cooperates with AMD-compliant loaders such as RequireJS or curl.js so it can be loaded dynamically and the ready event can be controlled by the loader.
Backbone と Underscore は AMD をサポートしていない。
- Why did Underscore.js remove support for AMD?
- Remove AMD/require.js support
- Register as AMD module, but still export a global
しかし、代替ライブラリもあるし、ラッパーもある。
-
- An alternative to Underscore.js, delivering consistency, customization, performance, and extra features.
- Features --> AMD loader support (RequireJS, curl.js, etc.)
Bower で検索すると出てくる。
D3.js (Data-Driven Documents) はビルドスクリプトで頑張ってサポートしようとしている。
グローバル変数を利用する shim を使う場合は how to integrate d3 with require.js の回答にあるように設定する。 (回答者は requirejs の作者)
- requirejs.config({
- shim: {
- d3: {
- exports: 'd3'
}
}
});
JavaScript 自体に import 機構がないことに起因した課題。 サーバサイドでもクライアントサイドでも JavaScript を使う時代になってきたので、 スクリプトのポータビリティが高いに超したことはない。 冒頭に挙げた Writing Modular JavaScript With AMD, CommonJS & ES Harmony が全てではあるが、現実的には ES Harmony まで見越した実装は難しいので、 まずは RequireJS + AMD でモジュール性を確保した書き方を身につけられると良い。