Building, transpiling, or compiling front-end assets, whichever way you want to state it, modern web development is best accomplished using tools like Less, CoffeeScript, Browserify, RequireJs, or any other variant that does or will exist. The difficulty comes in unifying this vast pool of resources to arrive at the most efficient application you can for todays standard web browsers. But, more importantly that they leave the door open for you to migrate to the next powerful tool without significant effort. It is important to note that these technologies are not required to write an efficient application, but they are paramount when developing a maintainable codebase.
My colleagues and I are currently evaluating many different software stacks to determine which one we would like to use for a new project. While all of them have their pros and cons, it has been clear that using NodeJs and many of the tools developed on it’s platform is the way to go for our client side assets. The major players that we have seen that unify these tools up till now include Make, Grunt, Mimosa, and Gulp. The capabilities of these tools that we are interested in are:
- Time and difficulty to understand it well
- Easy environment specific configuration
- Composability with existing tools
- Development experience
- Watch mode
- Compile time
Peter Müller argues that using Make would require you to specify your dependency graph in multiple locations, thus violating DRY. However, being the devils advocate here for Make, do we really need to specify that dependency graph when you are using tools like Browserify, RequireJs, or even Less? Since Make is only composable via cli tools it makes it difficult to do much without first writing a cli tool that will do what you want. Thus for the occasional case where you do want to modify the pipeline it would require more setup and complication; as opposed to something that can be easily accomplished with minor code in a NodeJs based build tool. In short there is something to be said for having your build tools in the same language as your application.
Make is simple to understand and there really aren’t too many moving parts to grasp. Since it relies primarily on executing shell commands, it will work with just about anything you throw at it, and remain orthogonal to your application. It is a fast tool with great support for detecting when files have actually changed and really does need to be re-compiled. As a symptom of it’s orthogonality to your application it is inherently reversible. Watch mode can be accomplished by delegating to a cli tool like nodemon.
- Make is a tried and true build tool with a 20 year track record
- Technology agnostic
- Optimal build path (Only builds changed files)
- Simple and easy to learn
- Small tweaks only available through cli tools
- Yet another syntax to learn
- Redefine dependency graph
- Necessary to use temp files for intermediary steps (Many potential IO hits)
Grunt is a much younger tool than Make, but it has garnered the largest adoption of the Node community. Gulp is nipping at it’s heels; but from what I can tell Grunt is still king. Grunt has adopted the model of configuration over code, meaning you should only need to send configuration options to the plugins you use with minimal code modifications. Unfortunately, this does lead to a build configuration file that is slightly confusing and difficult to reason about. Compared to Mimosa or Gulp files which are usually much shorter and easier to understand at a quick glance. The primary configuration approach does help prevent you from coupling your application code with the build infrastructure, maintianing reversibility.
- Many plugins to choose from
- One-off tasks are easy to write
- Strong community adoption, though waining
- Hard to understand configuration
Compared to Make, Mimosa is a really young tool primarily focused on the web development workflow. It provides support for scaffolding new projects, building assets, and a development workflow. Mimosa has adopted a convention over configuration approach to its setup. This means that as long as you adhere to some sensible conventions then the Mimosa build configuration will be light and require little maintenance. There is a nice example of how minimal that is when using Backbone, Require.js, and Bower with only 1 line of config. You can easily find more examples doing so with different technologies.
Mimosa manipulates files in memory through the various build steps negating IO hits as much as possible. Note the file manipulation is in memory, but it does not utilized streams as Gulp does. In general though you do get a similar stream like approach instead of temp file approach as I outline in the Gulp comparison below. Gulp is faster at this primarily becuase it leverages Node streams, but as Mimosa’s author David Bashford has stated on gitter, “when the difference is 1ms vs 10ms… do you really notice? You don’t”.
There is a mimosa-adhoc-module which address the need for one-off operations, although I feel the plugin is clunky and not very intuitive. I don’t know how much you’d really need to do that if you are adhering to the sensible conventions, and so long as you adhere to the tenants of a 12 factor app. This does make it more difficult for you to accidentally couple your application to the build infrastructure.
The scaffolding feature in Mimosa is pretty cool, however in practice I’ve experienced that the skeletons do not stay up to date with the latest versions out there. Yeoman on the other hand, which only attempts to do scaffolding, seems to do better at staying current.
Mimosa’s ability to watch file changes, run them through the build pipeline, and then serve/reload your browser with the changes is really nice. There are simple switches at the command line that flip between development vs production versions of your application, definitely a killer feature.
Looking over the Mimosa source I am deeply concerned that there is no test coverage. This appears to be a common pattern for the core and the majority of its plugins. That scares me that future releases may have unintended consequences.
Overall, community support for Mimosa does not feel as accepted as other tools such as Grunt or Gulp.
- Scaffold an application
- Convention over configuration
- Watch with server
- Limited File IO
- Community acceptance seems minimal
- Source is not tested
However, Gulp’s bread and butter comes by allowing you to do this workflow:
You will only have to learn the semantics of the libraries that you use, not a new language altogether. Gulp has a gulp-shell plugin to easily integrate with other cli tools. Watch functionality is built into the core of Gulp, giving that to you for free.
Since your build tools are using the same language and libraries as your application, care must be taken to ensure you do not couple the application too tightly with the build infrastructure. Coupling the two would break reversibility thus preventing you from changing to a different build tool in the future, should the need arise.
- Less file IO
- Fast build times
- Strong community acceptance, and growing
- One off issues are easy to resolve within a language you are familiar with
- Must be cautious about coupling / reversibility