为什么连接的RequireJS AMD模块需要加载器?

时间:2012-06-11 21:19:11

标签: javascript requirejs web-deployment amd almond

我们喜欢在开发过程中使用RequireJS和AMD,我们可以编辑模块,在浏览器中点击重新加载,然后立即看到结果。但是,当需要将我们的模块连接到单个文件进行生产部署时,显然必须有一个AMD加载器仍然存在,无论该加载器是RequireJS本身还是其较小的合作伙伴“杏仁”,如下所述:

http://requirejs.org/docs/faq-optimization.html#wrap

我的困惑是:为什么需要装载机?除非你有非常不寻常的情况使你有必要在模块内部进行require()调用,否则似乎可以连接一系列AMD模块而不需要加载器。最简单的例子是一对模块,如下所示。

ModA.js:

define([], function() {
    return {a: 1};
});

ModB.js:

define(['ModA'], function(A) {
    return {b : 2};
});

鉴于这两个模块,似乎连接器可以简单地生成以下文本,而不会使生产服务器或浏览器承受RequireJS或Almond所需的额外带宽或计算负担。

我想象一个产生的连接器(我正在使用V形符号«,»显示上面两个模块的片段在哪里插入):

(function() {
    var ModA = «function() {
        return {a: 1};
    }»();
    var ModB = «function(A) {
        return {b : 2};
    }»(ModA);
    return ModB;
})();

据我所知,这可以正确地重现AMD的语义,只需要少量多余的胶水JavaScript。有这样的连接器吗?如果没有,我会因为认为我应该写一个而感到愚蠢 - 是否真的很少有代码库由简单而干净的模块组成,这些模块用define()编写,并且永远不需要在其中进一步调用require()启动以后异步提取代码?

5 个答案:

答案 0 :(得分:14)

AMD优化器的优化范围可以超过要下载的文件数量,还可以优化内存中加载的模块数量。

例如,如果您有10个模块并且可以将它们优化为1个文件,那么您已经节省了9个下载。

如果Page1使用全部10个模块,那就太棒了。但是如果Page2只使用1呢? AMD加载程序可以延迟执行“工厂函数”,直到模块为require'd。因此,Page2只触发一个“工厂函数”来执行。

如果每个模块在require'时消耗100kb的内存,那么具有运行时优化的AMD框架也将在Page2上节省900kb的内存。

这方面的一个例子可能是'About Box'样式对话框。它的执行被推迟到最后一秒,因为在99%的情况下它不会被访问。例如。 (用松散的jQuery语法):

aboutBoxBtn.click(function () {
    require(['aboutBox'], function (aboutBox) {
        aboutBox.show();
    }
});

您可以节省创建与“关于框”关联的JS对象和DOM的费用,直到您确定有必要为止。

有关详细信息,请参阅Delay executing defines until first require了解requirejs对此的看法。

答案 1 :(得分:1)

唯一真正的好处是如果您跨部门使用模块,那么独立缓存模块会带来好处。

答案 2 :(得分:1)

我有同样的需求,所以我为此目的创建了一个简单的AMD“编译器”。您可以在https://github.com/amitayh/amd-compiler

获取

请注意,它有许多功能缺失,但它完成了工作(至少对我而言)。随意贡献代码库。

答案 3 :(得分:0)

如果您使用require.js将代码编译为单个大型文件进行生产,则可以使用almond.js来完全替换require。

Almond只处理模块引用管理而不是不再需要的加载本身。

为了工作,请注意restrictions杏仁的施加

答案 4 :(得分:0)

没有理由无法成为您建议的构建工具。

最后一次*我查看了优化器的输出,它将模块转换为显式命名的模块,然后将它们连接在一起。它依赖于require本身来确保以正确的顺序调用工厂函数,并且传递了适当的模块对象。要构建一个你想要的工具,你必须明确地线性化模块 - 不是不可能,而是更多的工作。这可能就是为什么没有这样做的原因。

我相信**优化器有一项功能可以自动将自身(或杏仁)包含到构建文件中,这样您只需要下载一次。这将大于您想要的构建工具的输出,但在其他方面相同。

如果有一个构建工具产生了你要求的那种输出,那么在同步require的情况下,必须更加小心,使用exports代替返回,以及任何其他CommonJS兼容性功能。

*那是几年前的事了。我认为,2010年。

**但现在似乎无法找到它。