我正在使用require.js加载项目的依赖项。类似的东西
var deps = [];
if( some condition )
deps = [dep1, dep2, ...]
else
deps = [other1, other2, ...]
define(deps, function(arg1, arg2, ....){
});
这对我来说很好。问题是当我缩小我的代码时,我会遇到以下问题:
Uncaught Error: Mismatched anonymous define() module: function (e,t.....
任何知道解决办法的人都请帮我。提前谢谢。
r.js会检测到要从数组中包含的deps,但如果deps像您的情况一样是动态的,则不会检测到
对于动态deps,您可以配置build.js文件,将其包含在模块中
假设低于代码
main.js
var x = 1;
var deps=[];
if(x > 0){
deps = ['.mod1'];
}
else{
deps = ['.mod2'];
}
define(deps, function(x){
return x * 10;
});
mod1.js
define([], function(){
return 5;
});
mod2.js
define([], function(){
return 10;
});
r.js不会将mod1和mod2与main一起包含,因为它们不是明确的deps,所以我们必须指示r.js,mod1和mod2可能是main的deps。我们在build.js 中这样做
build.js
({
paths: {
},
shim: {
},
baseUrl: "app",
removeCombined: true,
findNestedDependencies: true,
inlineText: true,
optimizeAllPluginResources: true,
stubModules: ['text'],
dir: "app-dist",
modules: [
{
name: "main",
include: ["mod1","mod2"]
}
]
})
通过此设置,我们指示r.js包括mod1和mod2以及main.js
希望这是明确的
问题
RequireJS的优化器无法对运行时生成的依赖项执行依赖项分析。它至少有能力以镜像运行时发生的事情的方式执行代码,而且仍有无法处理的情况。因此,为了使RequireJS的依赖关系分析成功,您的依赖关系必须是字符串的文本数组。在任何其他情况下,RequireJS都将无法执行分析,并且它将静默地失败。
在你的情况下,这有两个后果:
-
优化器实际上并没有为您的模块命名。这就解释了
Mismatched anonymous define() module
。优化器的功能之一是为模块提供最终名称。因此,你放在
main.js
中的一个模块,例如,当它还没有优化时,它会被转换,从而被定义为define("main", ...
。优化器将名称添加到define
调用的开头。(只有当模块尚未命名时,它才会这样做。)如何判断您的模块不是由优化器命名的?除了错误消息(这是一条主要线索)之外,如果您查看
r.js
生成的内容,您会发现您的模块被定义为define(deps,function
。注意模块的第一个参数不是它的名称。你还会看到后面的一个存根。这个存根看起来像这个
define("main",function(){})
。只有当模块的代码不是真正的AMD风格模块时,才应该存在此存根。例如,必须使用shim
配置的模块将具有这些存根。但是,您的模块不需要这个存根。无论如何,优化器是完全混乱的,并且没有正确地命名您的模块。
-
优化器找不到模块的依赖项。
解决方案:调整构建
mfarouk已经提到了如何修改您的构建,以便解决上面的第二个后果。我只想提一下,一般规则是:您必须在模块的include
中显式地放入优化器遗漏的所有模块的并集看起来是这样的:
modules: [
...,
{
name: "mymodule",
include: [dependency1, dependency2, ...]
},
...
]
其中dependency1
等是deps
数组中的依赖项。
为了处理第一个后果,您需要额外的定制。我建议使用优化器的onBuildRead
选项:
onBuildRead: function (moduleName, path, contents) {
if (moduleName !== "main")
return contents;
return contents.replace(/define(deps/,
'define("' + moduleName + '",deps');
}
当优化器读取每个模块时,会调用此函数。当它读取main
时,define
调用被修改为添加模块名称。优化器将看到模块已经命名,将保留名称,并且不会生成虚假的存根。