繁体   English   中英

动态加载require.js的依赖项

[英]Dynamically load dependencies of require.js

我正在使用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是动态的(如您的情况),则不会检测到它

对于动态部门,您可以配置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不会在main中包含mod1和mod2,因为它们不是明确的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将无法执行分析,并且将以静默方式失败。

在您的情况下,有两个后果:

  1. 优化器实际上没有为模块命名。 这解释了Mismatched anonymous define() module

    优化器的功能之一是为模块赋予其最终名称。 因此,您放入main.js的模块(例如尚未进行优化的模块)将进行转换,以便将其定义为define("main", ...优化程序会将名称添加到define的开头调用(仅当模块尚未命名时才这样做。)

    如何判断模块未由优化程序命名? 除了错误消息(这是一个主要线索)之外,如果查看r.js产生的内容,您还会发现模块定义为define(deps,function 。请注意,模块的第一个参数不是它的名称。

    您还将在其后看到一个存根。 存根看起来像这个define("main",function(){}) 仅当模块的代码不是实际的AMD样式的模块时,才应存在此存根。 例如,必须为其使用shim配置的模块将具有这些存根。 但是,您的模块不需要此存根。

    无论如何,优化器完全混乱,无法正确命名模块。

  2. 优化器找不到模块的依赖项。

解决方案:调整构建

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调用以添加模块名称。 然后,优化器将看到该模块已被命名,将其名称保留下来,并且不会生成虚假的存根。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM