В этой части мы раскроем третий раздел gulpfile.js, который позволит следить за нашими файлами и запускать задачи при сохранении. Также, помимо задачи минимизации CSS мы собираемся добавить возможность компилировать Sass-файл вместо применения исходного CSS, а затем отобразить сообщение после успешного завершения.
Вы должны знать, как вся эта работа или задачи соответствуют пакетам Gulp, которые нам нужно загрузить в проект.
Для начала, вот моя текущая структура папок:
- Build/
- index.html
- package.json
- gulpfile.js
- node_modules/
- 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']);