Статьи

Как перейти на Gulp.js 4.0

Несмотря на конкуренцию со стороны webpack и Parcel , Gulp.js остается одним из самых популярных исполнителей задач JavaScript. Gulp.js настраивается с использованием кода, что делает его универсальным вариантом общего назначения. Наряду с обычным переносом, упаковкой и оперативной перезагрузкой, Gulp.js может анализировать базу данных, отображать статический сайт, выдавать коммит Git и публиковать сообщение Slack с помощью одной команды.

Чтобы познакомиться с Gulp, взгляните на следующее:

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 gulpfile.js несовместимы с файлами конфигурации, разработанными для версии 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 должны быть совместимы, и большинство конфигураций gulpfile.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) 

Это утомительно, но вы можете игнорировать все, кроме первой ссылки на gulpfile.js , которая показывает строку, где произошла ошибка (102 в этом примере).

К счастью, большинство этих ошибок вызвано однотипными проблемами. В следующих разделах в качестве примера используется учебный код по CSS-задачам . Код доступен на GitHub и предоставляет исходный файл Gulp.js 3 gulpfile.js и перенесенный эквивалент Gulp.js 4 .

Преобразование массивов задач в вызовы серии ()

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() и 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) // .other plugins .pipe(gulp.dest(cssConfig.build)); )); // remember the extra closing bracket! 

Асинхронное завершение

Gulp.js 3 разрешал синхронные функции, но они могли вносить ошибки, которые было трудно отлаживать. Рассмотрим задачи, которые не возвращают значение gulp 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 примет возвращенное обещание (которое поддерживается пакетом del ) :

 gulp.task('clean', () => { return del([ dir.build ]); }); // or use the simpler implicit return: // 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'], () => { // image changes gulp.watch(imgConfig.src, ['images']); // CSS changes gulp.watch(cssConfig.watch, ['css']); }); 

Их можно перенести в методы Gulp.js 4 series() и обратный вызов done() :

 gulp.task('default', gulp.series('css', 'server', (done) => { // image changes gulp.watch(imgConfig.src, gulp.series('images')); // CSS changes gulp.watch(cssConfig.watch, gulp.series('css')); done(); })); 

Бонусный совет: конвертируйте методы задач в модули ES6

Большинство конфигураций gulpfile.js будут работать в Gulp.js 4.0 после преобразования массивов задач в вызовы series() и выполнения сигналов асинхронных функций.

Хотя метод определения task() по-прежнему поддерживается, более новый шаблон exports модуля ES6 предлагает несколько преимуществ:

  1. Можно определить частные задачи, которые можно вызывать в gulpfile.js но не из команды gulpfile.js .
  2. Функции могут передаваться по ссылке, а не по имени строки, поэтому синтаксические ошибки могут быть выделены редакторами.
  3. На одну и ту же функцию можно ссылаться, используя любое количество имен задач.
  4. Проще определять сложные зависимости в series() и / или parallel() .

Возьмите следующие images Gulp.js 3 и задачи css :

 gulp.task('images', () => gulp.src(imgConfig.src) // .other plugins .pipe(gulp.dest(imgConfig.build)) ); gulp.task('css', ['images'], () => gulp.src(cssConfig.src) // .other plugins .pipe(gulp.dest(cssConfig.build)) ); 

Они могут быть преобразованы для использования шаблона модуля Gulp.js 4:

 function images() { return gulp.src(imgConfig.src) // .other plugins .pipe(gulp.dest(imgConfig.build)); } exports.images = images; exports.pics = images; function css() { return gulp.src(cssConfig.src) // .other plugins .pipe(gulp.dest(cssConfig.build)); } exports.css = gulp.series(images, css); exports.styles = exports.css; 

Примечание: операторы return должны быть добавлены, потому что функции ES6 arrow => с неявным возвратом были заменены на стандартные определения функций.

В этом примере Gulp.js 4:

  • либо gulp images либо gulp pics могут быть использованы для запуска задачи images()
  • либо gulp styles gulp css или gulp styles запускают images() а затем css() .

Задайте exports.default чтобы определить задачу по умолчанию, запускаемую при выполнении gulp из командной строки без выполнения конкретной задачи.

Глоток Боже

Пример задач CSS , который оптимизирует изображения, компилирует Sass, минимизирует CSS и обновляет изменения при внесении изменений, занял менее одного часа для преобразования. Изучите код на GitHub, чтобы увидеть:

Потребовалось некоторое время, чтобы (правильно) прибыть, но Gulp.js 4 предоставляет возможности для определения задач, которые были бы непрактичными в версии 3. Обновление программного обеспечения может показаться пустой тратой усилий по разработке, но вы будете вознаграждены быстрее, более надежный набор задач, который сэкономит время в долгосрочной перспективе.