只调用 'require("jquery")' 一次

Call 'require("jquery")' only once

我正在使用 Gulp 和 Browserify。

我想按特定顺序调用我的脚本:jQuery、jQuery-easing、Bootstrap、[其他库],然后是我自己的脚本。

这显然行不通:

main.js

const $ = require("jquery");
require("bootstrap");
// require other libs
require("./scripts.js");

scripts.js

$(function () {
    // code that won't work
    // because $ is not defined
});

但如果我这样做:

main.js

require("jquery");
require("bootstrap");
// require other libs
require("./scripts.js");

scripts.js

const $ = require("jquery");
$(function () {
    // code that will work
    // because $ is now defined
});

它有效,但我想知道它是否很好地捆绑了我的脚本,以及要求 jQuery 2 次是否是一件好事……

还有更好的方法吗?

这实际上是 Browserify(以及其他模块打包器,如 Webpack、Rollup 和 Parcel)设计的工作方式!每个模块都应该导入所有它需要的其他模块运行。

了解原因的最好方法是稍微了解一下 JavaScript 模块打包器的工作原理。

当 Browserify 解析您的 main.js 文件时,它会将 require("...") 函数调用识别为该模块的 dependencies。例如,main.js 依赖于 jquerybootstrap./scripts.js。它开始在内存中构建一个图形,以便它知道哪些文件 link 到哪个。

./main.js --> jquery
     |
     + -----> bootstrap
     |
     + -----> ./scripts.js

然后它开始解析每个依赖项并将它们添加到图中。

./main.js --> jquery <----- +
     |                      |
     + -----> bootstrap     |
     |                      |
     + -----> ./scripts.js -+

每次它找到新的依赖项时,它都会将其添加到图中并对其进行解析以查看依赖项 依赖于哪些模块。

如果您的模块之一需要一个已经添加到图中的模块(例如 ./scripts.js 依赖于 jquery),那么打包器不需要再次将它添加到图中,它只是创建另一个连接。

最终它将收集您需要的所有模块,并且可以将每个模块添加到包中,然后再将其写入磁盘。

无论你在你的代码库中需要多少次jquery,它只会被添加到依赖关系图中一次,这意味着需要它两次没关系,因为它不会改变捆绑包的大小。

随着您的程序变大,依赖关系图也会变大,最终您将得到如下图所示的复杂模块关系。

它甚至在全局范围内工作得更好:

global.jQuery = global.$ = require("jquery");