ソースコードのファイルが複数存在する場合、どのプラットフォームでもコード管理に必須とされる機能の一つに module が存在する。今までの JavaScript では module をサポートしていなかった結果、CommonJS modules (partially implemented by node.js) や require.jsといった module 機能を追加する様々なライブラリが開発された。一方で、JavaScriptの次期バージョン(公式では ECMAScript 6 と名付けられている)以降、ついに module が言語レベルでのファーストクラスとして扱われる。Axel Rauschmayer 氏は introductory article about ECMAScript 6 modules という記事で、ECMAScript 6 における module はどの様なもので、どの様に利用するものか、現時点でどの様に moudle を利用するか(transpiler を利用している)を記載している。
Axel氏は、ECMAScript 6 (ES6) の module に対し、設計の目的を以下の様に説明してる。
ECMAScript 6 module の目的は、CommonJS Modules (CJS) と Asynchronous Module Definition (AMD) 両方の利用者にメリットがある形式を作ることだ。最終的な文法は CJS の様にコンパクトになる。一方で、CJS と比べて動的な機能が少なくなっている(例:通常の構文では、モジュールの条件付き読み込みができない)。これには、主に二つの利点がある。
- export されていないものを import しようとした場合、コンパイル時にエラーを取得できる
- ES6 moduleの非同期に読み込みを容易に行える
ES6 module の標準には二つの責務がある。
- 宣言構文(import と export 用)
- プログラムでのロード用API(モジュールをどう読み込むか、条件付きモジュール読み込み)
ES6 module の機能を利用することで、JavaScript ファイル全体を一つのオブジェクトやクロージャ内に不恰好に押し込める方法等、以前のブラウザではを開発者が行っていた実現方法は不要になる。代わりに、トップレベルで定義を指定する必要があり、関数と変数のみが宣言可能だ。明示的に公開を定義したもののみ、モジュールの利用側から参照することができる。
var privateVar = "this is a variable private to the module"; export var publicVar = "and this one is public"; export function returnPrivateVar() { return privateVar; };
上記のコードを mymodule.js として保存した場合、指定した関数と変数のみインポートする方法と module object としてインポートする方法の二つの方法で import することが可能だ。
import { returnPrivateVar, publicVar } from 'mymodule'; console.log(returnPrivateVar());
// またはこちらが利用可能 import 'mymodule' as mm; console.log(mm.returnPrivateVar());
新しい module 標準は、モジュールの動的ロードに対するインライン定義をサポートしている。当該機能について更に学習する場合、Axel 氏の記事 を通読することを推奨する。
現時点で新しい module 構文を試したい場合、以下の様に利用可能な候補がいくつか存在する。
- es6-module-transpiler は、ES6 モジュールを AMD または CJS 形式のモジュールにコンパイルする
- ES6 module loader は、ES6 形式モジュールの読み込みをサポートする Polyfill(新しい環境を基準にし、古い環境を新しい環境に近づけて差をなくす方法)だ
- require-hm は、ES7 モジュールの読み込みをサポートする require.js プラグインだ
- Traceur は、Google の transpiler であり、ES6 モジュールを含む Javascript の機能を多数サポートすることが目的だ
- TypeScript は、Microsoft が作成した JavaScript の実装の一つであり、ES6 モジュールをサポートしている