JavaScript でモジュールを使う時なんかによくでてくる CommonJS ですが、今までなんとなくでやり過ごして来ていたので改めておさらいしてみました。
CommonJSってなんだ
そもそも CommonJS とは何かと言うと、JavaScript の仕様を作っているプロジェクトです。
JavaScript の仕様というと ECMAScript を連想する方も多いと思いますが、ECMAScript はブラウザ上での JavaScript の仕様と標準を作っているのに対し、CommonJS ではブラウザ上だけでなく、サーバーサイドやクライアントでのCUI、GUI で JavaScript を使う際の仕様を作成しています。
単に仕様を作っているだけなので、ECMAScript に組み込まれるとかがない限り、それが JavaScript の標準になるというわけではないようです。
ちなみに CommonJS で作成された仕様は複数のソフトウェアによって実装が行われることで勧告段階に移るみたいです。
CommonJS の仕様を実装しているソフトウェアの中にはあの有名な node.js があります。
CommonJS のモジュールシステム
CommonJS のモジュールシステムは CommonJS が作成している仕様の中の一つです。
1.0、1.1、1.1.1 とバージョンがあり、1.1 が勧告段階にあるようなので、1.0からこの2つをみていきます。
CommonJS Modules/1.0
JavaScript にモジュールの概念を取り入れた、とてもシンプルな仕様です。
まず前提として、以下の2つがあります。
- 各jsファイルをモジュールとして扱う
- 各モジュールは独自にスコープを持つ
そしてモジュールをインポートするための require()
関数、モジュールから変数や関数などをエクスポートするための exports
オブジェクトが定義されています。
node.js で使用できる module.exports
は CommonJS の仕様ではなく、node.js による独自拡張です。
exports オブジェクト
モジュール内の変数や関数に外からアクセスできるようにするためのオブジェクトです。
exports
オブジェクトに直接格納するのではなく、exports
オブジェクトのプロパティとして追加します。
// math.js exports.add = function(a, b) { return a + b; }
require() 関数
モジュールをインポートするための関数です。引数は1つで、文字列としてモジュールIDをとります。返り値として、モジュール内でエクスポートされたオブジェクトが返ります。
モジュールIDは基本的に相対パスか絶対パスから拡張子を除いた文字列となります。
// script.js var math = require('./math'); console.log(math.add(1, 3)); // 4
返り値にモジュール内でエクスポートされたオブジェクトが格納されています。
CommonJS Modules/1.1
1.1 では 1.0 に加え、モジュールのメタ情報に関するプロパティが追加されました。ただし全て必須ではないので 、1.0 に準拠していれば自動的に 1.1 に準拠しているということになります。
node.js では以下のうちの require.main
と module.id
が実装されています。
require()
関数に2つ、新しく追加された module
オブジェクトに2つプロパティが追加されています。
require.main
エントリポイントとなったモジュールが格納されたプロパティです。
require.paths
モジュールの検索パスが格納された配列プロパティです。
module.id
モジュールIDが格納されたプロパティです。
module.uri
モジュールのURIが格納されたプロパティです。
モジュールのファイル位置ってことでいいかな?よくわかりませんでした。
ES6 から追加されたモジュールシステムとの互換性
残念ながら無いようです。
おさらいしといてなんですが、今後は ES6 のモジュールシステムが主流になるのでしょうか?