We've been working with JS-Automation for about a year now, specializing more and more on Grunt. But the more we relied on it, the more we had to go out of our way to get around problems inherent to Grunt. With Gulp, this changed.
Just to be clear: we started out with Grunt because we believed that it's better to use a stable, proven system than to risk jumping onto the newest fad. And a year ago, where were also much more plugins in Grunt than in Gulp. And we can testify that everything we needed to do could be done in Grunt, and we were very grateful for that. I even wrote some blogs about grunting. But IRL (in real life) we kept on running into issues which hurt our productivity and introduced unnecessary chaos and risks. Because of this, we are now continuously moving all our automation to Gulp. Not in one big gulp, but sip-by-sip (yes, the word-play is also better with gulp :)).
Reason 1 - it's about 100x - 1'000x faster IRL
Now these are in-real-life numbers, and it surprised me as well. The reason is fairly complicated and certain factors make it worse. So a job that took Grunt 5-20 seconds was completed within milliseconds. This means a lot when you're trying and tweaking some values. With Gulp, we can now save the original file (like making a change in a CSS) and by the time we were able to Alt-Tab-Switch to the browser, everything in the background had already completed. With Grunt we were always forced to wait for the logger to show completion, which breaks the flow you're in. The core issues are:
Speed on each File Change: 100-1000 times faster
Reason 2 - Grunt-Configuration becomes unmanageable IRL
Again an in-real-life experience which surprised us. Basically Grunt rules are configured in a JSON-style syntax, and then you define commands (called tasks) which run the automation on this configuration bit. This seems simple and straightforward but results in chaos in large systems. Here's why:
Take for example the configuration of a copy-job, something that you need a lot in Grunt, because each step in grunt starts with files lying in a folder. So you often have to copy some files to another temp-folder, to then do further processing. Now imagine that you have various automations, each needing a different copy-task. Here's the tree of configurations in Grunt just for various copy-actions (without the actual configuration):
- copy (this is the root configuration node for copying
- mainPart (a sub-configuration for some actions)
- mainPartDist (another sub-configuration)
- import-languages (another sub-config)
- import-icons (another sub-config)
- publish-dist (another sub-config)
This is all fairly clear. Now in a real grunt-job you will have to list which steps to perform, like
- Copy files from src to tmp
- Generate some more files from other file into the same tmp (from SCSS, Typescript, HTML-files, etc.)
- Do some checking
- Copy something again
- Merge / rename
So you'll have many such processes, each of them should only use certain parts of the copy-job at the right time. And it's easy to accidentally use the whole copy-job (which causes loads of issues and takes long) or to confuse certain parts because the entire grunt-file gets so long, that you start making mistakes. There are also cases where one configuration can overwrite the other, causing really nasty surprises. In our EAV-UI project which is a foundation of 2sxc, we ended up with about 1'000 lines of grunt code and every change we had to make was scary.
Reason 3 - Low-CPU File-Watchers on the Network
As we noted in the speed-issue, these task-engines need to continuously monitor file-changes to then start a process once the file has changed. Gulp has a built-in watcher called gulp.watch(…), which works very, very well over the network. It does exactly what you expect.
Not so with grunt. Watching is a plugin, and the ones we were able to use somehow were not able to really hook into the windows-file-change-API. This meant that the grunt-watchers we used, ended up performing the watch manually by continuously checking each file. This just burned the CPU of the dev-machine, causing a normal load of 30-80% just because it was watching the files. In addition, the change-recognition time was of course much worse than with gulp.
Love from Switzerland,