今日、私はAngularJSプロジェクトにBrowserifyを採用していますが、非常に不明確なことがあります。すべての例とブログ投稿で、次のようなものを見ました。
require('./messages');
angular.module('sling', ['sling.messages']);
exports = angular.module('sling.messages', [])
.controller('MessagesListCtrl', require('./MessagesListCtrl'));
module.exports = function() {
// ...
});
確かに、これは動作しますが、なぜこれを行うのですか?私はこれをこのように実装しましたが、それは絶対にうまく機能し、AngularJSプロジェクトではより普通に感じます:
require('./messages');
angular.module('sling', ['sling.messages']);
angular.module('sling.messages', []);
require('./MessagesListCtrl');
angular.module('sling.messages').controller('MessagesListCtrl', function() {
// ...
});
つまり、exports/module.exportsを完全にスキップし、require
を使用して基本的にコントローラー、サービス、フィルターなどのファイルを含めるだけです。
これは正しいことですか?私はそれがすべてうまくいくことを意味しますが、私は後でトラブルになりそうですか?
Browserifyを使用する主な(そして正直な唯一の)理由は、ブラウザにCommonJSモジュール(つまりNodeJSモジュール)を含める場合です。 CommonJSモジュールは、暗黙的な「モジュール」スコープを持つことにより、グローバルスコープの外に留まります。すべてのモジュールが持っている「エクスポート」オブジェクトを拡張することにより、モジュールスコープ(通常はモジュールのエントリポイントまたは主要機能)から何を公開するかを選択します。
したがって、「実際の」CommonJSモジュールは次のようになります。
ファイルA:
// a.js
function doSomething() {
console.log("I am doing something");
}
module.exports = doSomething
ファイルB:
// b.js
doSomething();
// Exception - attempt to call a non-existent function
ファイルC:
// c.js
var doSomething = require('a');
doSomething();
// logs "I am doing something"
モジュールスコープのないブラウザでは、a.js
がdoSomething関数でグローバルスコープを拡張します。これは、グローバルとして宣言されているためです。 Browserifyは、バンドルされた各モジュールを関数ラッパーにラップし、このラッパーへの引数として含まれるモジュールに「エクスポート」オブジェクトを提供することにより、これを回避します。
AngularJSを入力します。ここで使用できるアプローチは2つありますが、require( 'angular')を使用していないことが最初であるという事実から推測します。
Browserifyを使用してモジュールスコープを提供し、プロジェクトの主要な依存関係をウィンドウグローバルにするのは奇妙なため、2番目のアプローチを好む傾向があります。
ただし、AngularJSには独自の依存関係注入駆動型モジュールシステムが既にあります。 angularJSコンポーネントを宣言するとき、それらはangular
オブジェクトにアタッチされているモジュールオブジェクトにアタッチしています。これは、Angularの場合、angularJSモジュールファイルのexports
オブジェクトが本質的に冗長であることを意味します。ファイルが実行される限り、angular
オブジェクトはモジュールとコンポーネントで拡張されるためです。
そうしないと、Browserifyはファイルをバンドルせず、実行されず、モジュールでangular
オブジェクトを拡張することもないため、ファイルを「必要」にする必要があります。ただし、angular
オブジェクトがエクスポートであるため、Angularのエクスポートに何かを追加するのにneedを使用しないでください。
それでは、なぜCommonJSモジュールとエクスポートがどのように機能するかを説明するのにこの時間を費やしたのでしょうか?なぜなら、Browserifyを使用するother理由は、ブラウザアプリケーションでNPMでホストされているモジュールを使用できるようにするためです。これらのモジュールのほとんどは非角形のcommonJSモジュールです。つまり、それらの機能はエクスポートによって公開されます。この場合、上記のc.js
で行っているように、必要なときにそれらのエクスポートを変数にキャプチャすることが重要です。同様に、いくつかのモジュールを作成してNPMにリリースすると、ユーザーはモジュールのエントリポイントをpackage.json
でmainとして宣言されたファイルのexports
オブジェクトに追加することを期待します。