browserify external 与 exclude 之间有什么区别?

What is the difference between browserify external vs. exclude?

我正在使用 browserify 并试图让它跳过浪费时间包括或解析 jquery 和我通过 CDN 加载的其他 require-less 文件。

我应该使用 bundle.exclude('jquery') 还是 bundle.external('jquery')?有什么不同?他们的输出似乎相同,我不清楚文档:

Prevent file from being loaded into the current bundle, instead referencing from another bundle.

If file is an array, each item in file will be externalized.

If file is another bundle, that bundle's contents will be read and excluded from the current bundle as the bundle in file gets bundled.

Prevent the module name or file at file from showing up in the output bundle.

If your code tries to require() that file it will throw unless you've provided another mechanism for loading it.

答案:

你应该使用 exclude.

解释:

这两个函数都可以防止文件被包含在包中。对于您的用例,您可能不会 require jQuery,因此使用哪个并不重要。然而,这是正在发生的事情:

browserify 使用 module-deps 探索您的代码并找到任何 require 语句,然后告诉 module-deps 在哪里可以找到所需的模块。

如果文件在包中,只需在包的模块映射中为其提供密钥。

如果您说该文件是 external,browserify 会假设您的意思是它包含在另一个包中,因此会提供一个文件路径,假设该文件的 id 将从另一个包解析。要做到这一点,还需要一些额外的簿记工作。

如果你 exclude 文件,那么 browserify 会提供 undefined 给 module-deps 并且当你尝试使用需要所述文件的包时肯定会发生火灾。然而,这种方法缺少跟踪文件路径的开销(这实际上可以忽略不计)并且不会 "waste time" 在展开之前查看其他包。

一些例子: 我摆弄 node-browserify/example/api 来生成一些包,下面的示例是来自各种测试的模块映射,为了便于阅读而进行了某种格式化。

Vanilla - 运行 因为它在 browserify 仓库中:

{
    1: [function(require, module, exports) {
        module.exports = function(n) {
            return n * 3 };

    }, {}],
    2: [function(require, module, exports) {
        var bar = require('./bar');

        module.exports = function(n) {
            return n * bar(n);
        };

    }, { "./bar": 1 }],
    3: [function(require, module, exports) {
        var foo = require('./foo');
        console.log(foo(5));

    }, { "./foo": 2 }]
}

3 (main.js) 取决于 ./foo 位于 2

2 (foo.js) 取决于 ./bar 位于 1

1 (bar.js) 没有依赖项

标记为 api/bar.js 为外部:

{
    1: [function(require, module, exports) {
        var bar = require('./bar');

        module.exports = function(n) {
            return n * bar(n);
        };

    }, { "./bar": "/browser/bar.js" }],
    2: [function(require, module, exports) {
        var foo = require('./foo');
        console.log(foo(5));

    }, { "./foo": 1 }]
}

2 (main.js) 取决于 ./foo 位于 1

1 (foo.js) 依赖于 ./bar 应该在其他一些 bundle[=48 中标记为 /browser/bar.js =]

标记为api/bar.js排除:

{
    1: [function(require, module, exports) {
        var bar = require('./bar');

        module.exports = function(n) {
            return n * bar(n);
        };

    }, { "./bar": undefined }],
    2: [function(require, module, exports) {
        var foo = require('./foo');
        console.log(foo(5));

    }, { "./foo": 1 }]
}

2 (main.js) 取决于 ./foo 位于 1

1 (foo.js) 取决于 ZOMFG 的 ./bar!我不知道它在哪里。你需要??!1!

删除了 exclude/external 调用,并从 foo.js 中删除了 ./bar 的要求:

{
    1: [function(require, module, exports) {
        module.exports = function(n) {
            return n * bar(n);
        };

    }, {}],
    2: [function(require, module, exports) {
        var foo = require('./foo');
        console.log(foo(5));

    }, { "./foo": 1 }]
}

2 (main.js) 取决于 ./foo 位于 1

1(foo.js)无相依,人间桃花。我想知道他们是否通过其他方式加载 bar

@Will 回答的第一部分也很重要:

For your use case, you're probably not going to require jQuery, so it really doesn't matter which you use

我认为 OP 的示例令人困惑,无法询问排除和外部之间的区别。如果 jQuery 永远不会在代码中被 require()-ed,那么就不会问任何问题:它永远不会被 browserify 解析,并且无论如何都必须通过其他方式加载。

只是想指出这一点,因为我也觉得这很混乱。