Как стать автором
Обновить

Комментарии 16

Но это же перекладывание сложности из одного места в другое. Вместо одного грант-файла надо будет знать ещё один плагин для разбивания файла (load-grunt-config), соглашения об использовании YAML в нём. Спрашивается, что лучше, весь конфиг на одном листе или столько конфигов, сколько задач, плюс ещё один. И при малейшей перекрёстной зависимости задач или необходимости формирования конфига всё рушится и усложняется.

Что действительно полезно упомянуто — это 4 последующих плагина по оптимизации и информированию (grunt-newer, grunt-concurrent, time-grunt, grunt-notify).

Итого, краткое содержание статьи:

load-grunt-config — декомпозиция грант-файла в YAML-конфиг (только верхний уровень!) и отдельные сборочные файлы *.js по задачам со своими конфигами;
grunt-newer — контроль за отработкой в задачах только изменённых со времени прежнего запуска файлах,
grunt-concurrent — параллелизация очередей задач Grunt (которые это могут для себя допустить),
time-grunt — профилирование времени отработки задач Grunt,
grunt-notify — нотификация об окончании или ошибках сборки средствами ОС (вместо сообщений в консоли).
Я согласен с вами, что декомпозиция Gruntfile в некоторых случаях является усложнением при дальнейшей поддержке онного. Однако, в большинстве случаев, это все-таки упрощает процесс поддержки. При желании изменить конфигурацию для какой-нибудь задачи, вам не придется искать её в простыне кода, которая может достигать более нескольких тысяч строк. В таком случае, намного удобнее найти интересующий файл с конфигурацией одной задачи и отредактировать его.

В данный момент на проекте, которым я занимаюсь, задачи разнесены именно таким образом. Даже шаблонизация при работе с jasmine + connect выглядит весьма удобочитаемо, несмотря на то, что конфиг этих двух задач находится в разных файлах.

В конце концов, Grunt есть Grunt, и в рамках этой build-системы вряд ли можно добиться лучших результатов по организации кода. Да и меньше код всё равно не станет.
Разбивать или не разбивать это очередной холивар, даже в нашей команде мнения не однозначные. Такой подход мы начали использовать со времен выхода англоязычной статьи, никаких проблем не заметили, а уж тем более чтобы что-то рушилось. Да, если таску watch, нужен compass:dist, то такой должен быть, но это и в одном конском файле так.

load-grunt-config – там доступен не только YAML, из доков: js|yaml|coffee
Автор статьи слукавил про Gulp.
У меня достаточно огромный Gruntfile, это и простыня и в какой-то момент время сборки действительно стало неприлично большим.
Я попробовал Gulp, был поражён разницей (цифры лишь мои, но для сравнения: Grunt 60s, Gulp 3s).
Плагины Grunt активно переносятся. В Gulpfile можно использовать Gruntfile. Переезд буквально без жертв.
Я тоже попробовал gulp. Сначала просто vinil-fs по статье frontender.info/gulp-piping/, а потом уже и нативный gulpfile. Прирост производительности составил 15% и 20% соответственно. Т.е. не в 20 раз, как у вас, но тоже неплохо. Ну и после громоздкого конфига grunt было приятно использовать лаконичные записи, принятые в gulp. Но тогда переезда не случилось по причине сырости некоторых плагинов, подожду еще чуть-чуть.
Автор статьи по-моему особо не уделяет внимания Gulp, разве что вскользь упоминает его в самом начале.
Вообще, хоть я и не знаком с Gulp, но такая разница кажется мне слишком большой: правильно написанный Gruntfile, по моему мнению, не может уступать Gulp в 20 раз. Вы не могли бы показать эти два файла? Мне было бы очень любопытно разобраться.
как раз для вас ниже написал
Напишу для тех кто не знает. Gulp умеет ставить задачи в цепочку и работать с потоками (stream). Например если нужно 1) перевести coffee в js, 2) соеденитить все файлы и 3) минифицировать результат, то Gulp сделает это все за один «проход» в памяти, единожды прочитав с диска и единожды записав. В то время как такой же сценарий на Grunt 3 раза прочтет и 3 раза запишет на диск. А теперь представтье что изначально у вас ьыло 500 .coffee файлов. В общем отсюда и прирост.
Спасибо, это интересно, я обязательно попробую.
специально загрузил для вас свой gulpfile из одного проекта: gist.github.com/Jabher/1b438b1ba1f062f15fca

Обратите внимание на этот кусок кофекода:
  clientjade = require 'clientjade/lib/compile'
  clientjade files: ['templates/views'], (err, result)->
    return cb logger err if err
    separator = ';\n'
    es.concat(
      gulp.src('framework/frontend.coffee', read: false)
      .pipe(browserify transform: ['coffeeify'], extensions: ['.coffee']),
 
      gulp.src(src 'scripts/vendor/*.coffee')
      .pipe(coffee bare: true).on('error', logger),
 
      gulp.src(src 'scripts/vendor/*.js'),
 
      gulp.src(src 'scripts/*.coffee')
      .pipe(coffee bare: true).on('error', logger),
 
      gulp.src(src 'scripts/*.js')
    )
    .pipe(concat('application.js', newLine: separator))
    .pipe(insert.prepend result + separator)


Что происходит: он компилирует в рантайм шаблоны, затем подсасывает архитектурную библиотеку (которая собирается через browserify+coffeeify), js и coffee-файлы в vendor (с компиляцией на ходу), затем все в основной папке. Это все объединяется в один поток выполнения и уже тогда пишется на диск.
В грюнте подобная штука собиралась уже почти минуту в силу того что ему надо писать на диск все подряд (раздулись шаблоны и количество скриптов), тут занимает пару секунд, в основном из-за медленной библиотеки clientjade, которая по сути читает все шаблоны в папке.
Все никак руки не дойдут подключить кэширование, увы.

Ну и да, gruntfile с аналогичным функционалом описывался в где-то раз в 10 больше кода.
Было бы интересно увидеть сравнение мейнстримовых сборщиков (тупо сделать типовые операции и посмотреть, на конфиги, время, доп ресурсы и тп) — gulp, grunt, не так давно broccoli, вроде еще что-то было (они каждую неделю появляются, и каждый лучше всех конечно же). Я у себя всюду grunt, чисто по привычке использую, но было бы интересно посмотреть на альтернативы если они в лучше (на конкретных задачах конечно же).
Я постараюсь провести сравнительный анализ нескольких систем для сборки ближе к этим выходным. Думаю, что это будет grunt, gulp, branch и broccoli. Можно ещё добавить fez. Как считаете? Так же надо будет выбрать задачи, для которых я сделаю замеры по производительности, ведь, я так понимаю, никому не интересно будет смотреть на jslint, uglify, concat и imagemin?
Мне кажется, или
module.exports = function(grunt) {
  require('load-grunt-config')(grunt);
};

спокойно можно сократить до
module.exports = require('load-grunt-config');

и хвастаться «ещё более коротким Gruntfile'ом»?
Из своего опыта:
1) Подгрузка всех плагинов у нас выглядит так: require( 'matchdep' ).filterDev( 'grunt-*' ).forEach( grunt.loadNpmTasks );
2) У нас были проблемы с grunt-concurrent — он переиначивал параметры командной строки (проблема оказалась даже не в плагине, а в самом grunt, проблема с булевыми параметрами)
3) Были и проблемы со скоростью — сборка занимала до 40 минут, решилось обновлением версий плагинов и заменой некоторых на более продуктивные аналоги
4) Gulp нам не подходит именно из-за потоков, есть несколько специфичных тасков, которые можно организовать только при работе с файлами

И есть у меня такая мысль, что можно сделать grunt таким же шустрым, как и Gulp, реализовав в нём «виртуальную» файловую систему — когда файлы читаются с диска и сохраняются их промежуточные версии по специальному пути в оперативной памяти, а по окончании всех операций записываются на диск уже по реальным путям. Но я посмотрел исходники grunt мельком и понял, что быстро и просто это не реализовать… Но если есть евангилисты grunt — дарю идею.
А вы не могли бы уточнить, какие именно операции Gulp не способен выполнить? К слову говоря, Gulp как раз использует ту вирт. файловую систему, о которой вы говорили выше.
У нас используется grunt-usemin + grunt-filerev и, когда я впервые читал про gulp, для них ещё не было аналогов, сейчас вот нашёл gulp-usemin, на первый взгляд полный аналог, но не уверен. И есть ещё пара кастомных тасков, которые опираются именно на список файлов. Т.е. смысл в том, что это можно перенести на Gulp, но там всё равно будет необходимость читать список файлов либо как-то по другому сам процесс организовывать.

Сейчас время полной сборки занимает пару минут, что вполне устраивает для разворачивания на сервере, а локально сборка запускается только по конкретным задачам, которые проходят очень быстро (типа собрать JST файл из набора шаблонов). А редактируем мы gruntfile крайне редко. Так что смысла переходить на gulp никакого нет у нас, только пустая трата ресурсов будет. Да и, честно говоря, в нашем проекте конфигурационный стиль файла сборки больше подходит, чем кодостиль gulp-а.

А про виртуальную файловую систему — не совсем справедливо про gulp, всё таки там потоки и их явное использование. А виртуальная ФС — это когда пишешь file.write( '*/dir1/dir2/file' ); file.read( '*/dir1/dir2/file' ); — а grunt понимает, что надо не к реальной ФС обращаться, а взять указатель на буфер из некоего словаря в ОП. Но смысл — хранение данных в ОП — да, один.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории