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
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.