63

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
    }

    // ...
});
4

2 に答える 2

74

この制限は、簡素化された 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番目の例の1つの可能な書き換えを次に示します。

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

于 2013-07-03T13:05:18.013 に答える
7

自分に答える。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...
    });
});
于 2013-07-03T13:06:29.900 に答える