RequireJS中的动态需求,获取"模块名称尚未加载上下文"错误?

gre*_*emo 56 javascript browser module requirejs r.js

有没有办法定义一个"动态"加载RequireJS中其他模块的模块?如果是,优化器(r.js)如何理解如何/何时必须包含模块?

例如,让dynModules一个定义名称/路径对的模块:

define([], function () {
    return ['moduleA', 'moduleB']; // Array of module names
});
Run Code Online (Sandbox Code Playgroud)

另一个模块将基于该阵列动态加载模块.这不起作用:

define(['dyn_modules'], function (dynModules) {
    for(name in dynModules) {   
        var module = require(path); // Call RequireJS require
    }

    // ...
});
Run Code Online (Sandbox Code Playgroud)

... 给我:

未捕获错误:尚未为上下文加载模块名称"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
    }

    // ...
});
Run Code Online (Sandbox Code Playgroud)

exp*_*nit 68

限制涉及简化的CommonJS语法与普通回调语法:

加载模块本质上是一个异步过程,因为下载时间未知.但是,在模拟服务器端CommonJS规范时,RequireJS会尝试为您提供简化的语法.当你做这样的事情:

var foomodule = require('foo');
// do something with fooModule
Run Code Online (Sandbox Code Playgroud)

幕后发生的事情是,RequireJS正在查看函数代码的主体并解析出你需要'foo'并在函数执行之前加载它.但是,当一个变量或除了简单字符串之外的任何东西,例如你的例子......

var module = require(path); // Call RequireJS require
Run Code Online (Sandbox Code Playgroud)

...然后Require无法解析它并自动转换它.解决方案是转换为回调语法;

var moduleName = 'foo';
require([moduleName], function(fooModule){
    // do something with fooModule
})
Run Code Online (Sandbox Code Playgroud)

鉴于上述情况,这里有一个可能的重写你的第二个例子来使用标准语法:

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...
        }
    });

});
Run Code Online (Sandbox Code Playgroud)

编辑:从你自己的答案,我看到你正在使用下划线/ lodash,所以使用_.values_.object可以简化循环通过参数数组如上所述.

  • 感谢您的时间,我在RequireJS网站上搜索后找到了解决方案.看我的回答. (2认同)

gre*_*emo 7

回答自己.来自RequireJS网站:

//THIS WILL FAIL
define(['require'], function (require) {
    var namedModule = require('name');
});
Run Code Online (Sandbox Code Playgroud)

这会失败,因为在调用上面的工厂函数之前,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'
    };
});
Run Code Online (Sandbox Code Playgroud)

装载机:

define(['jade', 'lodash', 'config'], function (Jade, _, Config) {
    var deps;

    // Dynamic require
    require(_.values(Config), function () {
        deps = _.object(_.keys(Config), arguments);

        // Use deps...
    });
});
Run Code Online (Sandbox Code Playgroud)