Сравнение популярных систем сборки для frontend-разработчиков



    Я стал замечать, что в последнее время build-системам стали уделять всё больше внимания, и, под влиянием этого, их в одночасье стало настолько много, что, честно говоря, уже всех и не упомнить. Последнее время у меня на слуху четыре системы: Grunt, Gulp, Brunch и Gear. Про все что-то где-то было написано, но ни разу не ставился вопрос о том, какие преимущества или недостатки они имеют друг перед другом? И именно поэтому я решил провести сравнительный анализ самых популярных build-систем(по версии google).

    Но сперва надо определиться с критериями, по которым мы будем оценивать эти системы:

    • Начало работы.
    • Производительность. Никто не хочет ждать по минуте после изменения одного coffee-файла.
    • Документация. Чем нагляднее и проще — тем лучше.
    • Плагины. Ведь мы не хотим столкнуться с проблемой, когда мы начали использовать билд-систему, а в ней нет адаптера, скажем, для jasmine?


    Теперь, я полагаю, с вводной частью можно покончить и приступить, наконец, к сравнению.

    1. Начало работы


    Grunt
    Во многих статьях написано, что «писать для Grunt намного проще, чем потом это читать», и они во многом правы. Поэтому порог вхождения в эту билд систему чрезвычайно низок: достаточно прочитать одну страницу, чтобы иметь представление, как написать свой конфиг. Написание своих плагинов так же не занимает много времени и сил: всю систему вполне возможно изучить всего за несколько часов. Что касается порога вхождения в уже готовые проекты, то тут дела обстоят немного иначе, Gruntfile не так удобно читать, как писать. Представьте себе ситуацию, когда у вас к проекту подключены 20 плагинов и у каждого из них есть зависимости. Например, concat имеет смысл выполнять только после завершения работы плагина coffee и compass, а imagemin должен выполняться только после выполнения задачи copy. Это всё довольно проблематично отследить, даже если вы не используете шаблонизатор для описания ваших задач.

    Gulp
    Начало работы с Gulp такое же быстрое, как и с Grunt. Однако, оно лишено изъянов, которые мы обсуждали в начале работы с grunt для больших проектов, т.е. Gulp так же легко читать, как и писать, что делает его максимально располагающим к быстрому старту. Если же вы уже использовали какую-либо систему сборки, то время вхождения в Gulp уменьшится в разы.

    Gear
    Что касается творения от yahoo, тут все много печальней. Зайдя на сайт, мы видим громкое заявление о том, что система «easy to use», отлично! Соответственно, я полагаю, что сейчас мне коротко и ёмко расскажут об этой системе, как ею пользоваться и покажут простенький example. Итак, первое, что мы видим — это кусок кода и кнопочку «Run» в правом верхнем углу. Попробуем? А вот и нет! Вместо какого-то вразумительного результата мы увидим консоль ошибок. Лично мне это немного испортило первое впечатление. Ну да ладно, не об этом речь, идем дальше — установка gear.js

    $ npm install gear gear-lib
    

    Всё бы хорошо, но вот только есть одна неточность — если мы хотим использовать gear из CLI, то нам придется запускать установку с флагом -g, о чём нет ни единого упоминания. Что больше всего меня удивило — возможность установить gear «browser version». Как собирать coffee или scss из браузера я не догадался, тем более во всей доке нет ни одного слова про это. Идем дальше. А дальше мы видим два примера, при чем довольно странных примера — один иллюстрирует выполнение задач со множеством файлов, второй рассказывает нам, как запустить задачи асинхронно. Собственно, это все: никаких объяснений, ничего. Два голых куска кода — как хочешь, так и понимай. Думаю «ну ладно, наверно, дальше всё объяснят», но опять нет! Дальше под грифом «Документация» мы видим просто набор API. Как что-то собирать, основвываясь на этом API, какие гайдлайны использовать, где best practice — непонятно. В общем, никакого никакого «быстрого старта» ждать здесь не приходится.

    Brunch
    Тут все неплохо. Вполне себе понятное intro-видео, описывающее процесс создания приложения с помощью brunch и ссылка «за дополнительной документацией идите на github». Разворачивание проекта по видео занимает 30 секунд, при использовании генератора можно пощупать готовые решения и посмотреть best practice. В документации подробно описаны все возможные ситуации, и, хоть FAQ и не представляет из себя кладезь знаний, но ответы на самые частые вопросы найти все-таки можно. Brunch довольно своеобразная система, не похожая ни на что другое. Это не Gulp и уж тем более не Grunt(про Gear вообще молчу — это что-то с другой планеты). Brunch предоставляет все инструменты, которые могут потребоваться разработчику для автоматизации рабочего процесса, и делает весьма легко.

    2. Производительность


    Grunt
    Grunt здесь прилично сдает свои позиции. Во-первых, использовать node.js и не использовать многопоточность — это просто грустно. Во-вторых, без дополнительных плагинов, Grunt не умеет работать с кешированием измененных файлов. Т.е. если мы изменяем 1 из 10 000 файлов Coffee, то все десять тысяч будут пересобраны. Конечно, многопоточность можно привить с помощью grunt-concurrent, а работу с кешированием — с помощью grunt-newer, но это больше похоже на monkey-patch Grunt'а, чем на полноценную реализацию. Но и это ещё не всё. Grunt имеет весьма кривой механизм для работы с потоками данных. Представьте, что нам сначала требуется собрать coffee, потом соединить все файлы, минифицировать их и прогнать тесты. Все эти действия связаны с одним и тем же набором файлов, однако Grunt этого не понимает и использует для каждой задачи свой поток ввода-вывода, т.е. каждый раз заново считывает файлы и прогоняет для них ту или иную задачу, после чего записывает результат обратно на диск и так далее, пока все задачи не будут выполнены. Согласитесь, крайне затратные операции, особенно с учётом того, что мы можем использовать для этих же целей один поток ввода-вывода информации и все операции над одними и теме же файлами выполнять в оперативной памяти. Это бы позволило достичь намного лучшего результата по производительности.

    Gulp
    По сравнению с Grunt, данная система сборки заметно выигрывает в производительности. В отличии от своего предшественника, она поддерживает из коробки возможность форка для выполнения несвязанных стеков задач в разных подпроцессах. Это дает весьма ощутимый прирост скорости. Так же стоит отметить, что Gulp использует всего один поток ввода/вывода при выполнении ряда задач с файлами. Это достигается несколько иным архитектурным решением, нежели использует Grunt. Если при создании Gruntfile вы будете указывать одни и те же маски для файлов в разных задачах, то в Gulpfile ситуация диаметрально противоположная: мы пляшем от файлов, а не от задач. Пример:

    отрывок из Gruntfile:
    ...
    concat: {
      dist: {
        src: ['src/**/*.js'],
        dest: 'dist/app.js'
      }
    },
    jshint: {
      files: ['src/**/*.js']
    }
    ...
    

    отрывок из Gulpfile:
    gulp.task('scripts', function() {
        gulp.src(['app/src/**/*.js'])
            .pipe(concat('dest.js'))
            .pipe(jshint())
            .pipe(gulp.dest('dist/build'))
    })
    

    Как мы видим, Grunt требует указания src для всех плагинов. Соответственно, это необходимо для того, чтобы при последовательном запуске, наша build-система могла понять, с какими файлами ей нужно производить манипуляции. В отличие от Grunt, Gulp требует указания src лишь для задачи, в рамках которой будут выполняться те или иные файлы, тем самым получая возможность осуществить процесс ввода-вывода всего один раз, что обеспечит нам максимальное быстродействие при сборке. Более того, как я уже сказал выше, Gulp позволяет работать с многопоточностью «из коробки», точнее, не то, чтобы «позволяет работать», а «работает по умолчанию в многопоточном режиме». Это значит, что по умолчанию все задачи будут запущены одновременно в разных потоках. Но что тогда делать, если наш concat должен выполниться только после coffee? В таком случае, мы можем просто создать зависимость! Это очень похоже на require.js, сами посудите:

    var gulp = require('gulp');
    
    // takes in a callback so the engine knows when it'll be done
    gulp.task('one', function(cb) {
        // do stuff -- async or otherwise
        cb(err); // if err is not null and not undefined, the run will stop, and note that it failed
    });
    
    // identifies a dependent task must be complete before this one begins
    gulp.task('two', ['one'], function() {
        // task 'one' is done now
    });
    
    gulp.task('default', ['one', 'two']);
    

    Как вам уже, скорее всего, стало понятно, задача two зависит от задачи one, и при запуске gulp, он выполнит сначала задачу one, и только после её выполнения перейдет к задаче two.
    Так же, мы можем подключить к Gulp плагины gulp-cached и gulp-changed, чтобы иметь возможность кешировать неизмененные файлы и прогонять в рамках задач те файлы, которые подверглись изменению с момента предыдущего запуска.

    Gear, Brunch: работают по принципу, идентичному Gulp — они максимальная параллелизация процессов. Удивительно, но остается только Grunt, которые не поддерживает этого «из коробки».

    Вывод: На скромном бенчмарке(за основу взят стандартный Gruntfile, 10 JS, 10 CSS), выяснилось, что на моей моей машине, сортируя по производительности, мы можем наблюдать сл. результаты:
    1-е место Gear(300ms)
    2-е место Gulp(~+30ms)
    3-е место Brunch(~+80ms)
    4-е место Grunt(~+180ms)

    3. Документация


    Grunt
    С этим у Grunt все хорошо. Документация компактная и полностью удовлетворяющая любым запросам. Всё необходимое для работы с системой можно найти на оф. сайте. Здесь нет никаких «но» и исключений — Grunt отлично задокументирован: просто и ёмко. Здесь вы сможете найти пример Gruntfile, все шаги для запуска и создания своей конфигурации. Разве что видео с наглядным примером нехватает, но это и не требуется при такой документации, как у Grunt.

    Gulp
    Gulp наступает на пятки Grunt: документация почти один-в-один повторяет документацию своего предшественника, разве что лежит не на сайта, а на github. Однако есть и различия: во-первых, в Get Started у Grunt лежит готовые Gruntfile, который можно сразу попробовать. Того же, к сожалению, не скажешь о Gulp. На этой странице вам просто объяснят, как его поставить и запустить. А дальше, мол, листайте доку и ищите, что вам нужно. И несмотря на то, что найти «то, что нужно» совершенно не составляет труда, это лишние телодвижения, которые явно не делают проще работу с этой системой. Понятное дело, что любой человек, который хоть раз держал в руках систему сборки представляет, что нужно делать, однако не будем забывать, что подобные разделы пишутся как раз для людей, которые слабо понимают, как с этим нужно работать. Во-вторых, нет четкого гайдлайна, как пользоваться этой системой и с какой стороны на неё смотреть. Я уверен, что люди, которые выберут Gulp в качестве своей первой системы для автоматизации сборки своих проектов, будут вынуждены искать информацию с примерами на сторонних ресурсах.

    Gear
    Всё не для людей. Документация этого проекта — простой набор API, мол, «что хочешь — то и делай». Никаких гайдлайнов или best practice вы здесь не найдете. Скажу более — в интернете, кроме mojito, эту систему не использует, наверное, никто. По крайней мере, я не нашел ни одного опровержения этой теории: ни одного сайта, который хотя бы косвенно упоминал использование этого сборщика.

    Brunch
    В git лежит 5 файлов, которые подробно описывают работу с системой и 1 FAQ. Информация простая, легкая к восприятию, но всё же хотелось бы чего-то большего. Информации в интернете про систему немного, поэтому вся экосистема brunch вертится вокруг его git репозитория и форума.

    4. Плагины


    Grunt: 2000+ плагинов, однако некоторая часть не обновлялась после релиза и/или не выпустила ни одного релиза
    Gulp: 200+ плагинов, и количество стремительно увеличивается
    Gear: А? Плагины? npmjs.org говорит, что кроме gear-lib с 5 плагинами, для этого сборщика вообще ничего не существует.
    Brunch: 50+ плагинов, тенденция к очень медленному увеличению количества

    Резюме


    Grunt
    Сложно предположить, в какую сторону сейчас может развиваться Grunt. Судя по последним changelog'ам, разработчики скорее просто хотят убрать все видимые огрехи, чем позаботиться об увеличении производительности. И лично меня это весьма сильно огорчает. Я пользуюсь этим инструментом достаточно давно, я привык к нему, но я вижу, как он потихоньку умирает, а на его место встают более свежие, оптимизированные сборщики. Конечно, как таковой, Grunt вряд ли умрет в ближайшее время. Но я чувствую сильный отток пользователей в сторону более современных систем.

    Gulp
    После Grunt, для меня это и правда «глоток свежего воздуха». Мне очень нравится направление развития этого проекта, если его авторы «не перегорят», то я думаю, что он вполне сможет заместить Grunt.

    Gear
    Исходя из всего, что я написал про Gear, я сделал для себя вывод, что проект исключительно внутренний и выложен в open source скорее для поддержания имиджа компании, а-ля «смотрите, мы тоже сделали свою реализацию build-системы», чем для реального использования. Одно я могу сказать точно: чтобы пользоваться этой системой, вам потребуется всё писать самому. Мне хватило одного взгляда на Gearfile в каталоге самой библиотеки, чтобы понять, что я не буду этим заниматься. В конце концов, я хочу использовать build-систему для упрощения работы, а не наобарот. P.S. судя по всему, проект заброшен, т.к. последние 8 месяцев активности ноль.

    Brunch
    Хороший проект, с весьма качественное реализацией. Мне немного странно, что проект с таким потенциалом развивается так медленно. Темп разработки — наверно единственное, чего не хватает этому проекту.

    P.S. Я с удовольствием приму ваши замечания и предложения по улучшению статьи, а так же буду благодарен любой информации, которая сможет дополнить её.
    Share post

    Similar posts

    Comments 18

      +5
      Grunt и Gulp на данный момент основные системы сборки, которые имеют активный community и множество активных плагинов. Остальные же практически не имеют плагинов, а это основной фактор при выборе между системами сборки.

      Grunt действительно уступает Gulp по скорости выполнения задач, но Gulp имеет значительно меньше плагинов. Портировать плагины с Grunt на Gulp не очень просто из-за разной архитектуры систем сборки, которые описал автор.

      В следующем релизе Grunt 0.5 появится возможность запускать задачи параллельно, что позволит в некоторой степени уменьшить разрыв в производительности.

      Gulp еще довольно молод и уступает по количеству plugin'ов Grunt, но community его активно поддерживает и сейчас активно портирует плагины с Grunt и разрабатывают новые.
      Yeoman уже имеет генератор для Gulp, что поможет Gulp увеличить community.

      Основное отличие между Grunt и Gulp в их философии. Вам больше подходит система сборки, которая предпочитает код вместо конфигурации? Тогда вам будет удобнее работать с Gulp. В противном случае, используйте Grunt.
        +3
        У Gulp ~2400 плагинов, т.к. есть gulp-grunt, т.е. можно переезжать прямо сейчас. Наблюдаю очень быстрый рост количества плагинов, на днях было под 400 (на gulpjs.com/plugins/ временные проблемы с выдачей списка, завтра надеюсь починят).
        Основные плагины уже перенесены на gulp, их функционал аналогичный одноимённым у grunt, прирост особенно ощутим с большим количеством файлов.
          +3
          Я бы ещё отметил Mincer. Он строится не на идеологии Makefile, а на идеологии Rails Assets Pipeline.
          +7
          Вы забыли упомянуть, что Grunt понимает underscore-шаблоны, тогда кусочек Gruntfile превращается в:

          ...
          concat: {
            dist: {
              src: ['src/**/*.js'],
              dest: 'dist/app.js'
            }
          },
          jshint: {
            files: '<%= concat.dist.src %>'
          }
          ...
            +1
            Да, вы абсолютно правы. Я привел данный пример лишь для более наглядного различия между архитектурными решениями Grunt и Gulp.
            0
            Может быть, есть какие-то плагины к grunt для инкрементального построения?
              0
              к сожалению, нет, т.к. это противоречит архитектуре Grunt. Для подобных решений существует Gulp.
                0
                +1
                В последнее время большую популярность набирает сборщик broccoli: https://github.com/joliss/broccoli

                Основная идея: Gulp + работа с напрямую с каталогами, а не файлами. Количество плагинов: ~50.

                Trending на GitHub'e в категории JavaScript
                  0
                  Спасибо, я обязательно изучу данную билд систему и постараюсь написать о своём опыте работы с ней на хабр.
                    0
                    Я перевел пост про первый бета-релиз Broccoli, если вам по-прежнему интересна данная тема, то буду рад услышать ваши комментарии.
                    +1
                    А еще Бранч имеет бесплатную поддержку на русском. Будем рады выслушать ваши вопросы на toster.ru с тегом #brunch.
                      0
                      Спасибо за Бранч. Открыл его совместно с Чаплином, когда переписывал проект по-новой (старый юзал Грант). Очень крутая вещь.
                      Отдельно хотел бы попросить плагин для Хамла.
                        0
                        Если речь идет о ruby-haml, то все системы для сборки на node будут страдать от медленности его компиляции.

                        Дело в том, что haml / sass (не libsass) будут использовать сабпроцессы для компиляции, в то время, как, например, jade — прямые вызовы node.js функций. Один тупой вызов сабпроцесса это 300мс на моей машине. Можно представить сколько времени может потенциально уйти на компиляцию реально большого проекта.

                        Есть вариант использовать haml, переписанный на node, но у него будут отсутствовать фичи. Попробуйте сделать плагин лично, это очень просто. Вот, например, Jade-brunch — 1 маленький файл. Просто если плагин делает какой-то человек, который реально его использует, то он будет даже лучше поддерживаться, чем мейнтейнерами бранча, которые на него смотрят раз в год.
                      0
                      Только вот это (по крайней чере grunt и gulp) не просто системы сборки, это системы управления задачами (в том числе и сборки). А за сравнение спасибо.
                      • UFO just landed and posted this here
                          0
                          Иллюстрацию каких параметров вы хотите видеть в рамках этого сравнения?
                          О каком коде идет речь?
                          Статистические показатели указаны в статье. Если вы считаете, что каких-то показателей нехватает, не могли бы вы конкретизировать?

                        Only users with full accounts can post comments. Log in, please.