От автора: сегодняшняя статья посвящена Gulp 4, изменения в котором могут поначалу озадачить разработчиков. Несмотря на конкуренцию со стороны webpack и Parcel, Gulp.js остается одним из самых популярных исполнителей задач JavaScript. Gulp.js настраивается с использованием кода, что делает его универсальным вариантом общего назначения. Наряду с обычным переносом, упаковкой и интерактивной перезагрузкой, Gulp.js может анализировать базу данных, отображать статический сайт, выдавать коммиты Git и публиковать сообщение Slack с помощью одной команды.
Gulp.js 4.0
Gulp.js 3.x используется по умолчанию около десяти лет. До недавнего времени команда npm install gulp устанавливала версию 3.9.1 — версию, которая рассматривалась в предыдущем руководстве.
Gulp.js 4.0 был доступен в течение всего этого времени, но его нужно было явно установить с помощью npm install gulp@next. Отчасти это было связано с продолжающейся разработкой и тем, что файлы конфигурации Gulp.js 4 не совместимы с файлами, разработанными для версии 3.
10 декабря 2018 года Gulp.js 4.0 был объявлен версией по умолчанию и опубликован в npm. Любой, кто использует npm install gulp для нового проекта, получит версию 4.
Необходимо ли переходить на Gulp.js 4?
Нет. Gulp.js 3 устарел и вряд ли получит дальнейшие обновления, но его все еще можно использовать. Существующие проекты не будут обновляться, если версия явно не изменена в разделе dependencies файла package.json. Например:
"dependencies": { "gulp": "^4.0.0" }
Вы также можете установить Gulp.js 3 в новых проектах, используя:
npm install gulp@^3.9.1
Возможно, лучше придерживаться Gulp.js 3.x, если у вас очень сложная, критически важная система сборки. Однако существующие плагины Gulp.js должны быть совместимы, и большинство конфигураций можно перенести за час или два. Обновление в тоже время имеет ряд важных преимуществ, которые мы рассмотрим в этой статье.
Обновление до Gulp.js 4.0
Обновите зависимости package.json, как показано выше, затем запустите npm install. Вы также можете обновить интерфейс командной строки с помощью npm i gulp-cli-g. Чтобы проверить установку, введите в командной строке :gulp -v:
$ gulp -v [15:15:04] CLI version 2.0.1 [15:15:04] Local version 4.0.0
Миграция gulpfile.js
Выполнение любой задачи теперь может вызывать пугающие ошибки. Например:
AssertionError [ERR_ASSERTION]: Task function must be specified at Gulp.set [as _setTask] (/node_modules/undertaker/lib/set-task.js:10:3) at Gulp.task (/node_modules/undertaker/lib/task.js:13:8) at /gulpfile.js:102:8 at Object.<anonymous> (/gulpfile.js:146:3) at Module._compile (internal/modules/cjs/loader.js:688:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10) at Module.load (internal/modules/cjs/loader.js:598:32) at tryModuleLoad (internal/modules/cjs/loader.js:537:12) at Function.Module._load (internal/modules/cjs/loader.js:529:3) at Module.require (internal/modules/cjs/loader.js:636:17) at require (internal/modules/cjs/helpers.js:20:18) at execute (/gulp-cli/lib/versioned/^4.0.0/index.js:36:18) at Liftoff.handleArguments (/gulp-cli/index.js:175:63) at Liftoff.execute (/gulp-cli/node_modules/liftoff/index.js:203:12) at module.exports (/gulp-cli/node_modules/flagged-respawn/index.js:51:3) at Liftoff.<anonymous> (/gulp-cli/node_modules/liftoff/index.js:195:5)
Это неприятно, но вы можете игнорировать все, кроме первой ссылки, которая показывает строку, где произошла ошибка (в этом примере — 102).
К счастью, большинство из этих ошибок вызваны тем же типом проблемы. В следующих разделах в качестве примера используется код из руководства по задачам CSS. Код доступен на GitHub и предоставляет оригинальный Gulp.js 3 gulpfile.js и перенесенный эквивалент Gulp.js 4.
Преобразование массивов задач в вызовы series()
Gulp.js 3 позволял указывать массивы синхронных задач. Это обычно использовалось, когда вызывалось событие watch или у задачи были зависимости. Например, запустите задачу images перед задачей css:
gulp.task('css', ['images'], () => gulp.src(cssConfig.src) // .other plugins .pipe(gulp.dest(cssConfig.build)); );
Gulp.js 4.0 представляет методы series() and parallel() для объединения задач:
series(…) запускает задачи по одной в указанном порядке, а
parallel(…) выполняет задачи одновременно в любом порядке.
Сложные задачи могут быть вложены в любой уровень, чего было бы трудно достичь в Gulp.js 3. Например, запускать задачи a и b параллельно, а, когда обе завершены, запускать параллельно задачи c и d:
gulp.series( gulp.parallel(a, b), gulp.parallel(c, d) )
Приведенную выше задачу css можно перенести в Gulp.js 4, изменив массив на вызов метода series():
gulp.task('css', gulp.series('images', () => gulp.src(cssConfig.src) // другие плагины .pipe(gulp.dest(cssConfig.build)); )); // не забывайте о дополнительном закрытии скобки!
Асинхронное завершение
Gulp.js 3 разрешал синхронные функции, но они могли вносить ошибки, которые было трудно отлаживать. Рассмотрим задачи, которые не возвращают потоковое значение gulp. Например, задача clean удаляет папку build:
const gulp = require('gulp'), del = require('del'), dir = { src : 'src/', build : 'build/' }; gulp.task('clean', () => { del([ dir.build ]); });
Gulp.js 4.0 выдает предупреждение, потому что ему нужно знать, когда задача завершена, чтобы управлять последовательностями series() и parallel():
[15:57:27] Using gulpfile gulpfile.js [15:57:27] Starting 'clean'... [15:57:27] The following tasks did not complete: clean [15:57:27] Did you forget to signal async completion?
Чтобы решить эту проблему, Gulp.js 4 принимает возвращаемый Promise (который поддерживается пакетом del):
gulp.task('clean', () => { return del([ dir.build ]); }); // или используем более простое явное возвращение: // gulp.task('clean', () => del([ dir.build ]) );
В качестве альтернативы, вы можете передать функцию обратного вызова, которая выполняется по завершении ( del также предоставляет синхронный метод sync()):
gulp.task('clean', (done) => { del.sync([ dir.build ]); done(); });
Вот более сложный пример Gulp.js 3 с задачами наблюдения:
gulp.task('default', ['css', 'server'], () => { // изменение изображений gulp.watch(imgConfig.src, ['images']); // изменение CSS gulp.watch(cssConfig.watch, ['css']); });
Они могут быть перенесены в метод Gulp.js 4 series() и обратный вызов done():
gulp.task('default', gulp.series('css', 'server', (done) => { // изменение изображений gulp.watch(imgConfig.src, gulp.series('images')); // изменение CSS gulp.watch(cssConfig.watch, gulp.series('css')); done(); }));
Дополнительный совет: преобразование методов задач в модули ES6
Большинство конфигураций будет работать в Gulp.js 4.0 после преобразования массивов задач в вызовы series() и завершения сигналов асинхронных функций.
Хотя метод определения task() все еще поддерживается, новый шаблон модуля ES6 exports предлагает несколько преимуществ:
Можно определить частные задачи, которые можно вызывать внутри gulpfile.js, но не из команды gulp.
Функции могут передаваться по ссылке, а не по имени строки, поэтому синтаксические ошибки могут быть выделены редакторами.
На одну и ту же функцию можно ссылаться, используя любое количество имен задач.
Проще определить сложные зависимости в series() и / или parallel().
Рассмотрим следующие задачи Gulp.js 3 images и css:
gulp.task('images', () => gulp.src(imgConfig.src) // другие плагины .pipe(gulp.dest(imgConfig.build)) ); gulp.task('css', ['images'], () => gulp.src(cssConfig.src) // другие плагины .pipe(gulp.dest(cssConfig.build)) );
Они могут быть преобразованы для использования шаблона модуля Gulp.js 4:
function images() { return gulp.src(imgConfig.src) // другие плагины .pipe(gulp.dest(imgConfig.build)); } exports.images = images; exports.pics = images; function css() { return gulp.src(cssConfig.src) // другие плагины .pipe(gulp.dest(cssConfig.build)); } exports.css = gulp.series(images, css); exports.styles = exports.css;
Примечание: операторы return должны быть добавлены, потому что функции стрелок ES6 => с неявным возвратом были заменены на определения стандартных функций. В этом примере Gulp.js 4:
для выполнения задачи images() могут быть использованы либо gulp images, либо gulp pics
либо gulp images, либо gulp pics будет запускать images() следом за css()
Задайте exports.default для определения задачи по умолчанию, запускаемой при выполнении gulp из командной строки без конкретной задачи.
Потребовалось некоторое время, чтобы (правильно) все выстроить, но Gulp.js 4 предоставляет возможности для определения задач, которые были бы недостижимы в версии 3. Обновление программного обеспечения может показаться пустой тратой усилий по разработке, но вы будете вознаграждены большей скоростью, более надежным набором задач, что сэкономит вам время в долгосрочной перспективе.
Автор: Craig Buckler
Источник: https://www.sitepoint.com/
Редакция: Команда webformyself.