Automation of repetitive and critical tasks is key to develop a successful software product. Automated tasks will minimize software cost, reduce software delivery time as well as improving the product quality and reduce human error. Investing time in automating tasks will allow you to focus on developing features.
“War is of vital importance to the state; hence it is a subject of inquiry which can on no account be neglected”
– Sun Tzu, Art of War
Setting Up your Web App Build System
When developing modern web applications there are critical tasks you want to automate:
- testing: code linting, unit testing, e2e tests
- css preprocessing ( sass, less, …)
- optimization: concatenating and minifying css and scripts, compressing new or modified images, …
- deploying updates to a staging or production server
There are many tools that will help you automate these tasks. Which one to choose? Grunt, Gulp, Brunch, Broccoli,…
Back in 2012 Grunt.js came out and it was quickly adopted by the community, plugins started to proliferate and it became king for task automation on the client side, playing well with Bower and Yeoman. Like many other developers I’ve been using Grunt on my projects and it gets the job done but recently I started to use Gulp, another open source project with faster build times and a Unix/Node philosophical approach to solve problems.
Gulp.js focuses on code over configuration. By harnessing the power of Node streams, it enables faster build times by avoiding the need to write temporary files to disk. This is one of the main differences with Grunt. Stream instances are basically Unix pipes. They can be readable, writable or both and are easy to reason about — you can pipe a readable stream to a writable stream by doing readableStream.pipe(writableStream).
“Streams come to us from the earliest days of unix and have proven themselves over the decades as a dependable way to compose large systems out of small components that do one thing well.
You can then plug the output of one stream to the input of another and use libraries that operate abstractly on streams to institute higher-level flow control.”
Other advantages of using Gulp are:
- Using standard libraries to accomplish tasks
- Small, idiomatic Node modules that do one thing well
- Tasks are executed with maximum concurrency
- Really simple and elegant API
Learning the new flow control techniques will make you more efficient. To learn more about node streams read the Stream Handbook by James Halliday and play on the Node.js Stream Playground by John Resig. Another great resource is Node Streams: How do they work? by Max Ogden, it comes with a screencast version of the article.
Gulp has only few functions to learn:
task(name, fn) : it registers the function and you can optionally specify some dependencies if other tasks need to run first.
run(tasks…) : runs all tasks with maximum concurrency.
watch(glob, fn) : runs a function when a file that matches the glob changes
src(glob) : returns a readable stream. Takes a file system glob and starts emitting files that match. This is piped to other streams.
dest(folder) : returns a writable stream. File objects piped to this are saved to the file system.
This article will walk you through all of the intimidating stuff and introduce you to the core ideas that you will need to know to start using gulp. http://travismaynard.com/writing/getting-started-with-gulp
Caveats: the Gulp.js team is working on bringing in a new task system to improve efficiency ( even more ) and it might include some API changes, you can follow the progress here https://github.com/gulpjs/gulp/issues/355
So why should I use Gulp instead of Grunt?
Mark Dalgleish published a great presentation that covers the history of Grunt and Gulp and their differences: http://markdalgleish.github.io/presentation-build-wars-gulp-vs-grunt
The main reasons why I decided to switch to Gulp are:
– Grunt plugins often perform multiple tasks; Gulp plugins are designed to do one thing only.
– Grunt requires plug-ns for basic functionality such as file watching; Gulp has them built-in.
Gulp.js and node streams are more natural to understand than a huge config file and it also provides more flexibility and speed. Grunt is more mature. I think that both Grunt and Gulp can happily co-exist, If you are using it successfully, there’s no reason to switch Gulp unless you really want or need more flow control and you feel comfortable working with streams and living on the edge.