SitePoint Premium предоставляет вам полную коллекцию книг, посвященных основам разработки, таким как Pug, Gulp, Git и другим. Присоединяйтесь сейчас .
Эта статья была обновлена в апреле 2019 года, чтобы отразить текущее состояние плагинов Gulp и Gulp.
Разработчики тратят очень мало времени на программирование. Даже если мы игнорируем раздражающие встречи, большая часть работы включает в себя основные задачи, которые могут подорвать ваш рабочий день:
- генерирование HTML из шаблонов и файлов содержимого
 - сжатие новых и модифицированных изображений
 - компиляция Sass в код CSS
 -  удаление 
consoleиdebuggerоператоров из скриптов - перенос ES6 в кросс-браузер-совместимый код ES5
 - кодирование и проверка
 - объединение и минимизация файлов CSS и JavaScript
 - Развертывание файлов на серверах разработки, подготовки и производства
 
Задачи должны повторяться каждый раз, когда вы вносите изменения. Вы можете начать с благих намерений, но самый непогрешимый разработчик забудет сжать изображение или два. Со временем задачи подготовки производства становятся все более трудными и трудоемкими; вы будете бояться неизбежного изменения контента и шаблонов. Это ошеломляющая, повторяющаяся работа. Было бы лучше потратить свое время на более прибыльную работу?
Если это так, вам нужен исполнитель задач или процесс сборки .
Это звучит страшно сложно!
Создание процесса сборки займет время. Это сложнее, чем выполнять каждую задачу вручную, но в долгосрочной перспективе вы сэкономите часы усилий, сократите человеческие ошибки и сохраните здравомыслие. Принять прагматичный подход:
- Сначала автоматизируйте самые неприятные задачи.
 - Постарайтесь не слишком усложнять процесс сборки; час или два более чем достаточно для первоначальной настройки.
 - Выберите программное обеспечение для запуска задач и придерживайтесь его некоторое время. Не переключайтесь на другой вариант по прихоти.
 
Некоторые из инструментов и концепций могут быть новыми для вас, но сделайте глубокий вдох и сосредоточьтесь на одном.
Бегущие по задачам: варианты
Инструменты сборки, такие как GNU Make , были доступны в течение десятилетий, но специфичные для веб-сайтов исполнители задач — явление относительно недавнее. Первым, кто достиг критической массы, был Grunt — исполнитель задач Node.js, который использовал плагины, настроенные (изначально) с помощью файла конфигурации JSON. Grunt был чрезвычайно успешным, но страдал от скорости и сложных проблем настройки. Многие проблемы были решены в более поздних выпусках, но Gulp уже прибыл и предложил ряд улучшений:
- Такие функции, как просмотр файлов были встроены.
 - Плагины Gulp были (в основном) просты и предназначены для единой работы.
 - Gulp использовал код конфигурации JavaScript, который был менее подробным, более простым для чтения, более простым для изменения и предоставлял большую гибкость.
 - Gulp был быстрее, потому что он использовал потоки Node.js для передачи данных через ряд плагинов. Файлы были написаны только в конце каждого задания.
 
С тех пор появилось несколько конкурирующих альтернатив:
- npm — опция для более простых проектов
 - Webpack и Parcel выросли в популярности. Это упаковщики модулей, которые понимают синтаксис JavaScript и могут выполнять простые задачи с минимальными настройками.
 
Тем не менее, Gulp по-прежнему обеспечивает гибкость и эффективность для привлечения трети веб-разработчиков . Если вы можете писать JavaScript, Gulp позволяет задачам общего назначения делать что угодно.
Gulp требует Node.js. Знание JavaScript полезно, но разработчики из всех верований веб-программирования найдут его полезным
Версии глотка
  Gulp.js 3.9.1 была версией по умолчанию много лет, и, хотя Gulp 4 был доступен, его нужно было явно установить с помощью npm install gulp@next .  Это было необходимо, потому что, хотя плагины остаются совместимыми, Gulp 4 использовал новый синтаксис конфигурации. 
  10 декабря 2018 года Gulp.js 4.0 был объявлен по умолчанию и опубликован в npm.  Любой, кто использует npm install gulp в новом проекте, получит версию 4. Это будет использоваться в этом руководстве. 
Шаг 1: Установите Node.js
Node.js можно загрузить для Windows, macOS и Linux с узла nodejs.org/download/ . Существуют различные варианты установки из бинарных файлов, менеджеров пакетов и образов докеров; полные инструкции доступны.
Примечание: Node.js и Gulp работают в Windows, но некоторые плагины могут работать некорректно, если они зависят от собственных двоичных файлов Linux. Одним из вариантов для пользователей Windows 10 является подсистема Windows для Linux ; это может решить проблемы, но может привести к появлению альтернативных проблем.
После установки откройте командную строку и введите следующее, чтобы узнать номер версии:
 node -v 
  Вы собираетесь активно использовать npm — менеджер пакетов Node.js, который используется для установки модулей.  Изучите его номер версии: 
 npm -v 
  Примечание. Модули Node.js можно устанавливать глобально, чтобы они были доступны во всей вашей системе.  Однако большинство пользователей не будут иметь права на запись в глобальные каталоги, если команды npm имеют префикса sudo .  Существует ряд опций для исправления разрешений npm, и могут помочь такие инструменты, как nvm, но вы также можете изменить каталог по умолчанию, например, на платформах на основе Ubuntu / Debian: 
 cd ~ mkdir .node_modules_global npm config set prefix=$HOME/.node_modules_global npm install npm -g 
  Затем добавьте следующую строку в конец ~/.bashrc : 
 export PATH="$HOME/.node_modules_global/bin:$PATH" 
Затем обновите с этим:
 source ~/.bashrc 
Шаг 2: Установите Gulp глобально
  Установите интерфейс командной строки Gulp глобально, чтобы команду gulp можно было запустить из любой папки проекта: 
 npm install gulp-cli -g 
Убедитесь, что Gulp установил следующее:
 gulp -v 
Шаг 3: Настройте свой проект
  Примечание. Этот шаг можно пропустить, если у вас уже есть файл конфигурации package.json . 
  Предположим, у вас есть новый или уже существующий проект в папке project1 .  Перейдите к этой папке и инициализируйте ее с помощью npm: 
 cd project1 npm init 
  Вам будет задан ряд вопросов: введите значение или нажмите « Return», чтобы принять значения по умолчанию.  Файл package.json котором хранятся ваши параметры конфигурации npm , будет создан по завершении. 
  Примечание. Node.js устанавливает модули в папку node_modules .  Вы должны добавить это в свой файл .gitignore чтобы убедиться, что они не .gitignore к вашему хранилищу.  При развертывании проекта в другой системе вы можете запустить npm install чтобы восстановить их. 
В оставшейся части этого руководства мы предположим, что папка вашего проекта содержит подпапки, перечисленные ниже.
  Папка src : предварительно обработанные исходные файлы 
Это содержит дополнительные подпапки:
-   
html— исходные файлы и шаблоны HTML -   
images— оригинальные несжатые изображения -   
js— несколько предварительно обработанных файлов скриптов -   
scss— несколько предварительно обработанных файлов Sass.scss 
  Папка build : скомпилированные / обработанные файлы 
Gulp создаст файлы и создаст подпапки по мере необходимости:
-   
html— скомпилированные статические файлы HTML -   
images— сжатые изображения -   
js— единственный объединенный и свернутый файл JavaScript -   
css— единственный скомпилированный и свернутый файл CSS 
Ваш проект почти наверняка будет другим, но эта структура используется для приведенных ниже примеров.
Примечание. Если вы работаете в системе на основе Unix и хотите просто следовать этому руководству, вы можете воссоздать структуру исходных папок с помощью следующей команды:
 mkdir -p src/{html,images,js,scss} 
Шаг 4: Установите Gulp локально
Теперь вы можете установить Gulp в папку вашего проекта с помощью этой команды:
 npm install gulp --save-dev 
  Это устанавливает Gulp как зависимость для разработки, и раздел "devDependencies" в package.json соответствующим образом обновляется.  Предположим, что Gulp и все плагины являются зависимостями для разработки до конца этого руководства. 
Альтернативные варианты развертывания
  Зависимости разработки не устанавливаются, если для переменной среды NODE_ENV задано значение production в вашей операционной системе.  Обычно вы делаете это на своем живом сервере с помощью команды macOS / Linux: 
 export NODE_ENV=production 
Или на Windows:
 set NODE_ENV=production 
  Это руководство предполагает, что ваши ресурсы будут скомпилированы в папку build и переданы в ваш репозиторий Git или загружены непосредственно на сервер.  Однако может быть предпочтительнее создавать ресурсы на работающем сервере, если вы хотите изменить способ их создания — например, файлы HTML, CSS и JavaScript минимизируются в рабочей среде, но не в средах разработки.  В этом случае удалите --save-dev при установке Gulp и его плагинов.  Например: 
 npm install gulp 
  Это устанавливает Gulp как зависимость приложения в разделе "dependencies" package.json .  Он будет установлен при вводе npm install и может быть запущен везде, где развернут проект.  Вы можете удалить папку build из своего хранилища, так как файлы могут быть созданы на любой платформе при необходимости. 
Шаг 4: Создайте файл конфигурации Gulp
  Создайте новый gulpfile.js конфигурации gulpfile.js в корневом каталоге вашего проекта.  Для начала добавим базовый код: 
 // Gulp.js configuration const // modules gulp = require('gulp'), // development mode? devBuild = (process.env.NODE_ENV !== 'production'), // folders src = 'src/', build = 'build/' ; 
  Это ссылается на модуль Gulp, устанавливает для переменной devBuild значение true при запуске в разработке (или в непроизводственном режиме) и определяет расположение исходных devBuild и папок сборки. 
Примечание. Код ES6 приведен в данном руководстве. Это будет работать в Node.js с версии 6.0 и выше.
  gulpfile.js пока ничего не сделает, потому что вам нужно выполнить следующий шаг, описанный ниже. 
Шаг 5: Создание задач Gulp
Сам Гулп ничего не делает. Вы должны:
- установить плагины Gulp и
 - написать задачи, которые используют эти плагины, чтобы сделать что-то полезное
 
Можно написать свои собственные плагины, но, поскольку доступно почти 3000, маловероятно, что вам когда-нибудь понадобится. Вы можете искать, используя собственный каталог Gulp по адресу gulpjs.com/plugins/ , на npmjs.com , или используя мощную мощь Google и ища «gulp что-то ».
Большинство задач будет использовать:
-   
gulp.src(folder)для создания потока из файлов в исходной папке, и -   
gulp.dest(folder)для вывода потока в виде файлов вgulp.dest(folder)сборки 
  Любое количество методов плагина может быть .pipe(plugin) с помощью .pipe(plugin) между .src и .dest . 
Задача изображения
  Лучше всего это продемонстрировать на примере, поэтому давайте создадим базовую задачу, которая сжимает изображения и копирует их в соответствующую папку build .  Поскольку этот процесс может занять некоторое время, мы будем сжимать только новые и измененные файлы.  Нам могут помочь два плагина: gulp-newer и gulp-imagemin .  Установите их из командной строки: 
 npm install gulp-newer gulp-imagemin --save-dev 
  Теперь мы можем ссылаться на оба модуля в верхней части gulpfile.js : 
 // Gulp.js configuration const // modules gulp = require('gulp'), newer = require('gulp-newer'), imagemin = require('gulp-imagemin'), 
  Теперь мы можем определить функцию обработки изображений в конце gulpfile.js : 
 // image processing function images() { const out = build + 'images/'; return gulp.src(src + 'images/**/*') .pipe(newer(out)) .pipe(imagemin({ optimizationLevel: 5 })) .pipe(gulp.dest(out)); }); exports.images = images; 
Все задачи синтаксически похожи. Этот код делает следующее:
-   Создает новую функцию задания с именем 
images. -   Он определяет 
outпапку, в которой будут находиться файлы сборки. -   Он читает поток файлов из папки 
src/images/source.**/*гарантирует, что изображения в подпапках также обрабатываются. -   Он передает все файлы в модуль 
gulp-newer. Исходные файлы, которые новее, чем соответствующие файлы назначения, передаются через. Все остальное убрано. -   Он 
gulp-imageminоставшиеся новые / измененные файлы черезgulp-imagemin, который устанавливает необязательный аргументgulp-imagemin. -   Он выводит сжатые изображения в папку Gulp 
dest/images/. -   Он экспортирует общедоступную задачу 
imagesкоторая вызывает функциюimages. 
  Сохраните gulpfile.js и поместите несколько изображений в папку src/images/ вашего проекта, прежде чем запускать задачу из командной строки: 
 gulp images 
Все изображения сжимаются соответственно, и вы увидите такой результат:
 Using file gulpfile.js Running 'imagemin'... Finished 'imagemin' in 5.71 ms gulp-imagemin: image1.png (saved 48.7 kB) gulp-imagemin: image2.jpg (saved 36.2 kB) gulp-imagemin: image3.svg (saved 12.8 kB) 
  Попробуйте снова запустить gulp images ;  файлы не обрабатываются, поскольку файлы изображений не были изменены. 
Задача HTML
Теперь мы можем создать аналогичную задачу, которая копирует файлы из исходной папки HTML. Мы можем безопасно минимизировать наш HTML-код, чтобы удалить ненужные пробелы и атрибуты, используя плагин gulp-htmlclean .
Плагин gulp-noop также будет установлен. Это не выполняет никаких операций, которые могут быть полезны для простых решений разработки / обработки:
 npm install gulp-htmlclean gulp-noop --save-dev 
  Эти модули загружаются вверху gulpfile.js : 
 const // modules gulp = require('gulp'), noop = require('gulp-noop'), newer = require('gulp-newer'), imagemin = require('gulp-imagemin'), htmlclean = require('gulp-htmlclean'), 
  Теперь мы можем экспортировать html функцию в конец gulpfile.js : 
 // HTML processing function html() { const out = build + 'html/'; return gulp.src(src + 'html/**/*') .pipe(newer(out)); .pipe(devBuild ? noop() : htmlclean()) .pipe(gulp.dest(out)); } exports.html = gulp.series(images, html); 
  Это повторно использует gulp-newer и вводит пару концепций: 
-   Мы только 
gulp-htmlcleanHTML черезgulp-htmlcleanеслиNODE_ENVустановлен наproduction. Следовательно, HTML остается несжатым во время разработки, что может быть полезно для отладки. -   Экспортированная задача 
htmlиспользуетgulp.series()для объединения задач, которые выполняются одна за другой. В этом случае функцияimages()запускается доhtml(), которая гарантирует, что файлы HTML могут ссылаться на изображения. 
  Сохраните gulpfile.js и запустите gulpfile.js gulp html из командной строки.  Будут выполняться задачи html и images . 
Задача JavaScript
Слишком легко для тебя? Давайте обработаем файлы JavaScript, построив базовый модуль сборки. Это будет:
-   Сначала убедитесь, что зависимости загружены с помощью плагина gulp-deporder .  Это анализирует комментарии в верхней части каждого скрипта, чтобы обеспечить правильное упорядочение, например 
// requires: defaults.js lib.js -   Объедините все файлы сценариев в один файл 
main.jsиспользуяmain.js-concat . -   Удалите все операторы 
consoleиdebuggingс помощью gulp-strip-debug при работе в производственном режиме. - Минимизируйте код с ES6-совместимым gulp-terser .
 - Добавлять исходную карту при работе в режиме разработки с gulp-sourcemaps .
 
Установите подключаемые модули:
 npm install gulp-deporder gulp-concat gulp-strip-debug gulp-terser gulp-sourcemaps --save-dev 
  Затем загрузите их в начало gulpfile.js : 
 const ... concat = require('gulp-concat'), deporder = require('gulp-deporder'), terser = require('gulp-terser'), stripdebug = devBuild ? null : require('gulp-strip-debug'), sourcemaps = devBuild ? require('gulp-sourcemaps') : null, 
  Примечание: модули gulp-sourcemaps gulp-strip-debug и gulp-sourcemaps загружаются только в режиме разработки для эффективности. 
  Затем экспортируйте новую функцию задачи js : 
 // JavaScript processing function js() { return gulp.src(src + 'js/**/*') .pipe(sourcemaps ? sourcemaps.init() : noop()) .pipe(deporder()) .pipe(concat('main.js')) .pipe(stripdebug ? stripdebug() : noop()) .pipe(terser()) .pipe(sourcemaps ? sourcemaps.write() : noop()) .pipe(gulp.dest(build + 'js/')); } exports.js = js; 
  Эта функция во многом аналогична другим задачам, но sourcemap.init() вызывается до преобразования кода, а sourcemaps.write() вызывается после их завершения. 
  Сохраните, добавьте несколько файлов JavaScript в папку src/js/ , затем запустите gulp js чтобы увидеть, как происходит волшебство! 
Задача CSS
  Наконец, давайте создадим задачу CSS, которая компилирует файлы Sass .scss в один файл .css с помощью gulp-sass .  Это плагин Gulp для node-sass , который привязывается к сверхбыстрому порту LibSass C / C ++ движка Sass .  Мы предполагаем, что ваш основной файл Sass scss/main.scss отвечает за загрузку всех партиалов. 
Наша задача также будет использовать потрясающий PostCSS через плагин gulp-postcss . PostCSS требует свой собственный набор плагинов, и мы установим эти:
-   postcss-assets для управления активами.  Это позволяет нам использовать такие свойства, как 
background: resolve('image.png');разрешить пути к файлам илиbackground: inline('image.png');встроить данные закодированных изображений. - автоматический префикс для автоматического добавления префиксов поставщиков в свойства CSS.
 - css-mqpacker для упаковки нескольких ссылок на один и тот же медиа-запрос CSS в одно правило.
 - cssnano для минимизации кода CSS при работе в производственном режиме.
 
Большинство из этих плагинов принимают параметры; обратитесь к их документации для получения дополнительной информации.
Наконец, исходная карта будет добавлена в файл CSS при запуске в режиме разработки с использованием gulp-sourcemaps еще раз.
Установите все модули:
 npm install gulp-sass gulp-postcss postcss-assets autoprefixer css-mqpacker cssnano --save-dev 
  Загрузите их в начало gulpfile.js : 
 const ... sass = require('gulp-sass'), postcss = require('gulp-postcss'), assets = require('postcss-assets'), autoprefixer = require('autoprefixer'), mqpacker = require('css-mqpacker'), cssnano = require('cssnano'), 
  Теперь мы можем экспортировать новую задачу css в конец gulpfile.js .  Обратите внимание, что задача images установлена как зависимость, потому что postcss-assets может ссылаться на изображения в процессе сборки: 
 // CSS processing function css() { return gulp.src(src + 'scss/main.scss') .pipe(sourcemaps ? sourcemaps.init() : noop()) .pipe(sass({ outputStyle: 'nested', imagePath: '/images/', precision: 3, errLogToConsole: true }).on('error', sass.logError)) .pipe(postcss([ assets({ loadPaths: ['images/'] }), autoprefixer({ browsers: ['last 2 versions', '> 2%'] }), mqpacker, cssnano ])) .pipe(sourcemaps ? sourcemaps.write() : noop()) .pipe(gulp.dest(build + 'css/')); } exports.css = gulp.series(images, css); 
  Обратите внимание, что .on('error', sass.logError) гарантирует, что Sass выводит синтаксические ошибки на консоль, не останавливая задачу Gulp. 
  Сохраните файл, добавьте соответствующие файлы Sass .scss и запустите задачу из командной строки: 
 gulp css 
Шаг 6: Автоматизируйте задачи
  Мы выполняли одну задачу за раз.  Мы можем запустить их все одной командой, экспортировав задачу build в gulpfile.js : 
 // run all tasks exports.build = gulp.parallel(exports.html, exports.css, exports.js); 
  Метод gulp.parallel() выполняет задачи одновременно.  Его можно комбинировать с gulp.series() для создания сложных цепочек зависимостей.  В этом примере exports.html , exports.css и exports.js запускаются параллельно, но каждая из них может иметь последовательности зависимостей, включая задачу с images . 
  Сохраните и введите gulp build в командной строке, чтобы выполнить все задачи. 
  Это слишком много тяжелой работы?  Gulp предлагает метод .watch() который может отслеживать исходные файлы и запускать соответствующую задачу при каждом изменении файла.  Он передает набор файлов / папок для мониторинга, любые параметры (здесь не используются) и функцию задачи для запуска (необязательно в gulp.series() и / или gulp.parallel() ). 
  Давайте экспортируем новую задачу watch в конец gulpfile.js : 
 // watch for file changes function watch(done) { // image changes gulp.watch(src + 'images/**/*', images); // html changes gulp.watch(src + 'html/**/*', html); // css changes gulp.watch(src + 'scss/**/*', css); // js changes gulp.watch(src + 'js/**/*', js); done(); } exports.watch = watch; 
  Гулп должен знать, когда функция задачи завершена .  Обычно это выполняется путем возврата потока Gulp, но при желании это может быть обещание JavaScript, источник событий, наблюдаемый, дочерний процесс или обратный вызов.  Здесь мы используем колбэк с именем done() чтобы указать, что все задачи watch() были настроены. 
  Вместо немедленного запуска gulp watch давайте добавим задачу по умолчанию, которую можно выполнить, запустив gulp без дополнительных аргументов: 
 // default task exports.default = gulp.series(exports.build, exports.watch); 
  Сохраните gulpfile.js и введите gulpfile.js в командной строке.  Ваши изображения, HTML, CSS и JavaScript будут обработаны, затем Gulp будет продолжать следить за обновлениями и при необходимости повторять выполнение задач.  Нажмите Ctrl / Cmd + C, чтобы прервать мониторинг и вернуться в командную строку. 
Шаг 7: Прибыль!
Другие плагины, которые вы можете найти полезными:
- gulp-load-plugins : загрузить все модули плагинов Gulp без обязательных объявлений
 - gulp-preprocess : простой препроцесс HTML и JavaScript
 - или без глотка : плагин препроцессора Less CSS
 - gulp-stylus : плагин препроцессора Stylus CSS
 - gulp-size : отображает размеры файлов и экономию
 - gulp-nodemon : использует nodemon для автоматического перезапуска приложений Node.js при возникновении изменений
 
Задачи Gulp могут запускать любой код JavaScript или модули Node.js. Они не обязательно должны быть плагинами — например:
- синхронизация браузера : автоматически перезагружать ресурсы или обновлять ваш браузер, когда происходят изменения
 -   del : удалить файлы и папки (возможно, очищать папку 
buildв начале каждого запуска) 
Потратьте немного времени и Gulp может сэкономить много часов разочарований в разработке. Преимущества:
- плагины в изобилии
 - конфигурация с использованием трубок легко читаема и понятна
 -   
gulpfile.jsможно адаптировать и использовать в других проектах - Ваш общий вес страницы может быть уменьшен для повышения производительности
 - Вы можете упростить ваше развертывание
 -   
gulpfile.js— это весело (ну, интереснее, чем конфигурации JSON, используемые другими исполнителями задач) 
Полезные ссылки:
Применение описанных выше процессов к простому веб-сайту уменьшило общий вес более чем на 50% и более. Вы можете проверить свои результаты, используя инструменты анализа веса страницы .
Gulp продолжает оставаться отличным вариантом для автоматического запуска задач и может революционизировать ваш рабочий процесс. Я надеюсь, что вы нашли это руководство полезным и считаете, что Gulp подходит для вашего производственного процесса.