RequireJSの他のモジュールを「動的に」ロードするモジュールを定義する方法はありますか?はいの場合、オプティマイザー(r.js)はどのように/いつモジュールを含める必要があるかを理解しますか?
たとえば、dynModules
を名前/パスのペアを定義するモジュールとします。
define([], function () {
return ['moduleA', 'moduleB']; // Array of module names
});
別のモジュールは、配列に基づいてモジュールを動的にロードします。これは動作しません:
define(['dyn_modules'], function (dynModules) {
for(name in dynModules) {
var module = require(path); // Call RequireJS require
}
// ...
});
...私に与えます:
不明なエラー:モジュール名「moduleA」はコンテキスト_に対してまだロードされていません。 require([]) http://requirejs.org/docs/errors.html#notloaded を使用します
エラーを解決することができますが、それはもう「動的」ではありません:
define(['dyn_modules', 'moduleA', 'moduleB'], function (dynModules) {
for(name in dynModules) {
var module = require(path); // Call RequireJS require
}
// ...
});
制限は、単純化されたCommonJS構文と通常のコールバック構文に関連しています。
モジュールのロードは、ダウンロードのタイミングが不明なため、本質的に非同期プロセスです。ただし、サーバー側のCommonJS仕様のエミュレーションにおけるRequireJSは、単純化された構文を提供しようとします。このようなことをするとき:
var foomodule = require('foo');
// do something with fooModule
舞台裏で行われているのは、RequireJSが関数コードの本体を調べて、「foo」が必要であることを解析し、関数の実行前にそれをロードしていることです。ただし、変数など、単純な文字列以外のもの(例など).
var module = require(path); // Call RequireJS require
...次に、Requireはこれを解析して自動的に変換することができません。解決策は、コールバック構文に変換することです。
var moduleName = 'foo';
require([moduleName], function(fooModule){
// do something with fooModule
})
上記を考えると、標準構文を使用するための2番目の例を書き直すことができます。
define(['dyn_modules'], function (dynModules) {
require(dynModules, function(){
// use arguments since you don't know how many modules you're getting in the callback
for (var i = 0; i < arguments.length; i++){
var mymodule = arguments[i];
// do something with mymodule...
}
});
});
編集:あなた自身の答えから、アンダースコア/ロダッシュを使用していることがわかります。したがって、_.values
と_.object
を使用すると、上記のように引数配列のループを簡素化できます。
自分に答えます。 RequireJS Webサイトから:
//THIS WILL FAIL
define(['require'], function (require) {
var namedModule = require('name');
});
Requirejsは、上記のファクトリー関数を呼び出す前にすべての依存関係をロードして実行する必要があるため、これは失敗します。 [...]したがって、依存関係配列を渡さないか、依存関係配列を使用している場合は、その中のすべての依存関係をリストします。
私の解決策:
// Modules configuration (modules that will be used as Jade helpers)
define(function () {
return {
'moment': 'path/to/moment',
'filesize': 'path/to/filesize',
'_': 'path/to/lodash',
'_s': 'path/to/underscore.string'
};
});
ローダー:
define(['jade', 'lodash', 'config'], function (Jade, _, Config) {
var deps;
// Dynamic require
require(_.values(Config), function () {
deps = _.object(_.keys(Config), arguments);
// Use deps...
});
});