Broccoli is good for you!


posted by qmx on 31 August 2014

Unless you’ve been living under a rock, you’ve heard about Ember. The main complaint I have about it is that the learning curve is emacs-like steep:

Since I’m pretty stubborn, I kept poking at it and trying to dissect parts of it to get a proper grasp of what is going on under the hood. Then I’ve stumbled upon Broccoli, the build tool ember uses under the hood for ember-cli.

Broccoli?

Well, to my surprise dealing with broccoli was a mostly pleasant experience, specially after I’ve got rid of all the extra-baggage that comes with ember (and this deserves a post on its own).

Where Do I Start?

I’m not going to tell you how to install the tool, the Broccoli page has all the info you need. So let’s talk about some concepts.

Broccoli works with the concept of trees - a set of files/folder that can be processed, and you deal with it directly by writing JavaScript code. No fluffly DSLs or tons of declarative jsonghetti.

Note: I love grunt, it is one of the most powerful build tools we have for client-side code, and I do use it a lot, but oh boy, have you tried to maintain a huge app? This isn’t 100% grunt’s fault per se, we could be using XML instead. Works flawlessly but sometimes JSON can be clunky to deal with.

Let’s start by looking at the broccoli example app. It provides a Brocfile.js with CoffeeScript, ES6 Transpiler, SASS, a partial Bower integration. Then there’s a bunch of implicit decisions that come from the now deprecated Ember App Kit, which still spill on the newcomer. It’s just too much to deal with when you’re trying to figure out how the tool works.

So let’s start cutting stuff out, and the best way to cut is to start from scratch ;)

101

Take a look at this sample app I’ve put together. This is your dumb static site, with nothing interesting. Give it a spin:

npm install
broccoli serve

What we’ve got here? Both app and public folders got merged and exposed through the fancy web-server which is built into broccoli-cli. Here is where things get interesting:

We CAN HAZ Livereload!

Just by using broccoli-cli you get livereload support. Our Brocfile.js looks like this:

var mergeTrees    = require('broccoli-merge-trees');

var tree = mergeTrees(['app', 'public']);
module.exports = tree;

Compact, eh?

Not convinced? Things will start getting interesting soon.

102

So, let’s add a bower dependency to our site. Since people love to hate on jquery, that’s exactly what I’m going to add here.

broccoli-static-compiler can do a bunch of interesting stuff, but let’s attain to the mapping abilities for now. I want all the bower_components to be served under /deps on my app output. Our Brocfile.js looks like this:

var pickFiles = require('broccoli-static-compiler');
var mergeTrees    = require('broccoli-merge-trees');

var deps = pickFiles('bower_components', {
    srcDir: '/',
    destDir: '/deps'
});

var tree = mergeTrees([deps, 'app', 'public']);
module.exports = tree;

and our index.html has these amazing tags being properly served:

<script src="/deps/jquery/dist/jquery.js"></script>
<script src="/app.js"></script>

Intermission!

I’ll talk more about it on the next posts! Stay tuned!

NOTE:

I’d love to find the original site that has this learning curve image for giving proper credit! - please tweet at me if you know it!