Fast client-side asset builder
A fast, reliable asset pipeline, supporting constant-time rebuilds and compact build definitions. Comparable to the Rails asset pipeline in scope, though it runs on Node and is backend-agnostic. For background and architecture, see the introductory blog post.
For the command line interface, see broccoli-cli.
This is 0.x beta software.
Windows support is still spotty. Our biggest pain point is unreliable file deletion (see rimraf#72).
npm install --save-dev broccolinpm install --global broccoli-cli
Brocfile.js file in the project root contains the build specification. It
should export a tree.
A tree can be any string representing a directory path, like
'src'. Or a tree can be an object conforming to the Plugin API
Brocfile.js will usually
directly work with only directory paths, and then use the plugins in the
Plugins section to generate transformed trees.
The following simple
Brocfile.js would export the
app/ subdirectory as a
moduleexports = 'app'
With that Brocfile, the build result would equal the contents of the
tree in your project folder. For example, say your project contains these
app ├─ main.js └─ helper.js Brocfile.js package.json …
broccoli build the-output (a command provided by
broccoli-cli) would generate
the following folder within your project folder:
the-output ├─ main.js └─ helper.js
Brocfile.js exports the
app/ subdirectory as
var funnel = require'broccoli-funnel'moduleexports = funnel'app'destDir: 'appkit'
That example uses the plugin
In order for the
require call to work, you must first put the plugin in
devDependencies and install it, with
npm install --save-dev broccoli-funnel
With the above
Brocfile.js and the file tree from the previous example,
broccoli build the-output would generate the following folder:
the-output └─ appkit ├─ main.js └─ helper.js
You can see a full-featured
Shared code for writing plugins.
Broccoli defines a single plugin API: a tree. A tree object represents a tree (directory hierarchy) of files that will be regenerated on each build.
By convention, plugins will export a function that takes one or more input
trees, and returns an output tree object. Usually your plugin will be
implemented as a class representing a tree, but it is recommended to make the
new operator optional
A tree object must supply two methods that will be called by Broccoli:
.read method must return a path or a promise for a path, containing the
It receives a
readTree function argument from Broccoli. If
.read needs to
read other trees, it must not call
otherTree.read directly. Instead, it must
readTree(otherTree), which returns a promise for the path containing
otherTree's contents. It must not call
readTree again until the promise
has resolved; that is, it cannot call
readTree on multiple trees in
Broccoli will call the
.read method repeatedly to rebuild the tree, but at
most once per rebuild; that is, if a tree is used multiple times in a build
definition, Broccoli will reuse the path returned instead of calling
.read method is responsible for creating a new temporary directory to
store the tree contents in. Subsequent invocations of
.read should remove
temporary directories created in previous invocations.
For every tree whose
.read method was called one or more times, the
.cleanup method will be called exactly once. No further
.read calls will
.cleanup method should remove all temporary
directories created by
When it is known which file caused a given error, plugin authors can make errors
easier to track down by setting the
.file property on the generated error.
.file property is used by both the console logging, and the server middleware
to display more helpful error messages.
As of 0.11 Broccoli prints a log of any trees that took a significant amount of the total build time to assist in finding which trees are consuming the largest build times.
To determine the name to be printed Broccoli will first look for a
property on the plugin instance then fall back to using the plugin constructor's name.
broccoli serveon a production server. While this is theoretically safe, it exposes a needlessly large amount of attack surface just for serving static assets. Instead, use
broccoli buildto precompile your assets, and serve the static files from a web server of your choice.
#broccolijson Freenode. Ask your question and stick around for a few hours. Someone will see your message eventually.