如何在生产环境中动态加载多个优化的requirejs模块?

时间:2012-08-07 23:14:04

标签: javascript requirejs js-amd

我开始在虚拟项目中使用require js。我现在想使用r.js脚本来构建我的生产项目。

上下文是这样的:

  • 名为start.js的主文件是:

    require([/* some stuff */], function (){ /* app logic */ });
    

    有一个if,根据某些条件决定我应该要求什么。

  • 所需文件为ModuleA或ModuleB

  • ModuleA和ModuleB都有依赖关系。

    define([/*some deps*/], function(dep1, dep2...) { 
        /* app logic */ 
        return { /* interface */
    }
    
  • 在优化和模块连接之前,在开发模式下一切正常。

  • 使用r.js构建时,我将以下内容指定为模块目标:     模块:[{name:“start”},{name:“ModuleA”},{name:“ModuleB”}]

问题是我的ModuleA变成了:

 define(dep1 ..);
 define(dep2 ..);
 define(ModuleA ..);

但是没有从ModuleA加载。开发中的ModeulA代码加载并执行,构建加载后的代码但不运行。

我该如何解决这个问题?

更新

http://pastebin.com/p1xUcY0A - > start.js

http://pastebin.com/dXa6PtpX - > ModuleA js-animation.js

http://pastebin.com/xcCvhLrT - > ModuleB css-animation.js no deps。

http://pastebin.com/j51V5kMt - >运行优化程序时使用的r.js配置文件。

http://pastebin.com/UVkWjwe9 - >运行r.js后js-animation.js的外观如何这是有问题的文件。我没有从这个文件中获取js-animation模块。 require不会返回我的js-animation对象。

编辑:

在模块定义的末尾删除.js后,从start js开始,优化的start.js为http://pastebin.com/LfaLkJaT,js-animations模块为http://pastebin.com/qwnpkCC6。在chrome中,我在控制台http://pastebin.com/Hq7HGcmm

中收到此错误

2 个答案:

答案 0 :(得分:1)

我相信您的设置问题是您在.js中结束了模块依赖项名称。根据文档:

  

默认情况下,RequireJS还假定所有依赖项都是脚本,因此它不希望在模块ID上看到后缀“.js”。在将模块ID转换为路径时,RequireJS会自动添加它。

如果RequireJS看到以.js结尾的模块名称,则假定模块名称是相对于文档的路径。通过在.js中结束模块依赖项名称,它在开发模式下工作正常,因为RequireJS将加载指定为依赖项的文件。在您的情况下,它将加载文件js/js-animation.js,查看匿名define并正确加载模块。

在制作中,您的start.js模块仍然需要"js/js-animation.js"。 RequireJS将在路径js/js-animation.js加载优化模块,但现在优化器已将您的匿名模块转换为命名模块(在本例中为"js/js-animation")。结果是文件将被加载,但文件中没有define'd模块的名称与"js/js-animation.js"匹配,因此在某种意义上您的动画模块丢失了。

解决方案/ TL; DR:从所有模块依赖项名称(以及r.js配置中的模块定义)中删除尾随.js,您应该没问题。所以你的start.js应该成为(第4行的变化):

require([], function () {
  var $html = $("html"),
    animationModule = localStorage['cssanimations'] == 'true' ? 
    'js/css-animation' : 'js/js-animation',
    $doc = $html.find("body");

  console.debug("loading ", animationModule);
  require([animationModule], function( animationModule ) {
    animationModule.run({
      target : $("div.flex")
    });
  } );
} );

另请注意,您可能希望在RequireJS配置中使用baseUrlpaths来清理模块名称(例如,您可以删除js/前缀)。

答案 1 :(得分:1)

目前的require.js实现似乎存在问题。解决这个问题的方法是创建一个全局中介或中介模块,让所有动态加载的模块调用中介并通过事件宣布自己。这对我有用。