我们喜欢在开发过程中使用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()
启动以后异步提取代码?
答案 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年。
**但现在似乎无法找到它。