コードをモジュール化するために、次のクロージャ パターンを使用しています。
(function(root) {
// MODULE CODE HERE
if (typeof module !== 'undefined' && module.exports) { // CommonJS
/* var dependencies = require(...) */
module.exports = myModule;
} else if (typeof define !== 'undefined' && define.amd) { // AMD
/* var dependencies...; */
define([/* dependencies */], function(/* dependencies */) {
/* Assign closure level vars to respective arguments */
return myModule;
});
} else {
// Dependencies??
root.myModule = myModule;
}
})(this);
つまり、機能検出を使用して、CommonJS モジュール (node.js など)、AMD、または基本的なグローバル名前空間のインスタンス化をサポートします。
これは node.js で正常に機能します。私はまだそれを読んでいるので、AMD パターンをまだテストしていません(編集 2 を参照してください: AMD はまったく同じ効果を示します)。ただし、モジュールに依存関係がある場合、ブラウザーでは失敗します。つまり、たとえばmyModule
、別のモジュールで定義されているものを参照する場合: たとえば、上記のようにsuper.js
、child.js
それぞれのモジュール定義を使用して、 (ブラウザーで)super.js
という関数を作成するとします。のようなものを取得します。root.super
root === window
child.js
super()
super is not a function
何が起きてる?
それを修正するために、要素に読み込まれるsuper.js
との順序を変更しました。次に、jQuery を使用して、ドキュメントの準備ができたら強制的にロードしようとしました。child.js
<script>
child.js
$(document).ready(function() {
$.getScript('child.js', function() {
// Do stuff with child, which calls super
});
});
...再び、同じ問題。ただし、どちらの場合も、コンソールに入ると、super
期待どおりに利用可能で定義されています。
おそらく異なる(つまり、グローバルではない)スコープからのものsuper
であると思われるのはなぜですか?child.js
CommonJS エクスポートで依存性注入ビットを削除すると、node.js で同じエラーが発生して失敗します (依存性がある場合)。
EDIT @Amberlampsの回答で問題は解決しましたが、なぜこれが発生するのかという質問には回答しませんでした。私のモジュールパターンは次のとおりです。
(function(root) {
// MODULE CODE HERE
if (typeof module !== 'undefined' && module.exports) { // CommonJS
/* var dependencies = require(...) */
module.exports = myModule;
} else if (typeof define !== 'undefined' && define.amd) { // AMD
/* var dependencies...; */
define([/* dependencies */], function(/* dependencies */) {
/* Assign closure level vars to respective arguments */
return myModule;
});
} else {
if (root.hasOwnProperty(/* dependencies */)) {
/* var dependencies = root... */
root.myModule = myModule;
}
}
})(this);
これにより、環境間で依存関係が共通の名前で保持されます。ただし、疑問が残ります。グローバル オブジェクトがクロージャのスコープ内で使用できないのはなぜですか?
EDIT 2私は RequireJS と AMD を試していて、AMD が機能するように上記のコードを修正しました。この場合もまったく同じことが起こります。グローバルオブジェクトをクロージャー内で使用できるようにするには、クロージャー内の変数に明示的に割り当てる必要があります...