2012-06-11 53 views
37

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

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所需的额外带宽或计算。

我想,产生一个级联器(和我使用字形引号«»以示出从两个模块的片段上面已插入):

此,到目前为止我可以看,会正确地重现AMD的语义,至少有额外的粘连JavaScript。有没有这样的连接器?如果没有,我是否会傻傻地想我应该写一个 - 是否真的有很少的代码库由简单和干净的模块组成,用define()编写,并且在那之后不需要进一步调用require()进行异步取代码?

+1

你是如何解决这个问题的?我发现使用杏仁,min文件大3k,然后连接文件(9K vs 6K)。 – Naor

回答

14

AMD优化器的优化范围超过了要下载的文件数量,它还可以优化内存中加载的模块数量。例如,如果您有10个模块,并且可以将它们优化为1个文件,那么您已经保存了9次下载。

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

如果每个模块在require'd之间消耗100kb的内存,那么运行时优化的AMD框架也将在页面2上节省900kb的内存。

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

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

您保存创建JS对象和DOM相关的与“关于框”的费用,直到你确信这是必要的。

欲了解更多信息,请参阅Delay executing defines until first require for requirejs采取此。

+1

有趣!所以,如果我明白你在说什么,你正在定位创建对象并修改DOM *的代码仅仅是作为被要求的副作用*,那是正确的吗?我不会想到这一点,如果这种做法很常见,那么你可能会碰到JS编码器喜欢在生产中使用AMD加载器的原因。可能是因为我的Python背景,我的代码在导入时没有执行任何代码 - 它只是返回一个充满函数的对象,以便在最终需要它们的副作用时进行调用。 –

+0

你关于内存使用的例子经常被I/O开销所困惑 - 对于类似于盒子的东西,它看起来像是一次加载,但推迟初始化,这样可以节省内存和设置,而不会产生大的交互延迟命中。 –

+0

@Chris,我同意你的观点,但只想提出一个在运行时出现AMD加载器的例子。我可能会担心启动时执行的代码太多,而您可能会担心延迟。除了微不足道的情况之外,我认为在性能方面不存在一成不变的局面。在我的例子中不会有延迟点击,因为所有的JS已经被加载,只是没有'执行'。 –

1

唯一真正的好处是如果你跨模块使用模块,所以独立地缓存模块是有好处的。

0

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

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

小心的restrictions杏仁为了工作

0

强加没有理由为什么不能是构建工具,如您提出一个。

上一次*我查看了优化器的输出,它将模块转换为明确命名的模块,然后将它们连接在一起。它依赖于要求自己确保工厂函数按照正确的顺序被调用,并且正确的模块对象被传递。要想像你想要的那样构建一个工具,你必须明确地对这些模块进行线性化 - 这不是不可能的,而是要做更多的工作。这可能是为什么它没有完成。

我相信**优化器具有自动将自身包含到构建文件中的功能,因此您只需要下载一次即可。这将比你想要的构建工具的输出大,但其他方面相同。

如果有一个生成工具可以生成您要求的输出结果,那么对于同步require,使用exports而不是返回以及其他任何CommonJS兼容性特征。

*那是几年前。 2010年,我想。

**但似乎无法找到它的权利。

1

我有同样的需求,所以我创建了一个简单的AMD“编译器”,就是这么做的。你可以得到它在https://github.com/amitayh/amd-compiler

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