Updated 26 Mar 2016 for Brunch 2.0
While consulting at OnTrees I was introduced to brunch by @graham and have used it on a couple of my own projects (more recently exploregiving.com). Brunch is an alternative front-end build system to Grunt or Gulp.
You can achieve the same thing with any of these front-end build systems. I've just found the brunch conventions and workflow stragightforward to work with. What closed it for me was how easy it was to add brunch to our continuous deployment pipeline.
So what does Brunch give us?
In development, it gives us:
- a local server
- watcher type dev workflow including running tests (more on this later)
- simple package management using bower
- JavaScript Source Maps
- via plugins the ability to use any framework you can think of coffeescript, sass, less, jasmine etc all using the same brunch workflow
In production, it gives us:
- css/js bundling and minification
- cache busting
- simple deployment
Installing Brunch
Brunch is a node package, so the first thing to do if you don't have it already is to install node.
Now lets go ahead and install brunch globally:
npm install -g brunch
Next up your going to install bower globally for package management:
npm install -g bower
That's brunch served :)
Getting started with brunch
You usually get started using a brunch skeleton. A brunch skeleton is brunch pre-configured with the packages and plugins for particular frameworks. Brunch has skeletons for pretty much any front end framework you can think of sass, less, ember, angularjs etc - check them out.
We are going to use my brunch skeleton brunch-starter. I use this because for me, no two websites (or clients) are the same and I like to keep things as lightweight as possible. Brunch-starter is bare bones ready for us to start using the power of brunch to help us build our application.
To use brunch-starter, run the following command (from the folder you want to create your app in):
brunch new --skeleton https://github.com/DalSoft/brunch-starter
npm update
bower update
File structure
Your notice that brunch new created the following file structure:
|- app/ # this is the root of your website |-- assets/ # static content for example index.html, images etc these are copied as-is when you compile your project |-- js/ # contains your javascript that will be bundled and minified to app.js |-- css/ # contains your css that will be bundled and minified to app.css |- bower_components/ # your bower components that will be bundled and minified to vendor.js/.css |- vendor/ # your own components that will be bundled and minified to vendor.js/.css |- www/ this is where brunch will output your site to |- bower.json # this where you configure bower dependencies for example jQuery |- package.json # this where you configure npm dependencies for example brunch plugins |- brunch-config.js # this where you configure brunch
Using Brunch
To see brunch in action, we need to create a simple site. Below is a trivial example - it's not production quality and is for brevity just to show brunch working.
First off, let's tell brunch to watch our source files by opening a command prompt from our source folder and running the following:
brunch watch -s
This tells brunch to start the http server and watch our source files. If you haven't worked with watch dev flow it's great - files are complied into www automatically as soon as you save them and all you have to do is refresh your browser.
Next, create these files - Create index.html in app/assets, the js files in app/js and the css files in app/css.
h1.css:
h1 {
font-size: 3rem;
color:red;
}
p.css:
p {
font-size: 1rem;
color:purple;
}
hello-world1.js:
var module1 = function(){
function HelloWorld(){
alert('Hello World 1');
}
return {
'hello': HelloWorld
}
}();
hello-world2.js:
var module2 = function(){
function HelloWorld(){
alert('Hello World 2');
}
return {
'hello': HelloWorld
}
}();
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Brunch example</title>
</head>
<body>
<h1>Really dumb example</h1>
<p>This is a really dumb example to show how brunch.io works.</p>
<link href="/css/vendor.css" rel="stylesheet" type="text/css">
<link href="/css/app.css" rel="stylesheet">
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
<script>
module1.hello();
module2.hello();
</script>
</body>
</html>
As you do this, you will see in the command window that the code is already built and copied to the www folder ready for us to use. This is the advantage of using watch workflow code is automatically built as you go.
If you stop the current command and run:
brunch build --production
If you look at the javascript and css you will see it is minfied as well as bundled, this is the command you would run to build your website for release. To deploy your website, all you need to do is copy the files from the www folder.
How does it work brunch-config.js
If you look at app/assets/index.html you will notice that we have referenced the following css and js.
<link href="/css/vendor.css" rel="stylesheet" type="text/css" />
<link href="/css/app.css" rel="stylesheet" />
<script src="/js/vendor.js" />
<script src="/js/app.js" />
In the www folder after running brunch watch -s you will see all the css files you created in app/css are bundled to css/app.css and all the js files you created in app/js were bundled to js/app.js.
This is configured by brunch-config.js via javascript joinTo and stylesheets joinTo. It's pretty straight forward to configure and very flexible. Everything you need to know can be found in config documentation.
Again, if you run brunch build --production you will notice that css/app.css and js/app.js are minified.
css/vendor.css and js/vendor.js work in much the same way but for bower and your own libraries. I'll explain in a bit more details in the Bower and vendor sections.
Bower package manager
Working with bower in brunch is simple there are a few ways to do it - this is how I do it.
Let's add jquery as a dependency. Open bower.json and add jquery to the dependencies like so:
{
"name": "your-app",
"version": "0.0.1",
"main": "www/app.js",
"dependencies": {
"jquery": "2.1.1"
},
"overrides": {}
}
Now open a command prompt from the source folder and run:
bower update
Now if you were running brunch watch -s you will see that jquery was bundled to js/vendor.js which we have referenced in index.html.
That's how easy it is just add all your dependencies to bower.json and run bower update. Upgrading is now as simple as changing a version number.
Vendor folder
The vendor folder works in much the same way as the bower folder, except this is where you would copy static js libraries that are not available in bower. Anything in this folder is bundled into to js/vendor.js and css/vendor.css.
Brunch plugins
One really cool thing about brunch is it has lots of plugins for most of the frameworks out there. Lets say we wanted to use sass in our build chain.
Plugins are node modules, so all we have to do is an open command prompt from the source folder run:
npm install --save sass-brunch
Now let's add some sass. Copy this scss to app/css and name the file main.scss.
$background-color: red;
body {
background-color: $background-color;
}
If you were running brunch watch -s you will see that the sass was complied and bundled to css/app.css with the rest of the css.
There are plugins for most of the popular frameworks.
Next up?
If there is appetite - I'll do a part 2 on how to use brunch with angularjs and how to get brunch running unit and end to end tests.