I have a fairly large multi-page javascript applications that uses requirejs to organize code. I am researching moving to browserify because I like the simplicity that it offers and I am already used to the node.js module system.
Currently on each page I have javascript that goes like this
<script data-main="/scripts/config/common" src="/scripts/lib/require.js">
<script data-main="/scripts/config/page-specific-js" src="/scripts/lib/require.js">
and I have a common build step and a build for each page. This way the majority of the JS is cached for every page.
Is it possible to do something similar with browserify? Is caching like this even worth it, or is it better to bundle everything into one file across all pages (considering that maybe only one page can depend on a large external library)?
You can use factor-bundle to do exactly this. You will just need to split your code up into different entry points for each file.
Suppose you have 3 pages, /a
, /b
, and /c
. Each page corresponds to an entry point file of /browser/a.js
, /browser.b.js
, and /browser/c.js
. With factor-bundle, you can do:
browserify -p [ factor-bundle -o bundle/a.js -o bundle/b.js -o bundle/c.js ] \
browser/a.js browser/b.js browser/c.js > bundle/common.js
any files used by more than 1 of the entry points will be factored out into bundle/common.js, while all the page-specific code will be located in the page-specific bundle file. Now on each page you can put a script tag for the common bundle and a script tag for the page-specific bundle. For example, for /a you can put:
<script src="bundle/common.js"></script>
<script src="bundle/a.js"></script>
If you don't want to use the command-line version, you can also use factor-bundle from the API:
var browserify = require('browserify');
var fs = require('fs');
var files = [ './files/a.js', './files/b.js', './files/c.js' ];
var b = browserify(files);
b.plugin('factor-bundle', {
outputs: [ 'bundle/a.js', 'bundle/b.js', 'bundle/c.js' ]
});
b.bundle().pipe(fs.createWriteStream('bundle/common.js'));