require.js: 访问所有已加载的模块

44

有没有办法访问所有已加载的require.js模块?

背景:
我希望在所有javascript模块加载完毕后自动调用它们的init()函数,参见require.js + backbone.js: How to structure modules that have an initialize function?。 在没有使用require.js时,我遍历了我的自定义模块存储并调用了每个init()函数。
现在我想使用require.js来实现。我知道调用每个已加载模块(包括外部库)的my_custom_init_function_favoritecolor_petname_love123是有风险的。但我希望这比手动维护所有模块列表(以及这些模块的要求)更容易。忘记一个模块的init()比第三方库具有我的自定义函数名称要更容易(尽管后者可能更难调试)。

还有其他更好的解决办法吗?

3个回答

71

是的,require.s.contexts._.defined 是一个对象,它的键是模块名称,而值包括从该模块返回的值。

require.s.contexts._.defined 包括所有的模块(不管是使用define()还是require()所定义的,例如作为程序起始点的JavaScript文件,并使用data-main来指定RequireJS)。


5
注册表(registry)和上下文定义(defined on the context)有何区别?在执行 define('Mod',...) 后,我会在 context..registry 对象上看到一个新对象,但在 context..defined 上没有。在执行 require(['Mod'],...) 后,我会在 context._.defined 上看到该模块。 - alexK85
1
无法读取未定义的属性'contexts'。Require是该方法,因此切换到这个方法对我有用 requirejs.s.contexts._.defined - Tyguy7

11

我在我的RequireJS项目中刚完成了类似的行为。require.s.contexts['_'].registry存储了已注册模块的列表。

我使用Underscore.js来获取、过滤和迭代模块列表。以下代码片段可能会对您有所帮助:

var modules_registered = _.keys(require.s.contexts['_'].registry);
var modules_to_be_initialized = _.filter(modules_registered, function(module_title) {
    return module_title.indexOf('modules') > -1;
});

_.each(modules_to_be_initialized, function(module_name) {
    require([module_name], function(current_module) {
        current_module.init();
    });
});

1

我很懒,所以我就这么做了:

    var modulesToLoad = Object.keys(require.s.contexts['_'].registry);
    require(modulesToLoad);

根据其他答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接