Кто не знаком с тем, что при написании кода очень часто возникают ошибки или банальные опечатки?
И даже если установлены такие палочки-выручалочки, как Emmet, это не всегда спасает из ситуации. А если представить, что вы пишете большой проект и в нем закралась ошибка, то нелегко будет ее найти в куче кода.
При использовании Gulp, который автоматически отслеживает события и выполняет соотвествующие задачи, ситуация несколько “облегчается” тем, что при возникновении ошибки можно увидеть тот момент, когда она произошла.
Например, Gulp настроен на автоматическое фиксирование изменений через
1
gulp.watch
. Если возникла ошибка, то выполнение мониторинга в Gulp прерывается:
Но даже в этом случае довольно трудно разобраться, где именно закралась ошибка. В этой ситуации может помочь плагин gulp-plumber, который формирует вывод об ошибке. Но при этом работа Gulp не прерывается.
Давайте установим и попробуем в работе плагин
1
gulp-plumber
.
Установка плагина gulp-plumber
Установка плагина
1
gulp-plumber
стандартная, через менеджер пакетов
1
npm
с ключом
1
--save-dev
:
Использование плагина gulp-plumber
Для применения плагина
1
gulp-plumber
в проекте необходимо создать переменную
1
plumber
:
А затем дописать строку
1
.pipe(plumber())
в ту задачу, в которой необходимо включить возможность отслеживания ошибок. Например, пусть это будет задача минификации всех js-файлов проекта
1
uglify
. Тогда в ней сразу после строки
1
gulp.src('js/*.js')
добавляем строку
1
.pipe(plumber())
, чтобы отслеживались возможные ошибки во всех нижеследующих задачах, таких как
1
.pipe(uglify())
или
1
.pipe(gulp.dest('build/js'))
:
Точно также можно поступить, если необходим контроль ошибок в другой задаче, к примеру конкатенации CSS-файлов:
Запуск мониторинга ошибок gulp-plumber
Для удобства проверки работы плагина
1
gulp-plumber
создам задачу
1
gulp.watch
и помещу ее в задачу по умолчанию
1
default
:
Запускаю в консоли процесс мониторинга в Gulp командой:
… и смотрю на вывод в консоли:
Теперь намеренно вношу ошибку в файл
1
jquery-1.11.1.js
и снова перевожу взгзляд на консоль:
Отлично! Плагин
1
gulp-plumber
выполнил свою задачу - сформировал ясный и четкий отчет об ошибке. И при этом не прервал работу самого Gulp.
Возвратим все назад и исправим ошибку, допущенную ранее. Снова взглянем на консоль:
Плагин
1
gulp-plumber
снова справился со своей задачей - ошибка нами исправлена и он прилежно ее зафиксировал.
для отслеживания изменений в любом из файлов проекта.
Это очень удобно в работе, так как отпадает необходимость вручную запускать определенную задачу каждый раз, когда нужно зафиксировать эти изменения. В предыдущих статьях мы так и делали - запускали вручную на выполнение задачи по умолчанию или же определенную именованную задачу.
Сейчас давайте рассмотрим возможность запуска автоматического мониторинга в Gulp с помощью встроенной функции
1
gulp.watch
. Допустим, у нас имеются две именованные задачи, одна из которых выполняет минификацию js-файлов
1
gulp-uglify
, а вторая - конкатенацию css-файлов
1
gulp-concat
:
Нам нужно сделать так, чтобы Gulp запускал их каждый раз самостоятельно, когда мы внесем изменения в любой из js-файлов или css-файлов, а затем сохраним эти изменения.
Для этого создадим еще одну именованную задачу
1
watch
, цель которой - отслеживание изменений в указанных файлах. Создаем все как обычно (или - почти как обычно):
Создаем задачу по имени
1
watch
, а внутри тела функции поместим встроенную функцию
1
gulp.watch
. В качестве аргументов этой функции мы передаем ей два параметра.
Первый параметр - что и где Gulp должен отслеживать;
1
js/*.js
говорит о том, что необходимо отслеживать изменения всех файлов с расширением
1
.js
, помещенных в директории
1
js
.
Второй параметр - что должен делать Gulp, если обнаружит изменения в указанном месте. В данном случае мы говорим ему, что необходимо запустить задачу по имени
1
uglify
.
Как видим, имя задачи передается функции
1
gulp.watch
в виде массива; отсюда можно сделать вывод, что задач может быть не одна, а несколько - в виде последовательности.
Перейдем от слов к делу и запустим в консоли выполнение мониторинга с помощью функции
1
gulp.watch
. Команда для мониторинга в Gulp выглядит таким образом:
Видим, что задача по имени
1
watch
запустилась и вроде как закончилась (
1
Finished 'watch' after 7.06 ms
). Но на самом деле Gulp находиться в фоновом режиме и отслеживает изменения js-файлов.
Чтобы проверить это, отредактируем и сохраним js-файл (в моем случае это
1
jquery.js
):
Вау! Видим, что в консоли появились две строчки - это отработала задача
1
uglify
. То есть, Gulp “увидел”, что я внес изменение в файле
1
jquery.js
и мгновенно запустил задачу
1
uglify
, чтобы зафиксировать это изменение. Мониторинг с помощью функции
1
gulp.watch
работает!
Давайте немного усложним задачу и добавим мониторинг
1
gulp.watch
в директории
1
css
. При любом изменении файлов в этой папке должна запускаться задача
1
concat
:
Снова запустим Gulp для мониторинга изменений в проекте.
Кстати, а вы знаете, как останавливать Gulp, запущенный в фоновом режиме? Если нет, то это просто - в консоли Linux это выполняется сочетанием клавиш Ctrl+C.
Внесем и сохраним изменения в файле
1
normalize.css
, размещенном в директории
1
css
. Вернемся в консоль:
О! Видим, что
1
gulp.watch
“подхватил” изменение в файле
1
normalize.css
и запустил соответствующую этому изменению задачу
1
concat
. Отлично - все работает!
Мониторинг
1
gulp.watch
можно добавить в задачу по умолчанию (
1
default
). Давайте создадим такую конструкцию:
Теперь, если запустить задачу
1
default
в консоли, то увидим следующее:
Задачи запустились и выполнились именно в той последовательности, в какой они прописаны в массиве. Сперва выполнились две задачи на конкатенацию
1
concat
и минификацию
1
uglify
, а затем запустилась задача на мониторинг
1
watch
.
Gulp “повис” в фоновом режиме и отслеживает изменения с помощью функции
1
gulp.watch
в указанных директориях. Проверим это и внесем легкое изменение в любом из файлов (пусть это будут снова
1
normalize.css
и
1
jquery.js
):
Функция
1
gulp.watch
прилежно отследила оба эти изменения и запустила соотвествующие им задачи:
Отлично! Мы изучили вопрос создания задачи мониторинга в Gulp с помощью функции
В предыдущей статье “Gulp - установка и запуск плагина gulp-uglify”, где мы учились устанавливать и запускать плагины под Gulp, мы создавали задачу под этот плагин.
Сами не зная того, тогда мы создали именованную задачу (named task). Как вы помните из вводной статьи “Gulp - знакомство и первый запуск”, в этом менеджере имеется два типа задач - задача по умолчанию (default) и именованная задача (named task).
В этом разделе мы углубимся в вопрос задач в Gulp и рассмотрим детально, каким образом создается именованная задача (named task) или несколько именованных задач (named tasks), как можно объединять именованные задачи (named tasks) в последовательности, как можно вызывать выполнение одной задачи из другой задачи.
Создание named task в Gulp
В менеджере Gulp может существовать тысячи задач, каждая из которых нацелена на получение конкретного результата. Давайте создадим отдельную задачу для конкатенации файлов. Для этой цели существует плагин
1
gulp-concat
. На странице документации этого плагина описан процесс установки и настройки - gulp-concat.
Установим плагин
1
gulp-concat
в проект:
И создадим в файле
1
gulpfile.js
отдельную задачу для этого плагина:
… а также создадим отдельную переменную для этого плагина:
Кстати, если вы еще не задались вопросом, а что это за странные строки -
1
gulp.src
,
1
gulp.dest
,
1
gulp.task
, то могу вкратце сказать, что это встроенные функции Gulp, каждая из которых выполняет свою задачу.
Осталось запустить в консоли именованную задачу (named task)
1
concat
, которая произведет слияние в один файл всех файлов с расширением .css, расположенных в директории css:
Отлично - мы создали named task!
Создание последовательности named tasks в Gulp
В Gulp можно создавать последовательность задач, в которой выполнение всех задач будет производиться в том порядке, в котором они помещены в очередь. Для этого несколько отдельных именованных задач (named tasks) помещают внутрь задачи по умолчанию (default).
Вместо callback-функции разместим массив, состоящий из списка имен тех именованных задач (named tasks), которые мы хотим поместить в очередь. Фактически, в данном случае выполнение одной задачи будет производиться через вызов другой задачи.
Допустим, у нас имеются две именованные задачи (named tasks):
Поместим их в задачу по умолчанию:
Теперь в консоли достаточно запустить одну команду
1
gulp
на выполнение задачи по умолчанию (default). Тем самым мы запустим выполнение последовательности нескольких отдельных команд -
1
'concat', 'uglify'
:
В выводе консоли видим, что сначала запустилась задача
1
concat
и выполнилась за 7.17 миллисекунд, затем запустилась задача
1
uglify
и на ее выполнение ушло 2.64 милисекунды. И затем запустилась задача по умолчанию
под Gulp для компиляции файлов Sass в файлы формата CSS. Для разработчиков, которые пользуются препроцессором Sass данный плагин
1
gulp-ruby-sass
просто необходим.
Для компиляции Sass в CSS под Gulp имеется несколько плагинов. Например,
1
gulp-sass
или
1
gulp-ruby-sass
. Более стабильным плагином является
1
gulp-ruby-sass
. Вот его мы и установим.
Установка плагина gulp-ruby-sass
Команда установки уже стандартная для нас:
В директории
1
sass
заранее помещены мною два scss-файла
1
main.scss
и
1
style.scss
:
После этого создаю именованную задачу
1
sass
для плагина
1
gulp-ruby-sass
:
И запускаем задачу
1
sass
:
Оба файла скомпилированы
1
main.scss
и
1
style.scss
и помещены по пути
1
build/css
:
Взглянем на содержимое хотя бы одного из них (пускай это будет
1
main.css
), чтобы убедиться в том, что это уже CSS-файл, а не SCSS-файл:
Да, действительно, перед нами CSS-файл!
Добавление опций к плагину gulp-ruby-sass
До этого момента все плагины, которые мы устанавливали и настраивали в виде задач, были без опций. То есть, в потоке мы просто вызывали плагин через переменную и передавали ему данные для обработки. На этом работа плагина заканчивалась.
Однако внимательный читатель мог уже при первом знакостве с плагинами заметить, что в руководстве почти к каждому из них, помимо описания установки, есть раздел, посвященный опциям данного плагина. Другими словами, плагин может не просто обрабатывать данные, а обрабатывать так, как нам это нужно.
Что касается плагина
1
gulp-ruby-sass
, то данный плагин может производить компиляцию из Sass в CSS несколькими способами. Достаточно почитать раздел API к документации к нему - gulp-ruby-sass.
Мы же воспользуемся всего одной опцией из этого списка и сделаем так, чтобы результат компиляции был более сжатым. Для этого немного изменим созданную ранее задачу
1
sass
и добавим опцию
1
style: 'compressed'
к переменной
1
sass
:
Снова запустим задачу
1
sass
из консоли:
И взглянем на результат компиляции файла
1
main.scss
в файл
1
main.css
:
Отлично! Видим, что плагин
1
gulp-ruby-sass
действительно отработал с опцией
1
compressed
и произвел не просто компиляцию из SCSS в CSS, но и сжатие CSS-файла
1
main.css
- удалены все лишние пробелы и табуляция, выкинуты лишние точки с запятой, а все CSS-правила размещены в одну строку.
Объединение нескольких плагинов в одной задаче
До недавнего момента при работе в Gulp мы всегда поступали таким образом - “один плагин - одна задача”. Однако, Gulp гораздо гибче и мощнее, чем можно было бы подумать. В частности, в одной задаче можно объединить несколько ранее установленных плагинов именно благодаря поточности Gulp.
Чтобы было более понятно, разберем все вышесказанное на живом примере. Дополним задачу
1
sass
плагином конкатенации, чтобы “склеить” два результирующих файла
1
main.css
и
1
style.css
в один файл
1
compile.css
. Как вы уже догадались, для этой цели мы воспользуемся уже установленным ранее плагином
1
gulp-concat
.
Видоизменим задачу
1
sass
, добавив строку
1
.pipe(concat('compile.css'))
после строки с вызовом плагина
1
gulp-ruby-sass
:
Вновь запустим в консоли задачу
1
sass
:
Посмотрим содержимое по пути
1
build/css
:
Файл
1
compile.css
появился по указанному пути. Взглянем на его содержимое в редакторе Sublime Text:
Пример получился не совсем удачный, но, тем не менее, наглядный. Видим, чтобы оба плагина отработали. Была произведена компиляция, а затем “склейка” двух файлов в один.
Конечно, благодаря поточности в Gulp, в одну задачу можно добавлять не два плагина, а гораздо больше.
В предыдущей статье “Gulp - знакомство и первый запуск”” мы познакомились с установкой менеджера Gulp и запуском первой задачи под него. В этой статье мы перейдем к еще более интересному материалу, в котором узнаем, как устанавливать и запускать плагины под Gulp на примере одного из них - gulp-uglify.
Как я уже упоминал ранее, Gulp имеет модульную структуру. Под Gulp, несмотря на молодость проекта, уже написано достаточное количество плагинов. Конечно, оно не сравниться с огромной коллекцией таковых под мега-популярный Grunt, но для большинства случаев жизни уже сейчас их хватит.
Каждый из плагинов - это код, решающий только одну задачу. Например, один плагин умеет сжимать изображения, другой сжимает js-файлы, третий сжимает css-файлы; еще один умеет компилировать scss-файлы в css-файлы. И так далее - список можно продолжать и продолжать.
Становиться понятно, что для конкретной задачи нам нужно установить нужный плагин и создать задачу (task) в файле
1
gulpfile.js
. А затем запустить Gulp на выполнение этой задачи. Конечно, задач может быть не одна, а несколько. Все зависит о того, какие именно задачи нам необходимо выполнять.
Давайте рассмотрим процесс установки плагинов и настройки задач на примере одного из них -
1
gulp-uglify
. Данный плагин служит для минификации js-файлов - он удаляет пробелы, запятые, точки с запятой. В результате js-файл получается меньшим по размеру.
Все плагины под Gulp размещены по этому адресу - Gulp Plugins. В строке поиска нужно вводить имя искомого плагина, в результате получаем (или не получаем) страницу с описанием плагина и командой для его установки.
Устанавливаем gulp-uglify под Gulp
На странице плагина gulp-uglify описана команда установки этого плагина, которую мы повторим для себя, в своем проекте:
Опять таки, ключ
1
--save-dev
“говорит” менеджеру
1
npm
добавить плагин
1
gulp-uglify
в качестве зависимости в файл
1
package.json
:
Создаем задачу gulp-uglify под Gulp
Плагин
1
gulp-uglify
установлен и теперь самое время прописать в файле
1
gulpfile.js
именованную задачу (named task) под него. Надеюсь, уважаемый читатель помнит о двух типах задач под Gulp, описанных в предыдущей статье “Gulp - знакомство и первый запуск”.
Открываем файл
1
gulpfile.js
в редакторе кода (у меня это Sublime Text) и вносим туда следующие строки:
В принципе, можно и не вводить вышеприведенные строки вручную, а просто скопировать их со страницы описания плагина gulp-uglify. Они размещены в блоке с заголовком Usage.
Но это не главное. Важнее разобраться, что из себя представляет каждая из этих строк. Так вот, строка
1
uglify = require('gulp-uglify')
- это создание переменной с именем
1
uglify
, в которую помещается плагин
1
gulp-uglify
. Обратите внимание на синтаксис этой строки и ее табуляцию - оба аспекта важны и их несоблюдение приведет к тому, что Gulp не будет работать. По большому счету, можно написать и так -
1
var uglify = require('gulp-uglify');
, но предыдущая запись является более правильной.
Далее идут строки для новой именованной задачи для Gulp. Имя задачи задаем произвольно и пусть оно будет таким -
1
gulp-uglify
. В теле callback-функции пропишем директорию, содержимое которой Gulp должен отслеживать -
1
gulp.src('js/*.js')
. В данном случае указываем, что Gulp должен следить за изменениями всех файлов с расширением .js, расположенных внутри директории
1
js
.
Следующая строка
1
.pipe(uglify())
получает в виде потока содержимое директории
1
js
и обрабатывает его с помощью плагина
1
gulp-uglify
, помещенного внутрь переменной
1
uglify
. Результат обработки передается в виде потока в строку
1
.pipe(gulp.dest('build/js'))
, которая сохраняет его по пути
1
build/js
.
Вот мы и разобрали суть задачи в Gulp! Ведь ничего сложного, правда?!
Запускаем задачу gulp-uglify в Gulp
Переходим от слов к делу и запустим на выполнение только что созданную нами задачу
1
gulp-uglify
. Не забываем, что именованные задачи в Gulp запускаются с указанием их имени:
Вуаля! Видим (по аналогии с предыдушим опытом запуска дефолтной задачи), что именованная задача
1
gulp-uglify
успешно запустилась, выполнилась за 12 миллисекунд и также успешно завершилась. По идее, теперь по пути
1
build/js
у нас должен располагаться минифицированный js-файл (в моем случае это был
1
jquery-1.11.1.js
).
Посмотрим и видим, что так оно и есть, файлик
1
jquery-1.11.1.js
помещен туда, куда мы и прописывали:
А точно ли он минифицированный? Это легко проверить - открываем его в Sublime Text и наблюдаем такую картину:
Полезные плагины под Gulp
Мы успешно установили и запустили плагин под Gulp - можно в очередной раз поздравить себя! В данном случае это был плагин
1
gulp-uglify
для минификации js-файлов.
Однако, как можно догадаться, существует большое количество других полезных плагинов. Все они устанавливаются и настраиваются точно также, как и рассмотренный нами
1
gulp-uglify
.
Ниже я приведу примерный список наиболее полезных плагинов под Gulp, существующих на сегодняшний день:
1
gulp-minify-html
// минификация HTML-файлов
1
gulp-minify-css
// минификация CSS-файлов
1
gulp-csso
// еще один плагин минификации CSS-файлов
1
gulp-uglify
// минификация JS-файлов
1
gulp-sass
// компиляция SCSS-файлов в CSS-файлы
1
gulp-ruby-sass
// компиляции SCSS-файлов в CSS-файлы, более стабильный
1
gulp-concat
// конкатенация (соединение нескольких файлов в один файл)