However, there’s little in the way of an introduction to setting up Brunch in an existing project - the homepage only shows how to use Brunch with it’s ‘skeleton’ scripts. Thankfully, getting your own project to work with Brunch is simple and painless.
Brunch vs Grunt
Grunt tries to be everything to everyone. As a result, Gruntfiles end up huge and complex, requiring you to specify every plugin used, what files to apply it to, and exactly what comes out. If you’re using a tool like Yeoman, a Gruntfile is written for you - but good luck if your setup changes.
The first thing to do is install the
brunch command by running
sudo npm install brunch -g. You’ll also want to be using Bower for external packages, which Brunch has excellent support for.
The application we’ll be converting uses CoffeeScript, AngularJS, and LESS, and has no current build system beyond running the CoffeeScript and LESS watchers on the app/ directory. Here’s what the application structure looks like before we install Brunch:
|- app/ # this folder is served statically, with the compiled files living alongside the originals |-- images/ |-- scripts/ # contains .coffee files, which are converted to .js files by coffee -wc |--- components/ # components, installed by bower. Currently |-- styles/ # contains .less files, which are converted into .css files by the less watcher |-- views/ # angularjs views and templates. |- index.html # the main app file. Includes <script> tags for every .js file and bower component |- test/ |- server.coffee # our server file - statically serves the app directory when run. |- component.json # bower package folder - still using the old version of bower |- .bowerrc # bower config file that tells it to install into the app/components folder |- package.json # npm package folder
The first thing we need to do is modify the application structure to fit Brunch’s conventions. That means moving installed packages to outside the
app/ directory, and creating an assets folder for static files.
The assets folder will live inside
app/. It needs to contain any files that will be served statically - in this case, just
index.html along with the
For this project, we also had to delete the existing bower configuration file (.bowerrc) and
components/ folder, rename the
component.json file to
bower.json before updating bower to the latest version (currently 1.2.6). Running
bower install created a
bower_components/ folder in the root project directory. This allows Brunch to easily identify which files are part of our app and which files are external libraries without having to write any complex regular expressions.
Finally, we need to update our index.html to be aware of the changes in structure. Currently, we have this in the head:
<link rel="stylesheet" href="/styles/bootstrap.min.css"> <link rel="stylesheet" href="/styles/main.css">
and this in the body:
<script src="/components/jquery/jquery.js"></script> <script src="/components/lodash/lodash.js"></script> <script src="/components/angular-unstable/angular.min.js"></script> <script src="/components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="/components/angular-sanitize/angular-sanitize.js"></script> <script src="/components/angular-resource/angular-resource.js"></script> <script src="/components/angular-cookies/angular-cookies.js"></script> <script src="scripts/app.js"></script> <script src="scripts/directives.js"></script> <script src="scripts/data.js"></script> <script src="scripts/services.js"></script> <script src="scripts/controllers/landing.js"></script> <script src="scripts/controllers/decision-tree.js"></script> <script src="scripts/controllers/resource.js"></script> <script src="scripts/controllers/task.js"></script>
Ouch! With Brunch, we can replace the css files with this:
<link rel="stylesheet" type="text/css" href="/css/app.css">
and the ridiculous number of script files with this:
<script src="/js/vendor.js"></script> <script src="/js/app.js"></script>
Brunch configuration is incredibly simple. Here’s the
config.coffee file for this project:
The configuration file is simply specifying what folders Brunch should look for and what it should do with them. So, using regular expressions we tell Brunch that the
app/assets folder should be copied directly into the output folder, which we name
_public (see the
The rest of this is fairly self explanatory, although it’s important to note that Brunch uses the new bower.json files to find packages located in
bower_components - so only one of
jquery.min.js will be included in
Finally, we’re also telling Brunch to include certain scripts before others in the vendor.js file, mainly to make sure that
angular.js uses jQuery rather than its jQLite implementation.
Installing Brunch Plugins
Looking at the config file again, you’ll notice there’s no configuration or ‘registering’ of plugins - although most plugins can be configured, the default behaviour usually works with no configuration.
Brunch plugins are just npm packages. Any Brunch plugin that’s installed will automatically be used. Using
npm install --save-dev plugin-name will install the package and update
Looking at the
package.json file, we can see the plugins we’ll be using in this project:
clean-css-brunch, and the
And that’s it! Brunch is now configured and ready to use.
brunch command has two main commands -
brunch build and
build runs the Brunch compilation process and immediately quits, whilst
watch compiles everything then waits for changes on any of your files, and then immediately compiles and updates the files. Unlike Grunt, Brunch caches your files, so after the initial compile, the
watch command is incredibly fast .
By default, minification is disabled. Brunch has a
--optimize flag that will enable minification. However, this is deprecated in favour of the
--production flag, which minifies the output files, removes source maps and disable the auto reload plugin.
The Brunch home page has more information on using Brunch, as well as a list of the skeletons available.
If you want to write your own Brunch plugins, take a look here.
Finally, if I’ve made any mistakes, or if you’re still not sure how to set up Brunch (or if you just want to say hi!), feel free tweet me and I’d be happy to help.