As front-end development increases in complexity, powerful build-step tools have gone from nice-to-have to a necessity. Many teams are now compiling and transpiling JS/CSS, maintaining complex test suites, treating logic as components, linting and minifying code. Good tools integrate these efforts, increasing velocity and developer satisfaction. There is no shortage of these build tools, and none of them are a perfect fit for every situation. But, as usual, some rise above the pack and become something really great.
It worked, but any time someone needed to add a class, or include a new utility function, they would have to go through the exercise of:
Adding the new file to the Makefile.
Adding the new test to the Karma config.
Making sure all of the new file’s dependencies were loaded before it.
If they weren’t, rearrange and reinsure that no existing dependency links were broken.
A more advanced build tool also allows other concepts and possibilities to be “discovered”. For instance, it’s fascinating to me that The End of Global CSS is the actual title of a recently written article. Having easily approachable yet extremely capable compilation tools means that we can all be writing ES6 (or ES7) if we want, and just have it transpile to valid ES5. You can write whatever flavor of CSS that you want, and have vendor prefixes automatically inserted by Autoprefixer. It’s as if we’re finally having our cake and eating it, too!
After playing with both Browserify and Webpack, we settled on using Webpack at Librato. It seems to be more capable out-of-the-box, but lots of people use and prefer Browserify’s approach. I’d recommend checking them both out to see which fits your project better.
Here’s a short list of things that Webpack made significantly easier for us:
- No more long “manifest” files that include all of our modules in a delicate and fragile order.
(The same applies to our karma.config.js because of karma-webpack.)
- It’s no longer difficult to determine exactly what dependencies any of our internal modules have, because they’re required at the beginning of the file.
- It forces modularity and gives us a nice set of conventions for how to actually build things. Webpack has good documentation and it allows us to remove homegrown solutions which varied project to project.
Implementing Webpack ended up being relatively easy, but here’s a quick summary of some of the pain points:
It’s tedious to go through and require dependencies and add module.exports = foo to all of the files that were previously just concatenated together.
Shimming jQuery into modules that depend on it being in global scope is a little tricky and requires some extra work.
One of the big issues we faced with using NPM for managing dependencies was ensuring that everyone on our team had the exact same versions of every package installed. The simplest approach we’ve found is to use an npm-shrinkwrap.json and specify save-exact = true in our .npmrc. We’ve also started migrating all of our projects to NPM 3 for this reason (from the release):
Your dependencies will now be installed maximally flat. Insofar as is possible, all of your dependencies, and their dependencies, and THEIR dependencies will be installed in your project's node_modules folder with no nesting. You'll only see modules nested underneath one another when two (or more) modules have conflicting dependencies.
So, to recap:
We install and version external dependencies installed with NPM.
Internal and external modules (and tests) are compiled/transpiled/bundled/shimmed together with Webpack.
We ensure that we are all consistently building with the same versions of dependencies by using NPM shrinkwrap.
Since migrating this project to Webpack, I’m finding that I can leave the mental overhead of keeping track of our large dependency tree behind. It feels so great to automate away those dull pains. Thanks to Tobias Koppers for creating Webpack, and to Henrik Joreteg for the introduction to Webpack and for an awesome example of a Webpack config.
We're building an awesome application on a cutting-edge stack. If that sounds interesting to you, let's talk.