简体   繁体   中英

How to exclude library files from browserify bundle

I want to avoid cluttering up my distribution bundle with library files and use separate script tags for them in the HTML.

One way is like this...

m1.js

module.exports = "first module";

m2.js

module.exports = "second module";

cnd-m1.js

var m1 =  "first module";

main.js

var m1 = this.m1 || require("./src/m1");
var m2 = require("./src/m2");

console.log(m1);
console.log(m2);

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>browserify test</title>
</head>
<body>
    <script type="text/javascript" src="src/cdn-m1.js"></script>
    <script type="text/javascript" src="dist/bundle.js"></script>
</body>
</html>

Where cdn-m1.js could be a library for example.

The only way I could figure out to make it work is to put a short-circuit fallback in the require statement and --ignore the file in my build.

in package.json

  "scripts": {
    "build-ignore": "browserify ./main.js -i ./src/m1.js > ./dist/bundle.js",
    "build": "browserify ./main.js > ./dist/bundle.js"
  },

Using the build-ignore script, the m1 module was stubbed in the bundle making it much smaller (assuming its a 50k line library) and it falls back on the cdn-served version.

bundle.js

function e(t, n, r) {
    function s(o, u) {
        if(!n[o]) {
            if(!t[o]) {
                var a = typeof require == "function" && require;
                if(!u && a)return a(o, !0);
                if(i)return i(o, !0);
                var f = new Error("Cannot find module '" + o + "'");
                throw f.code = "MODULE_NOT_FOUND", f
            }
            var l = n[o] = {exports: {}};
            t[o][0].call(l.exports, function(e) {
                var n = t[o][1][e];
                return s(n ? n : e)
            }, l, l.exports, e, t, n, r)
        }
        return n[o].exports
    }

    var i = typeof require == "function" && require;
    for(var o = 0; o < r.length; o++)s(r[o]);
    return s
})({
    1: [function(require, module, exports) {
    //    browserify creates a stub for "./src/m1"
    }, {}], 

    2: [function(require, module, exports) {
        var m1 = this.m1 || require("./src/m1");
        var m2 = require("./src/m2");

        console.log(m1);
        console.log(m2);
    }, {"./src/m1": 1, "./src/m2": 3}], 

    3: [function(require, module, exports) {
        module.exports = "second module";
    }, {}]

}, {}, [2]);

Is there a better way to achieve this?

The answer is to use browserify-shim In order to figure it out, I created a slightly more complicated scenario with a fake lib file ( main-a.js ) with two sub-dependencies ( m1.js and m2.js ) and made the app ( main-b.js ) dependent on the fake lib.

I rolled main-a.js into a stand-alone bundle that exposed one global called fakeLib and used a separate script tag in the index.html to load that.

I then used browserify-shim to build an isomorphic version of the app that required main-a.js in node, but used window.fakeLib in the browser.

using this app:

/**
 * main-b.js
 */
require("./src/main-a").say();

This does not work:

  "browserify-shim": {
    "./src/main-a": "fakeLib"
  },

but this does:

  "browserify-shim": {
    "./src/main-a": "global:fakeLib"
  },

You must use this global: I think that may be due to a bug in browserify because it doesn't agree with the browserify handbook


index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>browserify test</title>
</head>
<body>
    <div style="white-space: pre;" id="output"></div>
    <script type="text/javascript" src="dist/main-a-lib-pretty.js"></script>
    <script type="text/javascript" src="dist/bundle-B.js"></script>
</body>
</html>

Fake library...

/**
 * m1.js
 */
exports.say = "first module";

.

/**
 * m2.js
 */
exports.say = "second module";

.

/**
 * main-a.js
 */
var m1 = require("./src/m1");
var m2 = require("./src/m2");

exports.say = function() {
    function op(t){
        this.document
            ? document.getElementById("output").textContent += t + "\n"
            : console.log(t);
    }
    op(m1.say);
    op(m2.say);
};

package.json for fake lib. This makes a standalone package that exposes fakeLib

{
  "name": "browserify-nightmare",
  "version": "1.0.0",
  "main": "main-a.js",
  "dependencies": {
  },
  "devDependencies": {
    "browserify-shim": "^3.8.12"
  },
  "scripts": {
    "build-lib": "browserify ./main-a.js -s fakeLib > ../dist/main-a-lib-pretty.js",
    "build-lib-pretty": "browserify ./main-a.js -s fakeLib | js-beautify > ../dist/main-a-lib-pretty.js"
  },
  "author": "cool.blue",
  "license": "MIT",
  "description": ""
}

Fake app

/**
 * main-b.js
 */
require("./src/main-a").say();

package.json that uses browserify-shim to return fakeLib from require("./src/main-a") in the browser but acts like a normal CommonJS module in node.

{
  "name": "browserify-nightmare",
  "version": "1.0.0",
  "main": "main-b.js",

  "browserify-shim": {
    "./src/main-a": "global:fakeLib"
  },
  "browserify": {
    "transform": "browserify-shim"
  },
  "devDependencies": {
    "browserify-shim": "^3.8.12"
  },

  "scripts": {
    "build-B": "browserify ./main-b.js > ./dist/bundle-B.js",
    "build-B-pretty": "browserify ./main-b.js | js-beautify > ./dist/bundle-B.js"
  },
  "author": "cool.blue",
  "license": "MIT",
  "description": ""
}

this answer was super-helpful

git repo

First you have to create a seperate bundle for m1.js :

browserify -r ./src/m1.js > ./dist/m1_bundle.js

then simply create the "normal" bundle and reference to the created m1_bundle.js :

browserify -x m1 -d ./main.js > ./dist/bundle.js

now you have to include the two bundles into your HTML-file.

NOTE: you have to include the m1_bundle.js before the "normal" bundle.js in your HTML.

For more details show my other answer . There i explain, how to do the same thing but with node_modules instead of an own library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM