有没有一种方法可以定义一个在RequireJS中“动态”加载其他模块的模块?如果是,优化器(r.js)如何理解如何/何时必须包含一个模块?
例如,让dynModules一个定义名称/路径对的模块:
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 })
鉴于以上所述,这是您的第二个示例可能的重写,以使用标准语法:
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可以简化上述遍历参数数组的循环。
_.values
_.object