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

How can I load multiple optimized requirejs modules dynamically in a production env?

本文关键字:优化 requirejs 模块 加载 生产环境 动态      更新时间:2023-09-26

我已经开始在一个虚拟项目中玩requirejs了。我现在想使用 r.js 脚本来构建我的生产项目。

上下文是这样的:

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

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

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

  • 所需的文件是模块 A 或模块 B

  • 模块 A 和模块 B 都有依赖项。

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

  • 使用 r.js 构建时,我将以下内容指定为模块目标: 模块 : [ { 名称 : "开始" }, { 名称 : "模块 A" }, { 名称 : "模块 B" } ]

问题是我的模块 A 变成:

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

但是模块 A 中没有任何加载。开发中来自 ModeulA 的代码加载并执行,代码在构建加载但不运行后。

我该如何解决这个问题?

更新

http://pastebin.com/p1xUcY0A -->开始.js

http://pastebin.com/dXa6PtpX --> 模块 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 动画模块。require不返回我的js动画对象。

编辑:

在模块定义末尾和 start js 中删除.js后,优化的 start.js http://pastebin.com/LfaLkJaT,http://pastebin.com/qwnpkCC6 js-animations 模块。在 chrome 中,我在控制台 http://pastebin.com/Hq7HGcmm 中收到此错误

我相信

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

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

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

在生产中,您的start.js模块仍然需要 "js/js-animation.js" . RequireJS 将在路径js/js-animation.js加载优化的模块,但现在优化器已将您的匿名模块转换为命名模块(在本例中为 "js/js-animation" )。 结果是文件将被加载,但文件中没有define模块的名称与"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/前缀)。

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