Comments
Зачем все эти сложности, если можно все делать npm-ом на системных пайпах? Gulp плагины это всегда обертки, и они либо сквозят багами, либо нет недостающих фич, либо нужных оберток просто нет, в то время как для npm есть вообще все, что может быть для сборки js. К тому-же настроить сборку на npm в разы быстрее и проще, чем через gulp. А главное, npm — стандартный способ, в то время как gulp — костыли.

Отличная статья в тему.
Gulpfile является в своем роде makefile для проекта. В него можно засунуть как dev-штучки, к примеру создание нового контроллера на AngularJS, с шаблоном и записью в роутер, так и production, к примеру компиляция статики Django и перемещение её в другую папку. Просто это удобно и всё на своих местах.
Удобно в теории. На практике с первым багом обертки gulp с невнятным error message понимаешь, что приходится лезть в код модуля, лежащего в основе плагина gulp и писать репорт автору gulp-плагина на гитхаб, который в 50% случаев будет проигнорен, в 50% — пофикшен через 2-3 недели. После n-кратного натыкания на эту ситуацию, понимаешь, что почему-бы просто не сделать build.js, использующий те же нативные модули с внятными ошибками, понятным и хорошо задокументированным API, и если хочется — на тех же стримах (пайпах из gulp, только стандартных).
Этот подход более эффективен в силу того, что авторы конечных модулей, как правило, очень заинтересованы в их успешности и занимаются их поддержкой, в то время как авторы оберток для gulp в целом относятся к ним холодно. Более того, у конечных модулей, возьмем, к примеру, компилятор из ES6 в ES5, как правило, есть множество конкурентов, и если один модуль проваливается, можно просто переключиться на другой. В случае, если использовать обертки gulp, ты автоматически привязан к конкретному модулю.
Но build.js, как правило, также является сложной альтернативой, хотя и уже в разы более гибкой.
Большинство задач, будь то компиляция статики для django или создание нового контроллера для angular легко решается через скрипты npm, запускаясь не `gulp collectstatic`, а `npm run collectstatic`, где в package.json что-то вроде
"scripts": {
"collectstatic": "./manage.py collectstatic"
}


Но в целом, конечно, дело вкуса. Если большой проект уже на gulp, то перевести его на чистый npm требует усилий. У меня это заняло несколько часов, но результат и сэкономленные поныне нервы стоили того.
В целом, вы правы, пользоваться инструментом, на который забил разработчик, не стоит.

Но в этом и прелесть Gulp, что вы можете использовать нативные инструменты.
Например, Browserify, подключается напрямую, без посредника-плагина.
Для удаления файлов можно использовать npm-модуль del, это тоже очень просто.

Если же не использовать систему сборки, а собственный build.js, то будет некоторое количество стандартного кода по разбору аргументов CLI и настройке параметров сборки — и получится свой велосипед, который придется переносить из проекта в проект.
Поэтому лучше использовать одну из существующих систем сборки, я выбрал Gulp, потому что он мне показался лучше Grunt
Ну под аргументы есть тоже много инструментов: nomnom, yargs, minimist. Они тоже очень удобны и стандартны, в отличие от gulp (с gulp не перейдешь так просто на grunt, или, там, brunch, mimosa итп).
Использование жестко одной системы сборки для всего (как одного фреймворка, UI-библиотеки, и т. п.) противоречит анархичному духу ноды, крупные фреймворки и проекты имеют тенденцию разваливаться. Как минимум, рассчитывать при разработке своего проекта на какой-то один «божественный» фреймворк это недальновидно, как класть все яйца в одну корзину. Штуки, пытающиеся вобрать в себя всё вызывают недоверие. Нужный набор атомарных взаимозаменяемых плагинов, соответствующих концепции разделения ответственности в долгой перспективе выигрывает.
А скажите кто-нибудь человеку, далёкому от node:
— инкрементальную компиляцию эти штуки (grunt/gulp/npm/whatever) умеют?
— можно как-нибудь заставить эти штуки работать «на лету» — т.е. обнаруживать изменения файлов и перекомпилировать что нужно?
— можно ли эти штуки вставить прямо в веб-сервер? Чтобы я шел на /CSS/MainCSSBundle.css — и оно по-необходимости перекомпилировало, и отдавало свеженькое?
1. Инкрементальная компиляция — дело компилятора, а не инструмента сборки. Надо смотреть что вы компилируете. Некоторые штуки, типа typescript компилят только изменившиеся файлы. А вот у LESS инкрементальной компиляции нет — каждый раз перекомпилируется вся структура.

2. Можно. У многих инструментов есть свой вотчер, как у browserifywatchify. Но есть и более общие тулзы, типа watch, где можно задать свои действия в колбеке на изменения в директории.

3. Можно. gulp-webserver, grunt-connect, а также специфичные для проектов: browserify-server,…
2. Есть в комплекте, поглядите доку и примеры.
3. Проще сделать обратное неварное — livereload модуль подключить.
Все же статья устарела немного, поэтому вот мои 5 копеек. Grunt это task runner, а не система сборки и несмотря на то что во многих случаях его можно использовать для сборки, как уже описано в статье выше — это подходит не для всего (производительность страдает в случае где есть промежуточные шаги). А значит что Grunt и Gulp некорректно сравнивать, так как назначение у них разное. Именно так и считает автор другой ещё не очень популярной, но многообещающей системы сборки Broccoli — Jo Liss. Jo говорит что вполне нормально и разумно использовать task runner вместе с pipeline плагином (будь то Gulp или Broccoli), поэтому в статье лучше всего было бы сравнить возможности и недостатки Gulp и Broccoli.

Кроме этого есть ещё пару мест где можно придраться к статье:
вот так выглядит простейший Grunt-файл...

В результате мы получаем огромную простыню кода, в которой ничего нельзя найти. А поскольку Grunt-файл большой, то и сборка становится непозволительно долгой. И как это ускорить, совершенно непонятно, потому что в архитектуре Grunt не заложено никаких способов для этого

Решением для этих проблем будут плагины и примеры из этой статьи. Обратите внимание на эти два плагина: load-grunt-config и grunt-concurrent. Первый поможет решить проблему с простыней, а так же заметно ускорить загрузку задачи если вы будете испльзовать его в режиме jit-grunt. Второй позволяет запускать те задачи которые независят друг от друга параллельно (в том числе и для watch).

И последняя придирка:
gulp.src('*.coffee')
    .pipe(coffee())
    .pipe(concat())
    .pipe(uglify())
    .pipe(gulp.dest('build/'))

Тут лучше было бы разделить задачу на два шага — первый для режима разработки, второй для production. В первом убирается шаг с uglify, во втором все тоже самое только с concat. Иначе во первых будет медленнее сборка для разработки, во вторых после шага с concat, uglify sourcemap не сможет правильно указывать на исходные файлы. В случае если бы тут не было coffee файлов то можно было бы просто обойтись конфигом Grunt.

В остальном статья отлично показывает сильные строны Gulp, особенно на примере с jekyll.
Спасибо, очень полезные 5 копеек для этого поста.

load-grunt-config никак не уменьшает размер общего описания сборки. Конечно, в нескольких файлах читать удобнее, но все равно читать приходится много.
grunt-concurrent я смотрел, Gruntfile c concurrent есть в репозитории с benchmark. Он помог собрать быстрее, но не так быстро как gulp.

Идея с jit заслуживает внимания, ее можно применить и в gulp, чтобы оптимизировать импорты исходя из запускаемых задач.

С последним замечанием просто соглашусь. Я упростил для наглядности доклада, в реальности все как вы и говорите
Only those users with full accounts are able to leave comments. Log in, please.