在我的应用程序中,我希望以编程方式创建命名模块,并在使用define访问它时。以简化形式,它看起来如下:
define("myModule", [], function() {
return {
myModule: true
};
});
var obj = require('myModule');
虽然我没有看到任何问题,为什么它不能以这种方式工作,require.js当然会这样说:
MODULE NAME ... HAS NOT BEEN LOADED YET FOR CONTEXT: ...
如果我按照以下方式更改我的代码,它会起作用:
define("myModule", [], function() {
return {
myModule: true
};
});
require(['myModule'], function(obj){
});
但是现在它是异步代码,我不希望这样。
答案 0 :(得分:1)
看起来同步的require
形式实际上只是sugar,允许以类似于CommonJS的方式编写代码,并帮助将CommonJS代码移植到RequireJS。不幸的是,它生成的错误消息未正确指出问题的性质。这种形式的require
工作正常,只要模块已经已定义已初始化,就会返回一个模块。如果尚未定义和初始化,则失败。由于这种require
形式不初始化模块,因此必须使用异步表单来初始化它们。
我认为这不会改变。截至去年7月,James Burke(RequireJS的首席开发人员)表示支持同步动态加载脚本有no plans。
我可以通过两种方式看到这个:
将整个应用程序包装在一个异步require
调用中,该调用将加载您要使用的所有模块var foo = require('foo');
。我知道您提到过要避免异步调用,但是您没有指定您想要避免的是在整个应用中是否有异步require
调用传播。我在这里建议的是启动应用程序的一个异步require
调用:
require(['main', 'myModule', ... other modules ...], function (main) {
main();
});
假设main
模块是应用程序的主要入口点,那么您可以在应用程序代码的任何位置执行var myModule = require('myModule');
因为myModule
已经定义并且在执行同步require
之前初始化。
为RequireJS创建并行系统。这样的事情有效:
var syncmap = Object.create(null);
function syncdefine(name, factory) {
var mod = factory();
syncmap[name] = mod;
define(name, mod);
}
function syncrequire(name) {
return syncmap[name];
}
syncdefine("myModule", function () {
return {
myModule: true
};
});
console.log("outside", syncrequire("myModule").myModule);
require(["myModule"], function (mm) {
console.log("inside", mm.myModule);
});
syncdefine
函数为RequireJS定义一个模块,并立即与syncrequire
一起使用。调用syncrequire
会立即返回模块。它也可以通过RequireJS' require
致电。
此代码仅供参考。它不是一般的解决方案。