Skip to content

Commit

Permalink
Merge pull request #32 from alxhill/master
Browse files Browse the repository at this point in the history
Added initial content for Brunch chapters
  • Loading branch information
addyosmani committed Feb 8, 2014
2 parents 0fd6c00 + 62ec71e commit f2fb4e9
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 5 deletions.
1 change: 0 additions & 1 deletion chapters/build-systems/brunch/brunch-topic-1.md

This file was deleted.

77 changes: 76 additions & 1 deletion chapters/build-systems/brunch/getting-started.md
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
# Getting started
# Getting started

## *Installation*
The first thing to do is install the ``brunch`` command with ``npm`` by running ``sudo npm install brunch -g``. You'll also want to be using [Bower](http://bower.io) for external packages, which Brunch has excellent support for.

## *Walkthrough*

## Conventions
Brunch has a few conventions that help keep things simple - but you don't have to follow all of them. Firstly, Brunch asks you to specify a folder called 'assets' that is directly copied into your output folder with no modifications. Secondly, most Brunch projects have two separate JavaScript files - app.js, which contains your code, and vendor.js for all external libraries, including bower packages. This allows you to package your files into modules without affecting external libraries.

## Folder structure
In order to understand how best to use Brunch, lets look at a typical folder structure and modify it to follow Brunch's conventions.

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.
|- bower.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 ``images/`` and ``views/`` folders.

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. 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:

```html
<link rel="stylesheet" href="/styles/bootstrap.min.css">
<link rel="stylesheet" href="/styles/main.css">
```

and this in the body:

```html
<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:

```html
<link rel="stylesheet" type="text/css" href="/css/app.css">
```

and the ridiculous number of scripts with this:

```html
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
```

Much better!
10 changes: 9 additions & 1 deletion chapters/build-systems/brunch/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Introduction
# Introduction

## Brunch's Capabilities
[Brunch](http://brunch.io) is a front end build system that lets you get stuff done with little configuration. Brunch compiles, concats and (optionally) minifies your scripts and styles. It can also package JavaScript files into AMD or CommonJS modules. Brunch automatically applies plugins in the correct order to the right files - so with the right plugins, a .coffee file would be converted into a .js file and automatically minified, with no explicit setup necessary.

## Why Brunch?
Compared to other build tools such as Grunt, Brunch is simple. Grunt's makes very few assumptions about your code or build process, and as such is more flexible in terms of what it can do. However, this flexibility comes at the cost of verbosity.

## *When is Brunch the right choice?*
4 changes: 2 additions & 2 deletions chapters/build-systems/brunch/toc.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
* [Introduction](introduction.md)
* [Getting started](getting-started.md)
registerTask
* [Brunch - Topic 1](brunch-topic-1.md)
* [Using Brunch](using-brunch.md)
* [Troubleshooting](troubleshooting.md)
* [References](references.md)
* [References](references.md)
79 changes: 79 additions & 0 deletions chapters/build-systems/brunch/using-brunch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Using Brunch

## Configuration
Brunch configuration is incredibly simple. Here's a sample ``config.coffee`` file for an AngularJS and CoffeeScript file.

```coffee
conventions:
assets: /^app\/assets\//
modules:
definition: false
wrapper: false
paths:
public: '_public'
files:
javascripts:
joinTo:
'js/vendor.js': /^bower_components/
'js/app.js': /^app\/scripts/
order:
before: [
'bower_components/lodash/lodash.js'
'bower_components/jquery/jquery.js'
'bower_components/angular/angular.js'
]
stylesheets:
joinTo:
'css/app.css': /^app\/styles/
```

(N.B: We're using CoffeeScript here, but you can use raw JavaScript instead if you prefer - just name your file `config.js` instead)

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 `paths` property).

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.js`` and ``jquery.min.js`` will be included in ``vendor.js``.

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.

## 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 ``package.json``.

Looking at the ``package.json`` file, we can see the plugins we'll be using in this project:

```json
{
"name": "project",
"version": "0.0.0",
"dependencies": {
"express": "latest",
"mongojs": "latest",
"mongoose": "latest",
"underscore": "latest",
"consolidate": "~0.9.1",
"q": "~0.9.6",
"webshot": "~0.5.1",
"gm": "~1.11.1"
},
"devDependencies": {
"javascript-brunch": ">= 1.0 < 1.8",
"coffee-script-brunch": ">= 1.0 < 1.8",
"css-brunch": ">= 1.0 < 1.8",
"ngmin-uglify-js-brunch": "~1.7.2",
"clean-css-brunch": ">= 1.0 < 1.8",
"auto-reload-brunch": "~1.6.5",
"less-brunch": "~1.5.2"
},
"engines": {
"node": ">=0.8.0"
}
}
```

Here we include the 'base' plugins for JavaScript and CSS, the CoffeeScript and LESS compilation plugins, the CSS minification plugin ``clean-css-brunch``, and the ``ngmin-uglify-js-brunch`` - a plugin that runs JavaScript code through [ngmin](https://github.com/btford/ngmin), the AngularJS 'pre-minifier', then uglifyjs to compress the code. We also use the auto reload plugin, which sets up a web socket server and refreshes the page whenever any files on disk are changed.

## *Workflow*

## *Deployment*

0 comments on commit f2fb4e9

Please sign in to comment.