Слежение за файлами

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

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

Для начала, вот моя текущая структура папок:

  • Build/
    • index.html
    • package.json
    • gulpfile.js
    • node_modules/
      • gulp/
      • gulp-minify-css/
    • main.css

Установка необходимых пакетов

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

npm install --save-dev gulp-notify
npm install --save-dev gulp-sass

Добавление задачи watch и автоматизация системы

Gulp предлагает объект с именем watch, который похож на объекты src и dest. Мы можем использовать объект watch и попросить Gulp следить за данной задачей. Это означает, что Gulp будет следить за файлом на случай его модификации.

Добавьте следующий код в ваш gulpfile.js чтобы начать слежение за файлом main.css:

gulp.watch('main.css', function(){
  console.log('seen');
});

Окончательно gulpfile.js должен выглядеть следующим образом:

var gulp = require('gulp');
var minifyCss = require('gulp-minify-css');

gulp.task('mincss', function(){
  return gulp.src('main.css')
    .pipe(minifyCss())
    .pipe(gulp.dest('main'));
});
gulp.watch('main.css', function(){
  console.log('seen');
});

Теперь перейдите к командной строке и запустите gulp mincss снова. Если всё произошло ожидаемо, то вы должны увидеть сообщение «seen», как на картинке ниже:

Объект watch по-прежнему будет следить за какими-либо изменениями сделанными в файле main.css и отображать «seen» каждый раз, пока вы не нажмёте Ctrl + C для его остановки. Круто!

Функция watch принимает два аргумента: файл(ы) для слежения и вызов для действия. Второй аргумент может быть замыканием (анонимной функцией) или объектом JavaScript.

Обратите внимание, что за раз мы можем добавить несколько задач в файл gulpfile.js. У нас может быть задача script для управления JavaScript-файлами, задача connectPHP для запуска сервера PHP и т. д. Это может усложнить управление отслеживанием. Допустим, у нас есть три файла для слежения, мы должны написать:

gulp.watch(['file1.css', 'file2.txt', 'file3.js'], function(){
  console.log('seen');
});

Это прекрасно будет работать, но у меня лично есть две основные проблемы с такой практикой. Во-первых, это выглядит грязно. Я должен писать полное имя файла. Во-вторых, отображается одно сообщение («seen») каждый раз, когда меняется любой файл, в то время как я хотел бы знать, когда менялся конкретный файл.

Лучший способ справиться с грязной частью — это создание объекта paths, вроде следующего:

var paths = {
  css:['path/to/style1.css', 'path/to/style2.css'],
  script:['path/to/script1.js', 'path/to/script2.js']
};

gulp.watch(paths.css, function(){
  console.log('seen css changes');
});
gulp.watch(paths.script, function(){
  console.log('seen javascript changes');
});

Это выглядит хорошо и даёт нам возможность узнать, когда изменился CSS или JavaScript.

Другой мощной штукой для уведомлений является второй аргумент. Поскольку мы можем использовать замыкание в качестве аргумента, представьте как мы передаём целую задачу. Так что у нас есть что-то вроде такого:

gulp.watch(paths.css, ['mincss']);

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

var gulp = require('gulp');
var minifyCss = require('gulp-minify-css');
var paths = {
  css:['main.css'],
  text:['test.txt']
};

gulp.task('mincss', function(){
  return gulp.src('main.css')
    .pipe(minifyCss())
   .pipe(gulp.dest('main'));
});

gulp.watch(paths.css, ['mincss']);

Пока это всё прекрасно, но представьте что у нас есть несколько задач для отслеживания. Как мы запустим их из командной строки? Допустим, следующий случай:

var gulp = require('gulp');
var minifyCss = require('gulp-minify-css');
var coffee = require('gulp-coffee');
var paths = {
  css:['main.css'],
  script:['script.coffee']
};

gulp.task('mincss', function(){
  return gulp.src('main.css')
    .pipe(minifyCss())
    .pipe(gulp.dest('main'));
});

gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'));
});

gulp.watch(paths.css, ['mincss']);
gulp.watch(paths.script, ['scripts']);

При запуске gulp mincss будут отслеживаться файлы CSS и CoffeeScript. Но при изменении CoffeeScript-файла он не будет отслеживаться, только файл CSS. В том смысле, что отслеживание произойдёт только когда вы измените свой CSS-файл. То же самое происходит, когда вы решите отслеживать задачу scripts. Хотя это может быть иногда полезно с точки зрения экономии ресурсов.

Для преуменьшения проблемы мы должны собрать все задачи в одну, которая вызывается один раз и отслеживает все наши задачи единовременно:

var gulp = require('gulp');
var minifyCss = require('gulp-minify-css');
var coffee = require('gulp-coffee');
var paths = {
  css:['main.css'],
  script:['script.coffee']
};


gulp.task('mincss', function(){
  return gulp.src('main.css')
    .pipe(minifyCss())
    .pipe(gulp.dest('main'));
});

gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'));
});

  gulp.task('watcher',function(){
    gulp.watch(paths.css, ['mincss']);
    gulp.watch(paths.script, ['scripts']);
});

Теперь всё что вам нужно сделать это запустить gulp watcher и все ваши файлы будут отслеживаться одновременно. Любой файл, который вы измените будет компилирован.

Существует ещё один способ как сделать всё проще. Вместо запуска gulp watcher вы можете просто запустить gulp и он сделает всю работу. Но прямо сейчас в нашем случае если вы введёте gulp вы получите такую ошибку:

[11:08:34] Task 'default' is not in your gulpfile
[11:08:34] Please check the documentation for proper gulpfile formatting

Gulp просит нас создать ещё одну задачу с именем default, которая необходима для работы.

Итак, что насчёт задачи default? Эта задача берёт все задачи для запуска в единый объект, включая нашу задачу watcher. Теперь мы можем изменить gulpfile.js на это:

var gulp = require('gulp');
var minifyCss = require('gulp-minify-css');
var coffee = require('gulp-coffee');
var paths = {
  css:['main.css'],
  script:['script.coffee']
};

gulp.task('mincss', function(){
  return gulp.src('main.css')
    .pipe(minifyCss())
    .pipe(gulp.dest('main'));
});

gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'));
});

gulp.task('watcher',function(){
  gulp.watch(paths.css, ['mincss']);
  gulp.watch(paths.script, ['scripts']);
});

gulp.task('default', ['watcher', 'mincss', 'scripts']);

Автор и редакторы

Автор: Ахмед Салифу Амиду
Последнее изменение: 25.08.2016
Редакторы: Влад Мержевич