Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between browserify external vs. exclude?

I'm using browserify and trying to get it to skip wasting time including or parsing jquery and other require-less files I've loaded via CDN.

Should I use bundle.exclude('jquery') or bundle.external('jquery')? What is the difference? Their output seemed identical, and the docs are unclear to me:

  • b.external: https://github.com/substack/node-browserify#bexternalfile

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.

  • b.exclude: https://github.com/substack/node-browserify#bexcludefile

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.

like image 816
Scott Stafford Avatar asked Sep 23 '15 18:09

Scott Stafford


People also ask

When should I use Browserify?

Browserify solves the problems of having too many JS files referenced in your HTML, inability to use Node modules in the browser, and inability to reference your own modules in your own code. Watchify streamlines the process of bundling your files and will make a change every time you change a JS file in your project.

What are some of the benefits of Browserify?

Browserify provides a common way to structure all of your JavaScript code by bundling dependencies into a single file that can be referenced within a <script> tag in the browser.

Is Browserify a dev dependency?

It is one of our devDependencies – modules required for developers to make updates to this app.


1 Answers

Answer:

You should use exclude.

Explanation:

Both functions prevent the file from being included in the bundle. For your use case, you're probably not going to require jQuery, so it really doesn't matter which you use. However, this is what's going on:

browserify uses module-deps to explore your code and find any require statements, and then tells module-deps where to find the required module.

If the file is in the bundle, it simply needs to provide the key for it in the bundle's module map.

If you said the file is external, the browserify assumes you mean it's included in another bundle, and so provides a path to the file assuming that that as an id will resolve from anther bundle. There is a little additional bookkeeping involved to be able to do this.

If you exclude the file, then browserify will provide undefined to module-deps and there will definitely be a fire when you try to use the bundle that requiring said file. However, this approach lacks the overhead of tracking the file path (which would really be negligible) and doesn't "waste time" looking in other bundles before exploding.

Some examples: I fiddled with node-browserify/example/api to produce some bundles and the examples below are the module maps from various tests, somewhat formatted for readability.

Vanilla - ran as it is in the browserify repo:

{
    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) depends on ./foo which is at 2

2 (foo.js) depends on ./bar which is at 1

1 (bar.js) has no dependencies

Marked api/bar.js as external:

{
    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) depends on ./foo which is at 1

1 (foo.js) depends on ./bar which should be labelled /browser/bar.js in some other bundle

Marked api/bar.js to exclude:

{
    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) depends on ./foo which is at 1

1 (foo.js) depends on ./bar which is at ZOMFG! I dunno where it is. yru require??!1!

Removed the exclude/external call, and removed the require of ./bar from foo.js:

{
    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) depends on ./foo which is at 1

1 (foo.js) has no dependencies, the world is peachy. I wonder if they loaded bar by some other means

like image 198
Will Avatar answered Oct 09 '22 18:10

Will