Статьи

Введение в Gulp.js

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 уже прибыл и предложил ряд улучшений:

  1. Такие функции, как просмотр файлов были встроены.
  2. Плагины Gulp были (в основном) просты и предназначены для единой работы.
  3. Gulp использовал код конфигурации JavaScript, который был менее подробным, более простым для чтения, более простым для изменения и предоставлял большую гибкость.
  4. Gulp был быстрее, потому что он использовал потоки Node.js для передачи данных через ряд плагинов. Файлы были написаны только в конце каждого задания.

С тех пор появилось несколько конкурирующих альтернатив:

Тем не менее, 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

Сам Гулп ничего не делает. Вы должны:

  1. установить плагины Gulp и
  2. написать задачи, которые используют эти плагины, чтобы сделать что-то полезное

Можно написать свои собственные плагины, но, поскольку доступно почти 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; 

Все задачи синтаксически похожи. Этот код делает следующее:

  1. Создает новую функцию задания с именем images .
  2. Он определяет out папку, в которой будут находиться файлы сборки.
  3. Он читает поток файлов из папки src/images/ source. **/* гарантирует, что изображения в подпапках также обрабатываются.
  4. Он передает все файлы в модуль gulp-newer . Исходные файлы, которые новее, чем соответствующие файлы назначения, передаются через. Все остальное убрано.
  5. Он gulp-imagemin оставшиеся новые / измененные файлы через gulp-imagemin , который устанавливает необязательный аргумент gulp-imagemin .
  6. Он выводит сжатые изображения в папку Gulp dest/images/ .
  7. Он экспортирует общедоступную задачу 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 и вводит пару концепций:

  1. Мы только gulp-htmlclean HTML через gulp-htmlclean если NODE_ENV установлен на production . Следовательно, HTML остается несжатым во время разработки, что может быть полезно для отладки.
  2. Экспортированная задача html использует gulp.series() для объединения задач, которые выполняются одна за другой. В этом случае функция images() запускается до html() , которая гарантирует, что файлы HTML могут ссылаться на изображения.

Сохраните gulpfile.js и запустите gulpfile.js gulp html из командной строки. Будут выполняться задачи html и images .

Задача JavaScript

Слишком легко для тебя? Давайте обработаем файлы JavaScript, построив базовый модуль сборки. Это будет:

  1. Сначала убедитесь, что зависимости загружены с помощью плагина gulp-deporder . Это анализирует комментарии в верхней части каждого скрипта, чтобы обеспечить правильное упорядочение, например // requires: defaults.js lib.js
  2. Объедините все файлы сценариев в один файл main.js используя main.js -concat .
  3. Удалите все операторы console и debugging с помощью gulp-strip-debug при работе в производственном режиме.
  4. Минимизируйте код с ES6-совместимым gulp-terser .
  5. Добавлять исходную карту при работе в режиме разработки с 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 могут запускать любой код JavaScript или модули Node.js. Они не обязательно должны быть плагинами — например:

  • синхронизация браузера : автоматически перезагружать ресурсы или обновлять ваш браузер, когда происходят изменения
  • del : удалить файлы и папки (возможно, очищать папку build в начале каждого запуска)

Потратьте немного времени и Gulp может сэкономить много часов разочарований в разработке. Преимущества:

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

Полезные ссылки:

Применение описанных выше процессов к простому веб-сайту уменьшило общий вес более чем на 50% и более. Вы можете проверить свои результаты, используя инструменты анализа веса страницы .

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