【问题标题】:How can I load multiple optimized requirejs modules dynamically in a production env?如何在生产环境中动态加载多个优化的 requirejs 模块?
【发布时间】:2012-08-07 23:14:04
【问题描述】:

我已经开始在一个虚拟项目中使用 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 构建时,我将以下内容指定为模块目标: 模块:[{名称:“开始”},{名称:“ModuleA”},{名称:“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 无部门。

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

http://pastebin.com/UVkWjwe9 --> 运行 r.js 后 js-animation.js 的样子。这是有问题的文件。我没有从这个文件中得到 js-animation 模块。 require 不会返回我的 js-animation 对象。

编辑:

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

【问题讨论】:

  • 我可以粘贴虚拟项目的整个代码,不过它大约有 300 行。
  • 将您的代码放在 pastebin.com 上并编辑您的问题并附上您的 pastebin 网址:)
  • 不确定 pastebin 是否是一个不错的选择。这些项目在 dev 中有 4 个 js 文件,在生产中应该有 3 个。 :|
  • 澄清:您的“启动”模块是否具有require 之外的逻辑,会生成一系列依赖项?如果是这样,这个数组将包含依赖名称“ModuleA”还是“ModuleB”?也许你可以添加start.js的代码...
  • 感谢@rharper 的评论。我的 start.js 模块里面有两个要求。两个内部 require 调用中只有一个是根据条件完成的。这说明我的情况了吗?

标签: javascript requirejs js-amd


【解决方案1】:

我认为您的设置问题在于您在 .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'd 模块的名称与 "js/js-animation.js" 匹配,因此在某种意义上您的动画模块丢失了。

Solution / 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/ 前缀)。

【讨论】:

  • 您好,感谢您的详细回复。我很感激。我从模块名称中删除了 .js,构建脚本现在声明了名称末尾没有 .js 的模块。问题仍然存在。第二个生产模块,js-animation,和之前一样有两个定义,第一个给插件,第二个给自己,启动js仍然无法从中获取内容。 :|
  • @VladNicula 看起来您在编辑 start.js 时出错。您从模块名称的末尾删除了.js(很好),但也从前面删除了js/(您需要离开)。从优化的输出中可以看出,您的 require.js js-animation 模块实际上称为 'js/js-animation'。如果您的代码在开发模式下工作时出现此错误,我感到很惊讶...在 start.js 中将js/ 添加回您的模块名称并试一试。
  • start.js 模块位于 js 文件夹中。如果我在模块名称之前添加 /js,我会收到“未捕获的错误:脚本错误”,并且 url 中有 /js/js/module-name,这是错误的......
【解决方案2】:

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

【讨论】:

  • 我也有同样的问题,但包。当我尝试加载一个缩小的包时,我的 main.js 没有执行
猜你喜欢
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多