Broccoli: первый бета-релиз

Original author: Jo Liss
  • Translation
Broccoli является новой системой автоматической сборки. Её вполне можно сравнить с Rails asset pipeline, однако есть и некоторые различия: он запускается на Node.JS и не зависит от серверной части приложения.

После длинной вереницы 0.0.х альфа релизов, я только что выпустила первую бета версию, Broccoli 0.1.0.

Оглавление:

  1. Быстрый пример
  2. Мотивация / Особенности
  3. Архитектура
  4. За кулисами / Общий взгляд
  5. Сравнение с другими системами сборки
  6. Что дальше?


1. Быстрый пример


Ниже представлен пример конфигурационного файла для билда(Brocfile.js). Комментарии намеренно опущены, пример приведен только для того, чтобы проиллюстрировать синтаксис:

module.exports = function (broccoli) {
  var filterCoffeeScript = require('broccoli-coffee');
  var compileES6 = require('broccoli-es6-concatenator');

  var sourceTree = broccoli.makeTree('lib');
  sourceTree = filterCoffeeScript(sourceTree);

  var appJs = compileES6(sourceTree, {
    ...
    outputFile: '/assets/app.js'
  });

  var publicFiles = broccoli.makeTree('public');

  return [appJs, publicFiles];
};

Запустите broccoli serve, чтобы начать отслеживать изменения исходных файлов. При каждом изменении любого файла из списка отслеживаемых, broccoli автоматически пересоберет его в целевой директории. Broccoli оптимизирован выполнять serve максимально быстро, поэтому вы не должны испытывать паузы между очередными сборками.

Запустите broccoli build dist, чтобы выполнить единовременную сборку и положить результат в папку dist.

Для более подробного примера, взгляните на broccoli-sample-app

2. Мотивация / Особенности


2.1. Быстрый ребилд

Главной задачей при проектировании Broccoli, была реализация быстрых инкрементальных сборок. И вот почему:

Например, вы используете Grunt для сборки приложения, написанного на CoffeeScript, SASS, и еще нескольких препроцессорах. Когда вы что-то разрабатываете, вы хотите редактировать файлы и сразу же видеть результат в браузере, без постоянных запусков билд системы. Так вот, для этой цели вы используете grunt watch, но по мере увеличения вашего приложения, сборка происходит все медленней и медленней. После нескольких месяцев работы над проектом, ваш цикл «отредактировал-обновил» превращается в «отредактировал-подождал-10-секунд-обновил».

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

С помощью Broccoli, вы можете просто запустить broccoli serve, и он сам поймет, какие файлы необходимо отслеживать, и будет пересобирать только те, которые в этом нуждаются.

В результате, это означает, что ребилд, как правило, должен иметь O(1) постоянное время выполнения, вне зависимости оттого, какое количество файлов используется в проекте, т.к. собирается всегда только один. Я стремлюсь к результату в 200ms на каждую сборку с типичным набором задач, а т.к. такое время задержки кажется почти мгновенным для человеческого мозга, то для меня приемлемы результаты до половины секунды.

2.2. Цепочки плагинов

Другая важная задача — возможность компоновки вызова плагинов. Давате рассмотрим пример, чтобы показать как просто, используя Broccoli, вы можете компилировать CoffeeScript с последующей минифакцией:

var tree = broccoli.makeTree('lib')
tree = compileCoffeeScript(tree)
tree = uglifyJS(tree)
return tree

Используя Grunt, вам бы пришлось создавать временную директорию(помимо итоговой), чтобы сохранить туда вывод CoffeeScript. В результате всех этих манипуляций, Gruntfile обычно разрастается до довольно больших размеров. С помощью Broccoli, все подобные действия разруливаются автоматически.

3. Архитектура


Для особо любопытных, позвольте мне рассказать об архитектуре Broccoli.

3.1. Деревья, а не файлы

В качестве уровня абстракции для описания исходных и выходных данных используются не файлы, а деревья — директории с файлами и поддерикториями. Получается, что мы имеем не «файл-на-вход-файл-на-выход», а «дерево-на-вход-дерево-на-выход».

Если бы Broccoli работал с отдельными файлами, мы бы по-прежнему смогли компилировать CoffeeScript без проблем(т.к. файлы компилируются в соответствии 1 к 1), однако это вызвало бы проблемы при взаимодействии API с такими препроцессорами, как SASS(который позволяет использовать @import , что позволяет компилировать n файлов в 1).

Однако Broccoli спроектирован таким образом, что решение задач для препроцессоров типа SASS(n:1) не вызывает проблем, а задачи для препроцессоров типа CoffeeScript(1:1) легко решаются как частный случай n:1. А вообще, для таких(1:1) преобразований, у нас имеется класс Filter, который позволяет максимально просто использовать их в своих решениях.

3.2. Плагины просто возвращают новые деревья

Сперва, я спроектировала Broccoli с двумя примитивами: tree(далее «дерево»), которое представляют директории с файлами и transform(далее «преобразование»), которое берет на входе дерево и возвращает на выходе новое, скомпилированное дерево, после преобразований.

Это подразумевает, что мы преобразовываем деревья 1:1. Удивительно, но это не всегда является хорошей абстракцией. Например, в SASS есть «пути загрузки», которые используются для поиска файлов при использовании директивы @import. По схожему принципу работают конкатенаторы вроде r.js: у него существует опция «paths», которая отвечает за поиск импортируемых модулей. Лучший способ представления таких путей — сет(структура данных), состоящий из деревьев.

Как вы можете заметить, в реальном мире многие компиляторы/препроцессоры собирают n «деревьев» в одно. Простейший способ придерживаться подобного подхода — позволять плагинам разбираться со своими входными «деревьями» самим, тем самым позволяя им принимать 0, 1 или n «деревьев» на вход.

Но теперь, когда мы решили, что плагины сами будут обрабатывать свои входные деревья, нам больше не нужно знать о компиляторах как об объектах первого порядка. Плагины просто экспортируют функцию, которая принимает от нуля до n исходных деревьев(и, возможно, какие-то настройки), и возвращает объект, представляющий новое дерево. Например:

broccoli.makeTree('lib') // => a tree
compileCoffeeScript(tree) // => a tree
compileSass(tree, {
  loadPaths: [moreTrees, ...]
}) // => a tree


3.3. Файловая система и есть наше API

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

Чтобы избежать этого, первое, что приходит на ум — вынести представление файловой системы в память, где наши деревья будут представлены в виде коллекции потоков. Gulp так и делает. Я тоже пыталась реализовать такой подход в ранних версиях Broccoli, но это обернулось тем, что код стал достаточно сложным: с потоками, плагины должны были следить за очередями и взаимными блокировками. Также, к слову о потоках и путях: нам могут потребоваться атрибуты вроде времени последнего изменения или размера файла. Или, например, если нам будет необходима возможность считать файл заново или что-либо найти, отобразить файл в памяти, или, в конце концов, если нам потребуется передать входное дерево другому процессу через терминал — тут наше API для работы с потоками не сможет нам помочь, и нам придется сначала записать всё дерево в файловую систему. Слишком сложно!

Но подождите, если мы собираемся копировать каждую особенность файловой системы, а иногда и выдергивать из памяти наши деревья и перегонять их в физическое представление, после чего опять класть их в память, и опять… Почему бы просто не использовать файловую систему вместо потоков?

Модуль fs Node.JS уже предоставляет необходимый нам API к файловой системе — все, чего мы можем только пожелать.

Единственное неудобство заключается в том, что нам придется работать с временными директориями «за сценой», а потом надо будет прибраться. Но, на самом деле, это не так сложно, как кажется.

Люди иногда беспокоятся, что запись на диск происходит медленнее, чем в память. Но даже если вы возьмете рельный жесткий диск, то пропускная способность современных SSD становится настолько высокой, что ее можно сравнить со скоростью работы CPU, а это означает, что мы получаем лишь незначительные накладные расходы.

3.4. Кеширование вместо частичного ребилда

Когда я пробовала решить проблему инкрементальных сборок, я пыталась разработать способ проверить, какие файлы нужно пересобирать, чтобы позволить Broccoli вызывать это событие только для подмножества исходных файлов. При инкрементальной сборке нам необходимо знать, от каких исходных файлов зависит результат, ведь зачастую мы сталкиваемся с отношениями n:1. «Частичная сборка» — это классический подход Make, так же как и Rails asset pipeline, Rake::Pipeline или Brunch, но лично я для себя решила, что это ненужные трудности.

Подход Broccoli намного проще: мы просим все плагины кешировать выходные данные. Когда мы пересобираем проект полностью или когда мы перезапускаем отдельные плагины — большая часть информации будет браться из кеша самих плагинов, что будет занимать мизерное время.

Сначала Broccoli предоставлял некоторые кеширующие примитивы, но позже было решено исключить их из API ядра. Теперь мы просто ограничиваемся тем, что предоставляем архитектуру, которая не мешает реализации кеширования.

Для плагинов, которые мапятся 1:1, таких, как CoffeeScript, мы можем использовать общий кеширующий механизм(представленный в пакете broccoli-filter), оставляя код плагина очень простым. Плагины, которые собираются n:1, такие, как SASS, требуют более тщательной заботы о кешировании, поэтому для них требуется реализовывать особенную логику для работы с кешем. Я полагаю, что в будущем мы все же сможем выделить какую-то общую часть логики кеширования.

3.5. «Нет» параллельности

Если мы все страдаем от медленного выполнения сборок, может стоит попробовать выполнять задачи параллельно?

Мой ответ — «нет»: параллельный запуск задач делает возможным возникновение проблем с очередностью внутри плагинов, которые вы можете не заметить вплоть до деплоя. Это самые худшие из багов, поэтому уходя от параллельного запуска, мы ограждаем себя от целой категории багов.

С другой стороны, закон Амадаля останавливает нас от выигрыша большой производительности, при использовании параллельных запусков. Давайте приведем простой пример: наша сборка занмиает 16 секунд. Представим, что 50% мы можем запускать параллельно, а оставшаяся часть должна запускаться в порядке очереди(а-ля coffee->concate->uglify). Если мы запустим такую сборку на четырехядерной машине, то сборка будет занимать 10 секнуд: 8 секунд на синхронную часть, и 8 / 4 = 2 секунды на параллельную часть. В результате время сборки все равно целых 10 секнуд, а это всего лишь +40% производительности.

Для инкрементальных сборок, которые интересуют нас более всего, кеширование сводит к минимуму большинство преимуществ параллельного запуска задач, поэтому мы почти не проигрываем в производительности.

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

4. За кулисами / Общий взгляд

В основе моего решения написать хорошую систему сборки лежат две причины.

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

Вообще, я верю, что продуктивность разработчика определяется качеством библиотек и инструментов, которыми он пользуется. Цикл «отредактировал, перезагрузил страницу» мы повторяем изо дня в день по несколько сотен раз, и это, возможно, основной способ получения обратной связи. И если мы хотим улучшить производительность наших инструментов, надо сделать этот цикл настолько быстрым, насколько это возможно.

Вторая причина кроется в поддержке экосистемы front-end пакетов.

Я верю, что Bower и модульная система ES6 помогут нам построить прекрасную экосистему, но Bower сам по себе бесполезен, пока вы не надстроите над ним систему сборки. Вот почему Bower является абсолютно ни к чему не привязанным инструментом, позволяющим загружать все зависимости вашего проекта(рекурсивно, вместе с их зависимостями) в файловую систему — это все, что можно сделать с помощью него. Broccoli же нацелен стать именно тем недостающим звеном — надстройкой в виде системы сборки, под которой тот будет работать.

Кстати говоря, Broccoli сам по себе никак не связан с Bower или модулями ES6 — вы можете использовать его с тем, с чем захотите. (я знаю, что есть и другие связки, например npm + browserify, или npm + r.js.) Я затрону их в одном из следующих своих постов.

5. Сравнение с другими системами сборки

Если я вас почти убедил, но вам все еще интересно, как другие системы сборки ведут себя в сравнении с Broccoli, то позвольте мне объяснить, почему я написала Broccoli вместо того, чтобы использовать одну из нижеперечисленных:

Grunt — это инструмент для запуска задач, и он никогда не позиционировался, как система для сборки. Если вы попробуете использовать его как систему сборки, вы быстро разочаруетесь, т.к. он не предоставляет возможности использовать цепные вызовы(композицию), и вам быстро надоест разбираться со временными директориями, а тем временем файл конфигурации будет все разрастаться и разрастаться. Так же он не может обеспечить надежные инкриментальные сборки, поэтому ваши повторные сборки будут выполняться медленно и/или будут ненадежны, см. «Быстрый ребилд» выше.

Grunt создан как инструмент для запуска задач, который позволяет получить функциональность shell-скриптов на любой платформе, например скаффолдинг или деплой вашего приложения. В будущем, Broccoli будет доступен как плагин для Grunt, так что вы сможете вызывать его прямо из своего Gruntfile.

Gulp пытается решить проблему с последовательным вызовом плагинов, но, как по мне, он страдает определенными ошибками в архитектуре: несмотря на то, что вся его работа крутится вокруг «деревьев», они реализованы последовательностью файлов. Это отлично работает, когда один исходный файл преобразоввывается в один конечный файл. Но когда плагину требуется следовать import директивам, а это требует обращение к файлам вне очереди, работа усложняется. Сейчас, плагины, которые используют import директивы, приостанавливают выполнение сборки и считывают необходимые файлы прямо из файловой системы. В будущем, я слышала, будут использованы библиотеки, которые позволят запускать все потоки на виртуальной файловой системе и передавать их компилятору. Я считаю, что все эти усложнения — симптом полного несоответствия между системой сборки и компилятором. Вы можете еще раз прочесть раздел «Деревья, а не файлы», там я более подробно останавливался на этом вопросе. Я так же совсем не уверен, что абстрагируясь от файлов к потокам или буферу, мы получим более удобное API; см. «Файловая система и есть наше API».

Brunch, как и Gulp, использует API, основанное на файлах(а не на деревьях). Так же как и в Gulp, плагины, в конце концов, идут в обход системы сборки, когда им необходимо получить более одного файла. Brunch так же пытается выполнять частичный ребилд вместо кеширования, см. «Кеширование вместо частичного ребилда» выше.

Rake::Pipeline написан на Ruby, который менее вездесущ, чем Node в мире front-end разработки, и он так же пытается выполнять частичные сборки. Иегуда Кац сказал, что система не очень активно поддерживается, и он ставит на Broccoli.

Rails asset pipeline так же использует частичные сборки, и, более того, использует весьма различные подходы для разработки и продакшена, что может привести к весьма неожиданным ошибкам в момент деплоя. Но, что важнее, он требует ROR на бэкэнде.

6. Что дальше


Список плагинов все еще невелик. Но если этого достаточно для ваших задач, я бы настоятельно рекомендовала дать Broccoli шанс: https://github.com/joliss/broccoli#installation

Я бы хотела увидеть, как другие люди вовлекаются в разработку плагинов. «Заворачивать» компиляторы достаточно просто, но самое важно и тяжелое — это добиться правильного кеширования и минимальных потерь в скорости. Мы хотим выделить больше шаблонов кеширования, чтобы сократить повторяющийся код в плагинах.

В ближайшие пару недель в мои планы входит улучшение документации и вычищение кода ядра Broccoli и плагинов. Мы так же хотим добавить тесты для ядра Broccoli и предоставить элегантное решение интеграционных тестов для плагинов. Так же, в наших существующих плагинах отсутствует поддержка source map'ов. Это весьма накладно с точки зрения производительности, т.к. плагинам, при последовательном вызове, приходится брать Source Maps предыдущего плагина и правильно их интерполировать, но я пока еще не нашла времени заняться этим.

Скоро вы сможете увидеть активное использование Broccoli в экосистеме фреймворка Ember, который будет обеспечивать дефолтный стек ember-cli(скоро появится, по функциональности похожа на rails command line). Мы так же надеемся заменить Rake::Pipeline и Grunt при процессе сборки ядра Ember.

Я бы так же очень хотела увидеть Broccoli адаптированным под проекты вне Ember-сообщества. JS MVC приложения, написанные с помощью таких фреймворков, как Angular или Backbone, различные JS и CSS библиотеки, требующие сборок — главные кандидаты, чтобы быть собранными с помощью Broccoli. Используя Broccoli для реальных сценариев сборки, мы должны удостовериться в надежности его API, и я надеюсь, что в ближайшие несколько месяцев мы сможем выпустить первую стабильную(1.0.0) версию.

Этот пост является первым постом, детально рассматривающим архитектуру Broccoli, так что справочной информации/документации все еще мало. Я буду рад помочь вам начать работу, и исправить любые баги, с которыми вы столкнетесь. Вы можете найти меня на #broccolijs на Freenode, или написав мне на почту/позвонив в Google Talk: joliss42@gmail.com. Я так же буду рад ответить на любые интересующие вас вопросы в соответствующем разделе на Github.

Особые благодарности Jonas Nicklas, Josef Brandl, Paul Miller, Erik Bryn, Yehuda Katz, Jeff Felchner, Chris Willard, Joe Fiorini, Luke Melia, Andrew Davey, and Alex Matchneer за чтение и критику черновиков этой статьи.

От переводчика

Я бы хотел поблагодарить z6Dabrata и Марию Кузовчикову за помощь в корректировании этого перевода.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 18

    +1
    Неплохо, но надо еще подумать над этим
      +1
      Вы имеете ввиду перевод или саму систему сборки?
      0
      Выглядит интересно и разумно, но мне кажется не взлетит. Не зря ведь инвалидацию кеша называют одной из сложнейших задач в программировании. Да и просто сваливать главную фичу кеширование на авторов плагинов не разумно — не думаю, что народ будет запариваться на написание плагинов. Тот же gulp вполне не плохо со своей задачей справляется пусть у него и подход 1:1.
        0
        Так ведь написано, что хотят вынести повторяющиеся операции с кэшированием в отдельные модули, которые уже сторонние авторы смогут использовать в плагинах. Без этого, конечно, все было бы грустно.

        P.S. Все таки лень двигатель прогресса %-)
        0
        Система сборки не должна заниматься компилированием ресурсов. Компиляция должна лежать на уровне ниже — чтение файлов. Таким образом, изменив `menu.css` на `menu.less`, или `collapser.js` на `collapser.es6` — это не должно затрагивать систему сборки — всё должно оставаться как есть и работать сразу. И такой подход нас «бесплатно» избавляет от длительных компиляций при `лайфрелоуде`.

        А второе — (спорно, но важно) — в dev моде вообще не должно быть никаких процессов сборки. Стили, скрипты и шаблоны подгружаются в не собранном виде. То есть, ресурсы подгружаются отдельно и только те которые нужны в данный момент. Это упрощает разработку в разы — в developer tools у нас все файлы по отдельности, и только те которые используются в данном сценарии.

        А система сборки применяется единожды перед деплоем.
          +3
          А второе — (спорно, но важно) — в dev моде вообще не должно быть никаких процессов сборки

          В таком случае, объясните мне пожалуйста, как вы будете собирать SASS, Haml?
          Как вы считаете, оптимальнее каждый раз в режиме реального времени заново собирать все coffee файлы? Аналогичную задачу может решить инкрементальная сборка: ставите вотчер на coffee, после первой сборки он кеширует сохраненное состояние, а при сл. операции над каким-либо файлом, он выполнит сборку только для него. На моей, не особо мощной машине, это занимает 200 ms, а настройка решения занимает 5 минут, если разворачивать систему сборки с нуля. Аналогичное решение для компиляции coffee в js с последующим выполнением, я, признаться, не видел, и с трудом могу себе представить: в какой момент вы будете запускать компиляцию? Как вы будете избегать компиляции неизмененных файлов? Если вы в dev режиме не минифицируете файлы, то каким образом вы скомпилируете все файлы? Если же вы хотите компилировать не все файлы, а только по мере их использования, как вы это собираетесь делать? Приведите, пожалуйста, любой, пускай даже самый простой пример того, как это будет выглядеть. Предположим, у нас есть модуль А и модуль Б, они написаны на coffee. И есть точка входа в проект — index.html, из которой должен быть вызван модуль А, который зависит от модуля Б. Какое решение для «компиляции на лету» вы бы предложили? (я не стараюсь катить бочку, поймите правильно, я просто не вижу рационального пути решения этой задачи без системы сборки, или, как минимум, таск раннера а-ля Grunt).

          Это упрощает разработку в разы — в developer tools у нас все файлы по отдельности, и только те которые используются в данном сценарии.

          В чём состоит упрощение? В Chrome Dev Tools уже давно есть поддержка source maps, но, прошу заметить, я нигде не говорил, что при инкриментальной сборке проекта в dev режиме, вам требуется минифицировать файлы.
            0
            Я также за рациональный путь) А всё очень просто — HttpHandlers или file reader hooks. Это вводит дополнительную абстракцию в систему чтения/запроса файлов. Понимаете системе сборки или браузеру абсолютно не важно, что в файле coffeescript, при чтении файла он автоматически превращается в javascript — эдакий file middleware. Также и со стилями, в файле less, а при чтении получаем `css`. Вот и получается, что о компиляции нам больше нигде не нужно беспокоится, и о ней можно забыть — это всего лишь файл, обычный javascript. Вот теперь как быть с этим javascript, где и как его собирать, какую модульную систему использовать — вот что важно. А здесь много разных вариантов — мы используем свое решение, в дев моде каждый файл загружает свои зависимости сам, через обычный <script src="/file.es6"></script> (с source maps конечно). А для релиза все собираем. Много чего ещё есть, на этом собаку сьели, так что, если есть другие рациональные вопросы, буду рад ответить.
              +1
              Если я не ошибаюсь, то HttpHandlers — это ASP.NET решение, а веб-разработка, как вы понимаете, крутится не только вокруг него. Тем более, судя по всему, вы выполняете ту же задачу, которую выполняет система сборки, только делаете это своим велосипедом способом. И, я по-прежнему не понимаю, как вы будете компилировать SASS(а не less) и Haml.
                0
                Нет, я о httphandler как о обработчике запроса в общем, браузер запрашивает 'menu.sass', а запрос обрабатывает не static handler, а обработчик который предварительно компилирует ресурс. Такое реализуется на любом бэкенде, и asp.net здесь не причем. И для большинства уже все есть, ничего самому делать не нужно.
                Скажите, а чем отличается server side компилирование Lessa от server sidе компилирования sassa? Препроцессор есть как для первого так и для второго.
                Я лишь предлагаю более чистую архитектуру, а не велосипед.) А вы выступаете за комбайн который делает все сразу, но при этом в конфиге настраиваете компиляцию ресурсов и боретесь с прочими не нужными вещами.
                  0
                  Скажите, а чем отличается server side компилирование Lessa от server sidе компилирования sassa

                  У меня были сомнения, что вы собираетесь компилировать LESS на фронте.

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

                  Почему же? Я выступаю за систему сборки, которая имеет, к примеру, 3 задачи: собрать dev, собрать production, повесить вотчер для инкрементальной сборки(для dev). Когда вы запускаете dev билд, у вас выполняется стандартный набор действий: А, Б, В. Когда вы запускаете production билд, у вас запускается dev билд(А, Б, В), а потом запускается еще Г, Д, Е. Если же запускать инкрементальную сборку, то мы видим следующее: в системе висит демон, который отслеживает изменения для опр. формата файлов в директориях проекта, и при каждом изменении файла, он собирает его, используя его зависимости и кладет в результирующую директорию.

                  На самом деле, мы говорим не о таких разных вещах. Просто, насколько я понимаю, у вас есть одно решение для dev сборок(на уровне обработок запроса пользователя) и другое решение для production сборок. Я же просто сторонник того, что любую сборку должен выполнять один и тот же инструмент, просто по разным сценариям. В этом есть и другой плюс: т.к. мы рассматриваем инструменты для frontend разработчика, то будет справедливо сказать, что большая часть javascript программистов не знают серверных ЯП, и/или не знакомы с настройкой nginx/apache, а это значит, что путь сборки, подобный тому, что вы предложили, будет на порядок сложнее, т.к. он требует доп. знаний, но очевидных преимуществ не несет: нам все равно нужна система для сборки production, верно?
                    +1
                    Понимаете, у меня в деве никаких тасков `а, б, в` нету. Открыл браузер, редактор и вперед. А так как у нас ещё к тому же компонентная архитектура приложений, то поддерживается лайфрелоуд не только стилей, но и js кода. Быстрый пример:
                    Youtube


                    Но здесь я не хочу вас переубеждать, что и как лучше — если вам удобнее так как вы описываете, то я только рад. Но для себя я определился и другим также советую — настраивать систему разработки так, что бы компиляция происходила на самом нижнем уровне — при чтении файла. Таким образом, будет казаться, что браузер поддерживают coffescript например `нативно`. (_подключил файл через `script` тэг и он работает_). И тогда останется выбрать лишь модульную систему которая загружает скрипты/стили. Для которой определённо уже имеется свой `builder`. А код может быть написан, хоть частично на typescript, частично на coffee, a остаток на es6 — все равно каждый файл в результате при чтении становится js, или css, или…. И это жуть как удобно )
                      0
                      Понимаете, я совершенно не против вашего подхода. Я абсолютно уверен, что в рамках вашего проекта это решение прекрасно работает. Дело лишь в том, что на мой взгляд, нельзя сказать, что для всех систем ваше решение является оптимальным, а сказанные вами слова
                      Система сборки не должна заниматься компилированием ресурсов
                      или
                      в dev моде вообще не должно быть никаких процессов сборки
                      являются слишком громкими.

                      В конце концов, мы здесь обсуждаем систему сборки Broccoli, а не разницу в подходах ;)
                      Я бы с удовольствием перенес наше общение в лс, чтобы оставить в этой ветке только сообщения, относящиеся к теме.
                        +1
                        Полностью вас поддерживаю, что сборка должна быть лишь перед деплоем.
                        В соседнем посте я писал о basis.js. Так вот в dev все разобрано, тоже есть live update (только js не обновляем, это нельзя сделать безопасно). Перед деплоем все это собирается. По принципу «граф на входе, граф на выходе», которые отстраиваются самостоятельно, по переданному индексному html файлу.
                        Я думаю, будущее именно за такими системами разработки и сборки.
            –1
            в PhpStorm добавили поддержку Grunt из коробки в EAP версии. Это конечно не самый правильный подход, реализовывать все функции связанные со сборкой проекта в IDE, но все-таки есть некая сермяжная правда в этом.
            Установил IDE и начал работать, хотя для сборки Sass все равно исползуется внешний ruby движок
              0
              Почему-то с mincer нет сравнения. Может кто-нибудь поделиться опытом?
                0
                mincer хорошая вещь. сам его использую, но он обычно требует дополнительной обвязки под конкретный проект. хотя если честно, то думаю что его можно заменить сборщиком и набором плагинов к нему (+ загрущик манифеста).
              • UFO just landed and posted this here
                  +1
                  Почему вы считаете данную тему бесполезной?
                  О каких корыстных целях вы говорите?

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