The launch of the project was met with great enthusiasm and community support, especially from the Ember.js developers. But due to the recent release of the project, you might find it hard to use or integrate with an existing application.

Matt and I took the project for a spin last week, and we were impressed by the benefits of using Broccoli.

A bit of disclaimer.
Although I’m writing Ember.js apps for some time, this is the first time I decided to avoid using Ruby for builds. Nor Matt, nor I ever used existing Node.js build tools and this article is in no way an attempt to compare Broccoli with any of them.

Our task was simple. We wanted to achieve a bootstrapped Ember.js application, similar to what Stefan’s AppKit provides.

To list a few of the features:

Ember.js idiomatic application structure with ES6 modules

A persistence layer provided by Ember Data (think of it as an ORM for your application)

Production, Development (Fixtures) and Test environments support

Testing support using QUnit and Ember Testing package

Continuous Integration cross-browser ready test runner

CoffeScript support

Less/SCSS support (we went using Less along with Bootstrap 3)

We started by forking Jo Liss fork of AppKit, but we ended up starting from scratch which allowed us to understand more deeply the integration with Broccoli and to shape a more streamlined build process taking into account configuration environments. Don’t get me wrong, both the original AppKit and the forked changes helped us a lot. Thanks to the authors.

Broccoli Filters Support

Broccoli is especially powerful due to tree filters, although there are limitations to using them (limited support for complex integrations, ex: Emblem templating, limited integrations with processing libraries for CSS and HTML).
With all of these, CoffeeScript and Less implementations exist and are doing their job pretty well.

If you are familiar with the Sprockets or Rails Asset Pipeline, you will notice that it’s similar to Broccoli filters. Here’s an example how we chained Handlebars with CoffeeScript and Less file filters:

Now you can pass any trees to the preprocess and it will make sure the matched files are picked by the appropriate filters.

You can also spot the Less integration with Bootstrap of which I will write a bit later.

The application structure

There are almost no differences in terms of code organization if to compare with AppKit. The details we were missing were mostly related to the configuration environments support which we adopted and integrated into the application build process.

Note: Broccoli has an environment extension, but at this moment, all it does is to just to provide conventional access to the Node’s process.env where BROCCOLI_ENV attribute value is being read as the current configuration environment name and is limited to just to production and test. I suggest using this convention if you aren’t already, at least until the purpose of broccoli-env is fully decided.

By using Broccoli integration with Bower, access to the third party libraries was simple and easy. The snippet bellow showcases the purpose of broccoli.MergedTree and it shows how easy it is to manage trees using it.

Since we told the preprocess Less filter we will be using Bootstrap, all we needed, is just to merge the Bower trees to provide the integration.
And since Bower trees will also include vendored packages like QUnit, we just included the qunit.css into the build. Broccoli knows where to search for it.
Thanks to our environments, we can dynamically remove it from our build if we are not testing.

Testing the build

For testing Ember.js applications, QUnit framework has great support by using the Ember.Test package. We didn’t bother searching for other alternatives.

While the application build process seemed straight forward, the testing build might be a bit trickier. Mostly because we needed more libraries/trees included into the build and proper support for the continuous integration test runner.

While Ember.js AppKit encourages the use of the Trek’s httpRespond helper for mocking HTTP responses (think ajax/adapter requests), we had big issues making it work with the latest version of Ember (see #10. So we used jQuery Mockjax for the same purpose as fakehr.

To add testing support to our Brocfile.js we had to change the current application build process by extending the trees it uses and returning the appropriate result based on the used environment.

You can see how flexible this step was to us, just because of the way Broccoli manages the filters and transformations. If we wanted to make this shorter, we could just integrate the application build process along with the testing environment build process.

Now returning our tress, is the last thing we need to do to get the build started.

// Brocfile.js
// ...
return [publicTree, appJs, appCss];

Picking the test runner for cross-browser testing was another issue. Initially we tried to setup Karma runner, but it simply refused to work for us because of some strange issues (first the ES6 conflicts, then the lack of integration with the launchers I needed, i.e. Chromium). We ended up using Testem, which is probably the most flexible test runner to integrate with and mostly Just Works™.

Now integrating Broccoli builds with Testem was as easy as using broccoli build and tweaking testem.json to point to the build directory.

To summarize the whole experience… Of course there were situations where the lack of documentation and examples created frustrations. Or the lack of integration with existing tools required reading the source code. But overall, Broccoli seems to be a fast and flexible build tool.
Some of the aspects I really liked and was happy to see are related to the similarities with the existing Ruby tools, simplicity and modularity.

We published our setup as a boilerplate on Github. Make sure you check it out and give Broccoli a try.