何时使用RequireJS,何时使用打包的JavaScript?

75

对于网页工程师来说,这可能是个愚蠢的问题。但我有点困惑。现在我有一个应用程序,在其中使用了几个JavaScript文件来执行不同的任务。现在,我正在使用JavaScript bundler 来合并和压缩所有文件。因此,在运行时只会有一个app.min.js文件。现在,Requirejs 用于在运行时加载模块或文件。那么,问题是如果我已经将所有东西放在一个文件中,那我需要 requirejs 吗?或者什么情况下我可以使用 requirejs 和/或 bundler?

请让我知道是否需要进一步的细节。


1
我不明白为什么你需要两者都。你认为你需要吗? - nnnnnn
2
那是一个困惑。什么时候使用什么?还是只需要选择一个? - kunjee
除了惰性加载 Javascript 外,Require 还具备依赖注入的功能,因此可以消除全局变量的需求。在一个打包文件中,我觉得 Require 仍然是有用的。我错了吗? - papiro
3个回答

48

一般情况下,你只在开发过程中使用RequireJS的加载形式。当网站完成并准备好部署时,你需要压缩代码。其优点在于RequireJS知道你的依赖关系,并可以轻松按正确顺序压缩代码。以下是RequireJS网站上的说明:

当你完成开发并希望为最终用户部署代码时,可以使用优化器将JavaScript文件合并并进行压缩。在上面的示例中,它可以将main.js和helper/util.js合并成一个文件并对结果进行压缩。


4
我知道这是一个旧帖子,但我偶然发现它,因为我有类似的疑问。所以,接下来的问题是:如果我们最终将所有内容捆绑成一个文件进行部署,那么我的整个应用程序会一次性加载而不是分批(按需)加载。这是否与 AMD 相矛盾? - Code Poet
5
在某种意义上是的,但 AMD 更加理论化,而 requirejs 也关注现实世界的性能问题。逐个加载每个模块肯定更加简洁、纯粹,但需要很长时间 :) - Matt Greer
1
我也在SO上提出了这个问题,请参见https://dev59.com/GGIj5IYBdhLWcg3wMinW#20518314?noredirect=1#20518314。也许可以采取两种方法之间的中间点? - Code Poet

29

这是许多熟练的 JavaScript 开发者之间争议不断的问题。许多其他语言都有一个“编译”阶段,整个程序会被捆绑起来进行部署(JBoss 的 .WAR 文件就是其中之一)。来自传统背景的程序员通常更喜欢这种方法。

JavaScript 近年来发展迅速,很难确定具体的最佳实践,但那些欣赏 JavaScript 更加函数化特性的人经常更喜欢模块加载方式(如 require.js 所使用的方式)。

我写了一个名为 Frame.js 的库,其工作方式类似于 require.js,因此我的偏见是倾向于使用模块加载器的方式。

直接回答你的问题,是二者中的一个。

大多数主张将脚本打包成单个文件的人认为它能够实现更高效的压缩,因此更有效率。但我认为在大多数情况下,打包的效率优势是微不足道的,因为:(1)模块加载时间分布在整个会话中,(2)单个模块可以被压缩到几乎相同的百分比,(3)单个模块可以被服务器和路由器分别缓存,(4)仅在需要时加载脚本最终允许您为某些用户加载更少的代码并为整体加载更多的代码。

从长远来看,如果您能够看到动态脚本加载的优势,请使用它。如果没有,请将脚本捆绑成单个文件。


6
虽然我理解将文件分开的好处,但我认为捆绑文件也可以减少所需的HTTP连接数量。随着浏览器和服务器中的管线化变得越来越普遍,这可能不再那么重要,但目前它是一个相当大的问题。 - Andrew Theken
5
如果应用程序很大,HTTP连接开销可能会迅速增加。对于我们的应用程序,在未打包模式下逐个加载每个JS文件时,加载页面大约需要15-30秒钟。在打包模式下只需约1秒钟。 - Matt Greer
一个单一的打包、缓存文件显然比获取数十个或数百个文件要快得多,你永远无法确定它们是否被加载,或者加载需要多长时间。因此最好将所有东西都倒入客户端。在大多数情况下,这个单一文件的大小不会超过1MB,经过缩小和压缩后可能更小。所以,单一文件胜利! - vsync
数千个强类型类和一个 .swf 文件,胜利! - Triynko

11

这取决于你的应用程序。如果你正在制作一个仅包含适度JavaScript(小于100kb压缩后)的服务器端应用程序,那么就进行总捆绑,你可能会很好。

但是,如果你正在制作一个具有大量代码的JavaScript应用程序,则你的需求将不同。

例如,在我的应用程序中,我捆绑了所有核心文件。其中包括jQuery、underscore、backbone、我的主要应用程序文件、我的用户登录系统、我的布局系统、我的通知和聊天系统,所有这些都是我的初始大文件的一部分。

但我也有许多其他模块不属于初始捆绑的范畴,它们加载在它们之后。

论坛、维基、所见即所得、颜色选择器、拖放、日历和一些动画文件都是第二类的一部分。你需要合理地决定哪些是常用的,并立即需要哪些,而可以延迟哪些。

如果我立即包含所有内容,则可以获得超过1MB的JavaScript代码,这将是疯狂的,并使初始启动无法接受。

第二类在初始文件触发“initSuccess”事件后开始下载。

但第二类比第一类更智能,因为它首先加载更重要的内容。例如,如果你正在查看维基,则它将在加载颜色选择器之前加载维基。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接