Building a complicated build pipeline without constantly writing to the file system requires working totally against Grunt.
Irritating error handling (for a long time I kept a note in which I expressed my bad experience with it... fortunately I lost it).
Lack of development (yep, it was resurrected, but it requires a major refactoring effort due to its architectural limitations and it's unclear whether the community will be able to do it).
Other than that, we had to rewrite the builder from scratch and most of our other existing tasks were totally detached from Grunt (we've been just using it for parsing args and picking the right function to run), so it was good opportunity to get rid of Grunt.
Why Gulp?
TBH, I don't remember correctly. It was always somewhere there and when I needed to code the new builder, with all its processing steps, the need for flexibility and extensibility, Gulp just fitted well. The streams approach is demanding, but rewarding and gives you a perfect ground for writing reusable code. Gulp is not opinionated and, unlike Grunt, it focuses on a very limited number of features. That fit our needs perfectly.
It's not being rapidly maintained, but there's a constant effort to release Gulp 4. Moreover, due to its size it requires less development effort than Grunt and we can rather easily migrate from some other dependencies that we use to others. In other words, modularity FTW.
Why not Gulp?
Because Node.JS streams are tough.
This is at the same time a huge advantage and quite a problem. You can implement simple Gulp tasks without using any streams or using them without knowing what you're doing, but when you need to create a complex pipeline with forks, merging, mirroring, error handling, etc., then it's hard.
But at least it's tough for good reasons. Grunt was tough because it was badly designed and didn't fit our needs.
We already use Gulp and there's no way we can drop it (that's a pretty hard dependency when you started using Streams), so this is not a topic to discuss :D. I just wanted to summarise what caused the change as it happened somehow naturally.
This is kind of a post mortem for the change that we already did.
Previously we chose Grunt (see #2), mainly because we've been already using it in CKEditor 4 and other projects.
Unfortunately, with time it was more and more limiting. The biggest flaws I can name are:
Other than that, we had to rewrite the builder from scratch and most of our other existing tasks were totally detached from Grunt (we've been just using it for parsing args and picking the right function to run), so it was good opportunity to get rid of Grunt.
Why Gulp?
TBH, I don't remember correctly. It was always somewhere there and when I needed to code the new builder, with all its processing steps, the need for flexibility and extensibility, Gulp just fitted well. The streams approach is demanding, but rewarding and gives you a perfect ground for writing reusable code. Gulp is not opinionated and, unlike Grunt, it focuses on a very limited number of features. That fit our needs perfectly.
It's not being rapidly maintained, but there's a constant effort to release Gulp 4. Moreover, due to its size it requires less development effort than Grunt and we can rather easily migrate from some other dependencies that we use to others. In other words, modularity FTW.
Why not Gulp?
Because Node.JS streams are tough.
This is at the same time a huge advantage and quite a problem. You can implement simple Gulp tasks without using any streams or using them without knowing what you're doing, but when you need to create a complex pipeline with forks, merging, mirroring, error handling, etc., then it's hard.
But at least it's tough for good reasons. Grunt was tough because it was badly designed and didn't fit our needs.
PS. Before you start coding anything bigger in Gulp I really recommend reading https://github.com/substack/stream-handbook. I've read it a bit too late and wasted a good time because of that.
Summing Up
We already use Gulp and there's no way we can drop it (that's a pretty hard dependency when you started using Streams), so this is not a topic to discuss :D. I just wanted to summarise what caused the change as it happened somehow naturally.
I deleted the old article and created a new one here: https://github.com/ckeditor/ckeditor5-design/wiki/Task-Runner