в начало заметок о компонентах
task runners — класс утилит, автоматизирующих процесс преобразования файлов. Их много, Make, Rake, Cake, etc. Обычно выполняемые задачи очень важны и выполняются часто, и очень часто. Компиляция, запуск тестов, рендеринг и преобразование форматов файлов, минификация js-файлов, преобразование CSS. Крайне важная вещь для ежедневной работы.
grunt (хрюкание). Gruntfile.js — это конфигурационный файл для утилиты grunt. Gruntfile.js интуитивно понятен, одного взгляда на образец достаточно, чтобы создать подобный для своей задачи. Но gruntfile.js крайне уродлив, вдобавок авторы
gulp (глоток «свежего воздуха»). В отличие от gruntfile.js, gulpfile.js является не конфигурационным файлом, а программой на node.js. Посмотрите сравнение двух файлов. Да, это много удобнее и привычнее. Вдобавок, плагины gulp выполняют каждый свою задачу. Например, чтобы минифицировать js-файл, нужно вызвать два плагина, один минифицирует файл, а другой переименует его в файл.min.js. Это правильно. Но размер guplfile.js почти не меньше, чем gruntgile.js, и в десятый раз создавать его столь же унылый процесс. Тем не менее, дело вкуса, но, имхо,
Make же великолепен, и мощен, но Makefile имеет тот недостаток, что он весьма непонятен. Есть либо полное, очень подробное и сухое описание — учебник. Либо множество руководств, пересказывающих один и тот же текст из 1960-х годов прошлого тысячелетия, когда не существовало еще языков программирования, а язык C был еще в разработке. Вот эти замшелые примеры на C и пересказываются. Однако, разобраться в Makefile можно. Это позволит забыть и о
target-правила в Makefile организованы так:
здесь
Если
правила нужно разделять пустой строкой.
pattern правила описывают, что делать с конкретным расширением, и имеют вид:
phony-правила — это не файлы, а команды. Они могут иметь исходники, рекурсию и все, что имеют другие правила, но для них не вычисляется mtime. Например:
phony-правила нужно описать в специальной переменной
Есть автоматические, предзаданные переменные, их нужно понимать. Вот несколько часто встречающихся $@ — имя цели, $+ — все исходники, через пробел, $<; — имя первого исходника. Полный список в учебнике — http://www.gnu.org/software/make/manual/make.html#Automatic-Variables
Обычные переменные (файлы, требующие обработки, цели, имеющие файлы в исходниках) — можно просто перечислить
но часто удобно их вычислять с помощью shell:
или с помощью встроенной утилиты wildcard:
Или определить
В последнем случае сами html-файлы пока не создаются, но только массив их имен для дальнейшей обработки.
Что здесь происходит? make встречает имя components, обнаруживает такую директорию, и если мы внесли изменения в файл component.json, выполняет install.
Далее он переходит к SRC, это массив файлов JS. Он смотрит 'исходники' первого файла .js, находит pattern-правило для .js и выполняет его из исходника .html. Затем собирает все в единый
еще пример:
пример pattern-правил — обработать coffee, jade:
Естественно, утилиты
watch — это не компонента, не node.js утилита, а обычная unix-утилита. (Странно, что ее нет в Altlinux, например).
клонируем и ставим ее:
и запускаем
Сравните с тем, что нужно сделать для отслеживания изменений в исходниках, и авто-перекомпиляции в
В Makefile можно организовать то же самое и без утилиты watch:
продолжение следует
make vs. grunt vs. gulp, watch
task runners — класс утилит, автоматизирующих процесс преобразования файлов. Их много, Make, Rake, Cake, etc. Обычно выполняемые задачи очень важны и выполняются часто, и очень часто. Компиляция, запуск тестов, рендеринг и преобразование форматов файлов, минификация js-файлов, преобразование CSS. Крайне важная вещь для ежедневной работы.
grunt (хрюкание). Gruntfile.js — это конфигурационный файл для утилиты grunt. Gruntfile.js интуитивно понятен, одного взгляда на образец достаточно, чтобы создать подобный для своей задачи. Но gruntfile.js крайне уродлив, вдобавок авторы
gulp
пишут, что grunt
крайне неэффективен. Писать, и читать gruntfile.js
быстро становится очень скучно.gulp (глоток «свежего воздуха»). В отличие от gruntfile.js, gulpfile.js является не конфигурационным файлом, а программой на node.js. Посмотрите сравнение двух файлов. Да, это много удобнее и привычнее. Вдобавок, плагины gulp выполняют каждый свою задачу. Например, чтобы минифицировать js-файл, нужно вызвать два плагина, один минифицирует файл, а другой переименует его в файл.min.js. Это правильно. Но размер guplfile.js почти не меньше, чем gruntgile.js, и в десятый раз создавать его столь же унылый процесс. Тем не менее, дело вкуса, но, имхо,
gulp
много удобнее grunt
.Make же великолепен, и мощен, но Makefile имеет тот недостаток, что он весьма непонятен. Есть либо полное, очень подробное и сухое описание — учебник. Либо множество руководств, пересказывающих один и тот же текст из 1960-х годов прошлого тысячелетия, когда не существовало еще языков программирования, а язык C был еще в разработке. Вот эти замшелые примеры на C и пересказываются. Однако, разобраться в Makefile можно. Это позволит забыть и о
grunt
, и о gulp
. В component-сообществе, как и node-сообществе Makefile
очень популярен, поэтому и обсуждается здесь.Makefile — обзор
make
может выполнять любые shell-команды, и обрабатывать файлы любых типов, ограничений нет. Единственное — перед командой должен быть не пробел, а табулятор. (Все же прошлое тысячелетие, сильные были люди). Еще замечание — есть жалобы на имена файлов, имеющие пробелы.Макеfile
состоит из описания переменных и правил.target-правила
target-правила в Makefile организованы так:
target: sources
tab -> commands
tab ->tab -> commands, сл. строка той же команды
здесь
target
— то, что нам нужно получить, sources — массив файлов исходников. Обычно target
— это просто файл, за исключением специальных PHONY
целей (см. ниже).Если
make
встречает ошибку, он прерывает работу. (опция -i игнорировать ошибки).make
использует mtime
— время последнего изменения файла. target
считается готовым, если во-первых, он уже существует, и во-вторых он новее, чем его исходник. Поэтому make обрабатывает только те файлы, которые изменились.make
начинает с цели-target заданного правила. Если вызвать make без параметра, то это первое правило. Он смотрит исходники, и если для них есть свои правила, рекурсивно проверяет их. Порядок обработки исходников в массиве произвольный!make
идет вниз по цепочке исходников, пока не находит готовой цели, или цели не имеющей исходников, или его исходники не имеют своих правил. Когда он находит такой случай, он возвращается обратно по цепочке рекурсии, выполняя соответствующие команды. make
создает цепочки рекурсии для каждого исходника.правила нужно разделять пустой строкой.
pattern правила
pattern правила описывают, что делать с конкретным расширением, и имеют вид:
%.js: %.html
@component convert $<;
phony — правила
phony-правила — это не файлы, а команды. Они могут иметь исходники, рекурсию и все, что имеют другие правила, но для них не вычисляется mtime. Например:
clean:
rm -fr build components $(TEMPLATES)
.PHONY: clean
phony-правила нужно описать в специальной переменной
.PHONY
описание переменных
Есть автоматические, предзаданные переменные, их нужно понимать. Вот несколько часто встречающихся $@ — имя цели, $+ — все исходники, через пробел, $<; — имя первого исходника. Полный список в учебнике — http://www.gnu.org/software/make/manual/make.html#Automatic-Variables
Обычные переменные (файлы, требующие обработки, цели, имеющие файлы в исходниках) — можно просто перечислить
JS = index.js example.js
но часто удобно их вычислять с помощью shell:
CF = $(shell find templates -name "*.coffee")
или с помощью встроенной утилиты wildcard:
SRC = $(wildcard client/*/*.js)
Или определить
targets
из уже созданной переменной:HTML = $(JADE: .jade=.html)
В последнем случае сами html-файлы пока не создаются, но только массив их имен для дальнейшей обработки.
примеры задания переменных и правил:
SRC = $(wildcard client/*/*.js)
HTML = $(wildcard client/*/*.html)
TEMPLATES = $(HTML:.html=.js)
build: components $(SRC) $(TEMPLATES)
@component build
components: component.json
@component install
%.js: %.html
@component convert $<;
Что здесь происходит? make встречает имя components, обнаруживает такую директорию, и если мы внесли изменения в файл component.json, выполняет install.
Далее он переходит к SRC, это массив файлов JS. Он смотрит 'исходники' первого файла .js, находит pattern-правило для .js и выполняет его из исходника .html. Затем собирает все в единый
build/build.js
см. component build
, component convert
.еще пример:
JADE = $(shell find templates -name "*.jade")
HTML = $(JADE:.jade=.html)
all: $(HTML)
%.html: %.jade
jade < $< > $@
пример pattern-правил — обработать coffee, jade:
%.js: %.coffee
@coffee -c $<
%.js: %.jade
@jade -c $<
Естественно, утилиты
coffee
, jade
должны быть установлены в системе.watch
watch — это не компонента, не node.js утилита, а обычная unix-утилита. (Странно, что ее нет в Altlinux, например).
клонируем и ставим ее:
$ PREFIX=~ make install
и запускаем
make
$ watch make &;
Сравните с тем, что нужно сделать для отслеживания изменений в исходниках, и авто-перекомпиляции в
grunt
. В gulp
эта функциональность встроенно в ядро, а не является плагином. Но от этого не легче, чтобы запустить ее в gulpfile.js
. Даже не хочется приводить пример кода.В Makefile можно организовать то же самое и без утилиты watch:
.PHONY: continuously
continuously:
while true; do make 1>/dev/null; sleep 3; done
продолжение следует