这里问题的答案是“视情况而定”。我说的是在大型应用程序中使用过 RequireJS 但没有彻底阅读过 RequireJS 代码的人。 (只是指出,了解 RequireJS 内部和内部的人可能会与我解释不同。)require 的成本可以分解为 3 种成本情景:
如果模块从未被加载,require 从服务器加载文件,执行文件,执行模块的工厂函数并返回对模块的引用。 (从网络加载文件的成本通常比其他成本相形见绌。)
如果模块已经加载但从未需要,require 执行模块的工厂函数并返回对模块的引用。 (这通常发生在优化的应用程序中。)
如果模块已经被加载并且需要,require 返回一个对该模块的引用。
成本方案 1 > 成本方案 2 > 成本方案 3。
首先,让我们考虑每个文件有一个模块的情况。应用程序未优化。我有一个名为module1 的模块,它是千载难逢的必需品。它在主应用程序中的使用可以这样建模:
define(["module1", <bunch of other required modules>],
function (module1, <bunch of other modules variables>) {
[...]
if (rare_condition_happening_once_in_a_blue_moon)
module1.use();
[...]
});
这里我总是支付场景号 1 的代价,即使我不使用该模块。这样做会更好:
define([<bunch of required modules>],
function (<bunch of module variables>) {
[...]
if (rare_condition_happening_once_in_a_blue_moon)
require(["module1"], function (module1) {
module1.use();
});
[...]
});
这样一来,我只需支付加载模块的代价一次。
现在,如果我需要重复使用module 怎么办?这可以建模为:
define(["module1", <bunch of other required modules>],
function (module1, <bunch of other modules variables>) {
[...]
for(iterate a gazillion times)
module1.use();
[...]
});
在这种情况下,费用方案 1 支付一次,仅此而已。如果我像这样使用require:
define([<bunch of required modules>],
function (<bunch of module variables>) {
[...]
for(iterate a gazillion times)
require(["module1"], function (module1) {
module1.use();
});
[...]
});
我支付场景编号 1 一次 和 一个(无数次 - 1)成本场景编号 3。在一天结束时,是否应将 module1 包含在要求中define 调用或单独的 require 调用取决于您的应用程序的具体情况。
如果应用程序已通过使用r.js 或自制优化进行优化,则分析会发生变化。如果应用程序经过优化,使所有模块都在一个文件中,则每次您在上述情况下支付费用方案 1 时,您都将支付费用方案 2。
为了完整起见,我将补充一点,如果您不提前知道要加载的模块,则必须使用require。
define([<bunch of other required modules>],
function (<bunch of other modules variables>) {
[...]
require(<requirements unknown ahead of time>, function(m1, m2, ...) {
m1.foo();
m2.foo();
[...]
});
[...]
});