Gulp: базовая практическая часть по созданию своего сборщика проектов

Дневник разработчика

Основные методы gulp

  • Src – содержит путь к файлу.
  • Dest – содержит путь для сохранения файла
  • Series – последовательное выполнение задач
  • Parallel – параллельное выполнение задач (одновременный запуск выполнения задач)
  • Watch
  • Task -создаёт задачу. При описании метода передаём ДВА аргумента: имя задачи и функция, которая будет происходить при выполнении задачи.

series и parallel: порядок выполнения задач в gulp

При программировании задач в gulp важно учитывать возможности. Обратите внимание на то, в каком порядке они могут выполняться – последовательно или параллельно.

  • Series – последовательное выполнение задач
  • Parallel – параллельное выполнение задач (одновременный запуск выполнения задач)

При последовательном методе сборщик не приступит к выполнению следующей задачи, до тех пор, пока не завершится текущая запущенная ранее задача.

При параллельном методе – задачи запускаются одновременно, не дожидаясь завершения других.

gulp.task('default', gulp.series('first', 'second', 'third'));
gulp.task('default', gulp.parallel('first', 'second', 'third'));

При программировании задач в сборщике обычно все задачи собираются в дефолтный таск, который именуется «default» и запускается по средствам стандартной команды «gulp».

В нём описывают все используемые при сборке задачи в той последовательности, которая необходима в ходе разработки проекта.

Gulp: базовая практическая часть по созданию своего сборщика проектов

src и dest: методы копирования файлов при сборке проекта

  • Src – содержит путь к файлу.
  • Dest – содержит путь для сохранения файла

Для начала внутри нашего проекта нужно создать отдельную папку, в которой мы будем хранить исходные файлы проекта. Чаще всего её называют source или src

Затем требуется написать программу копирования файлов из папки с исходниками в финальую папку. Финальную папку чаще всего называют build.

Программа копирования использует методы src и dest:

gulp.task('copy', function () {
  return gulp
    .src('./src/index.html')
    .pipe(gulp.dest('./build/'))
})

Давайте проверим работает ли.

В папку с исходниками загружаем простой файл index.html

В gulpfile.js в нашем таске/программе

Обращаемся в gulp и вызываем метод task/ Передаем аргументы – название нашего таска и функцию с описанием действий программы.

gulp.task('copy', function () {})

Обращаю ваше внимание что в тасках мы не используем оператор return, который возвращает программе результат работы функции. В нашем случае это DONE – функция успешно завершила свою работу.

gulp.task('copy-one', function () {
  return
})

После return обращаемся к gulp и указываем методы, которые нужно применить для выполнения задачи/таска:

Нужно взять исходный файл: .src('./src/index.html')

И скопировать его в итоговую папку проекта. Так как мы пока что не модифицируем файл, а просто пересохраняем так как есть, то и команда будет простой: .pipe(gulp.dest('./build/'))

В итоге получается вот такой таск:

gulp.task('copy-one', function () {
  return gulp
    .src('./src/index.html')
    .pipe(gulp.dest('./build/'))
})

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

whatch: метод слежения за изменениями в файлах проекта

Для слежения за файлами проекта используется метод whatch

Конструкция таска выглядит следующим образом:

gulp.watch('./src/index.html', function (callback) {
  console.log('АХТУНГ, мой ФЮРЕР! отслеживаемый файл был изменён!');
  callback();

})

Обращаемся к gulp

Указываем нужный нам метод whatch

Методу передаем два аргумента/параметра:

  1. Строка с адресом к исходному файлу, за которым нужна слежка (можно не только один файл указать, а целую папку. Но при этом потребуется уточнить какие расширения у файлов должны быть.)

2. Второй аргумент – что мы должны сделать, если файл изменился – что произойдёт если файл изменился. В нашем случае мы просто выводим сообщение в консоль.

Не забываем прописать функцию callback, что бы таск не выдавал ошибку при запуске.

При запуске таска вы увидите, что gulp начал следить за указанным в таске файлом и при каждом изменении этого файла в консоли отображается сообщение, которое мы запрограммировали.

Gulp: базовая практическая часть по созданию своего сборщика проектов

Обратите внимание, что после вывода завершения таск не прекратил свою работу и продолжил слежку за файлом. Это логично и правильно.

Если же вы решили прекратить слежение за файлом (ну, к примеру для того, чтобы переписать таск или просто перезагрузить сборщик) – необходимо завершить работу таска, нажав комбинацию клавиш CTRL+С

В примере результатов работы таска в консоли вы видите упоминание анонимной функции. Это происходит, потому что обычно в работе таска используются дополнительные параметры, которые говорят программе что делать при изменении файла, а у нас с вами просто вывод сообщения в консоль. Только поэтому наша функция обозначается в консоли как анонимная.

Итак, мы разобрались с простым примером, теперь давайте добавим функциональности в наш таск. Самым логичным действием при изменении файла-исходника будет – пересохранение этого файла в финальной папке проекта. В этом нам поможет метод последовательного или параллельного выполнения задач:

gulp.task('copy', function () {
  return gulp
    .src('./src/index.html')
    .pipe(gulp.dest('./build/'))
})

gulp.watch('./src/index.html', gulp.series('copy'))

В консоли видим, что файл успешно отслеживается нашим сборщиком и пересохраняется.

Gulp: базовая практическая часть по созданию своего сборщика проектов

Маски в путях к файлам и опции исключения файлов

С одним файликом все просто и понятно, но как нам быть, если у нас в проекте 10 и более файлов, и за всеми нужно следить. В таком случае нам придётся писать много таков. А процесс сборки будет сложным и запутанным? Нет, всё гораздо проще. В этом нам помогут маски в путях к исходным файлам, за которыми требуется слежка.

Конструкция таска выглядит вот так:

/* Первый вариант использования маски в путях  */
gulp.task('copy', function () {
  return gulp
    .src('./src/*.html')
    .pipe(gulp.dest('./build/'))
})

gulp.watch('./src/*.html', gulp.series('copy'))


/* Второй вариант использования маски в путях  */
gulp.task('copy', function () {
  return gulp
    .src('./src/**/.*.html')
    .pipe(gulp.dest('./build/'))
})

gulp.watch('./src/**.*.html', gulp.series('copy'))

в первом варианте мы указываем таску, что нужно следить за всеми файлами, которые находятся в корне папки SRC и имеют расширение .html

Во втором варианте мы задаем более глобальные параметры и указываем для отслеживания все файлы с расширением .html. Даже те, которые будут расположены в подпапках.

Gulp: базовая практическая часть по созданию своего сборщика проектов

При этом файлы с другими расширениями (другие типы файлов) не будут копироваться и отслеживаться, потому что мы их не указали в нашем таске.

Важно понимать, что при написании таска для отслеживания изменений в файлах следует руководствоваться логикой и здравым смыслом. Не нужно следить за всеми файлами проекта и всякий раз при изменении какого-то файла пересохранять проект целиком.

К подобным задачам подходите точечно. Не следите за теми файлами, которые не меняются.

Не пишите глобальные маски путей типа gulp.watch(‘./src/**.*’, gulp.series(‘copy’))

Этим вы лишь загрузите ваш сборщик и будете терять время всякий раз при изменении исходников.

Следите только за теми файлами, которые активно изменяются в проекте, пересохраняйте только те файлы, которые реально меняются, разделяя таски на отдельные группы.

  • Таск для слежения и пересохранения css файлов
  • Таск для слежения и пересохранения файлов js
  • и т п

При таком точечном подходе ваш таск будет работать оптимально быстро.

Как же работать точечно? Давайте разбираться вместе.

Как запрограммировать слежение за определёнными файлами или исключить ненужные — при помощи массива и восклицательного знака.

gulp.task('copy', function () {
  return gulp
    .src(['./src/contacts.html', './src/catalog.html'])
    .pipe(gulp.dest('./build/'))
}) 

// передача списка файлов для отслеживания изменений в виде массива
gulp.watch(['./src/contacts.html', './src/catalog.html'], gulp.series('copy'))

Передача файлов в виде массива с исключением выбранного файла или папки

Для этого используется восклицательный знак в начале строки у элемента массива.

знак инверсии ! вернет противоположное значение этой переменной. Мы как бы говорим, что этот файл не нужно трогать.

// передача массива с одним исключённым файлом
gulp.task('copy', function () {
  return gulp
    .src(['./src/*.html', '!./src/catalog.html'])
    .pipe(gulp.dest('./build/'))
})

// отслеживание изменений массива с одним исключённым файлом
gulp.watch(['./src/**/*.html', '!./src/catalog.html'], gulp.series('copy'))
Gulp: базовая практическая часть по созданию своего сборщика проектов

В правилах исключения файлов можно использовать маски путей, добавляя с их помощью целые папки в исключения.

Юрий Ронин