This library is deprecated in favor of broccoli-watchify which is more up-to-date and more well maintained.
NOTE: We are locked into browserify
version < 10.2.5
because
Browserify changed the way they handle symlinks, and we need to adjust
broccoli-fast-browserify
to handle this. As soon as broccoli-fast-browserify
is fixed, we will bump the version of browserify
.
The broccoli-fast-browserify plugin bundles your assets with browserify.
This plugin differs from the other watchify/browserify plugins for broccoli in that it uses caching to significantly speed up compilation. There is an existing broccoli-watchify plugin that would seem to use this caching, however it does not detect changes through symlinks, which many broccoli plugins use under the hood.
broccoli-fast-browserify
does not depend on the watchify
package, which uses
filesystem change detection to determine when to rebuild. We don't need this
functionality because broccoli does that for us! Instead, this plugin borrows
the caching logic from watchify
and adapts it to be more suitable for broccoli.
Check out the the wiki for more examples of using broccoli-fast-browserify
.
npm install --save-dev broccoli-fast-browserify
By default, broccoli-fast-browserify
turns all *.browserify
files in the
input tree into a bundle with the same name, but with a .js
extension. Each
*.browserify
file is also the sole entry point for the bundle.
No other files are output from broccoli-fast-browserify
. Here is how you would
use broccoli-fast-browserify
with the default configuration:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree);
broccoli-fast-browserify
provides some simple options that let you control how
bundles are created. If you want to use a different extension for detecting
bundles, or a different output extension, you can provide the bundleExtension
or outputExtension
options:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundleExtension: ".bundle",
outputExtension: ".es5"
});
If you want to manually specify what bundle to build, with specific input files,
you can do that too, but the syntax is a little different. The best way to show
how to do this is with an example. If you wanted to create an output bundle
called lib/bundle.js
, where all index.js
files from the input tree are
entrypoints, this is what you would do:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
'lib/bundle.js': {
entryPoints: ['**/index.js']
}
}
});
Entrypoints is an array of globs, so you have a lot of power over what gets built.
You can pass configuration directly to browserify by specifying a browserify
option in the options hash. By default debug
is set to true so source maps are
generated. If you would like to disable sourcemaps, you would do this:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
browserify: {
debug: false
}
});
If you would like to generate multiple bundles based on some criteria, like the
default behavior (i.e. generating one bundle per *.browserify
input file),
then you can set the glob
option to true
in your bundle specification.
For example, to achieve broccoli-fast-browserify
's default behavior of
generating one bundle per *.browserify
file, here is what you would use
(this is the implementation used by broccoli-fast-browserify
, adapted for
this example):
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
"**/*.browserify": {
glob: true,
entryPoints: function(relativePath) {
return [relativePath];
},
outputPath: function(relativePath) {
// remove the bundle extension from the filename
var out = relativePath.replace(/\.browserify$/, '');
// If the file already has the output file extension (e.g. bundle.js.browserify)
// Then don't do anything, else add the output extension to the filename
if (! out.match(/\.js$/)) {
out = out + '.js';
}
return out;
}
}
}
});
With the glob
option set to true, the plugin will generate a bundle for each
file or directory matching the key of the bundle specification (in this case,
**/*.browserify
).
You must provide functions for entryPoints
and outputPath
, which are passed
each file/directory matched by the bundle glob. In this example, entryPoints
and outputPath
are both passed the relative paths to each *.browserify
file
in the input tree.
Let's look at the implementation of these methods:
The entryPoints
function simply returns the *.browserify
file wrapped in an
array, since we only want one entryPoint per bundle for this example.
The outputPath
function first strips off the ".browserify" extension, and if
the file doesn't already end with '.js', it adds the '.js' extension (this
handles cases where the input file is .js.browserify
).
Suppose you have the following directory structure:
ROOT/
lib/
packages/
utilities/
index.js
... more files
ui/
index.js
... more files
server/
index.js
... more files
Let's say you want to generate a bundle for each of the packages, where the entry
point is that package's index.js
file. And then you wanted to generate a
package which contains all three sub packages (all.js
). We will put these
packages in the root of the output tree.
This is how you might accomplish that:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
"lib/packages/*": {
glob: true,
entryPoints: function(relativePath) {
// in this case, relativePath is the specific packages directory,
// since the glob above matches our directories, rather than files
return [path.join(relativePath, 'index.js')];
},
outputPath: function(relativePath) {
// Again, relativePath is a directory here (e.g. lib/packages/utilities),
// and we want to return a javascript file, so we take the basename (utilities)
// and tack '.js' onto the end, so the output bundle file will be
// '/utilities.js', '/ui.js' and '/server.js'
return path.basename(relativePath) + '.js'
}
},
"all.js": {
// we don't set glob: true here because we want only one output file,
//(in this case /all.js)
entryPoints: ['lib/packages/*/index.js']
}
}
});
The output tree would look like:
ROOT/
all.js
server.js
ui.js
utilities.js
Browserify has the concept of external modules, which it skips over when
building a bundle. Browserify assumes that these modules will be made available
at runtime. If you wanted to build two modules, one which included React and the
other which didn't, you would specify an excludes
array for the bundle for
which you wanted React excluded. You can also specify excludes
at the top-level
options to exclude a module from all bundles:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
externals: ['vertx'],
bundles: {
"withoutReact.js": {
externals: ['react'],
entryPoints: ['index.js']
},
"withReact.js": {
entryPoints: ['index.js']
}
}
});
In this example, the vertx
module is not included in either of the generated
bundles, and the react
module is not included in the withoutReact.js
bundle
but is included in the withReact.js
bundle.
You even can specify custom browserify transforms for each bundle.
The transform
option can take the values described in node-browserify or
be an array of such values. For example:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
"transformed.js": {
transform: require('coffeeify'),
entryPoints: ['index.js']
}
}
});
If you need to specify options to a transform, you can wrap the transform
and its options in an array with 2 elements. See the 'browserify-shim'
transform below:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
transformed.js: {
transform: [
'coffeeify',
// the 'browserify-shim' takes options
[ require('browserify-shim'), { global: true } ]
],
entryPoints: ['index.js']
}
}
});
You can specify browserify requires and expose modules with the same API as transforms.
Example:
var fastBrowserify = require('broccoli-fast-browserify');
var tree = fastBrowserify(inputTree, {
bundles: {
transformed.js: {
require: [ 'react', { expose: 'React' } ]
}
}
});
Often you will want to create a separate bundle for your NPM modules. This is
easy with broccoli-fast-browserify
. Check out the wiki page on separating app and 3rd party bundles
for an example.
The 3 Clause BSD License (3-Clause-BSD). See LICENSE for details.
Copyright © 2014 Caleb Land.