Перезагрузка .html и .css файлов gulp
Мне нужно прослушивать файлы .scss и .html и перезагружать из при изменении
gulpfile.js:
var
gulp = require('gulp'),
livereload = require('gulp-livereload'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
cleancss = require('gulp-cleancss'),
rename = require('gulp-rename');
gulp.task('reload-css', function () {
gulp.src('./src/sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
overrideBrowserslist: ['last 3 versions'],
cascade: false
}))
.pipe(cleancss({compatibility: 'ie8'}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./src/css/'))
.pipe(livereload())
});
gulp.task('reload-html', function () {
gulp.src('./src/*.html')
.pipe(livereload())
});
gulp.task('default', function () {
livereload.listen();
gulp.watch('./src/sass/*.scss', gulp.parallel('reload-css', 'default'));
gulp.watch('./src/*.html', gulp.parallel('reload-html', 'default'));
});
Когда, допустим, я сохраняю .scss файл, то все хорошо, но если я сохраню изменения в .html файле, то происходит это
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] Starting 'reload-html'...
[18:08:49] Starting 'default'...
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
[18:08:49] D:\OpenServer\OSPanel\domains\localhost\src\index.html reloaded.
Как убрать эту многоразовую перезагрузку, при этом оставив функцию следить за 2 файлами сразу?
Ответы (1 шт):
Каждый раз, когда ваши файлы подвергаются изменению вы снова вызываете задачу default. Причем выполнение этой задачи вы осуществляете параллельно, а не последовательно. И проблема даже не в параллельности или последовательности, а в том, что после запуска задачи default вы рекурсивно запускаете её снова и снова, после каждого изменения файла.
gulp.task('default', () => {
gulp.watch(..., gulp.parallel(..., 'default')); // Рекурсивный вызов задачи default
gulp.watch(..., gulp.parallel(..., 'default')); // Рекурсивный вызов задачи default
});
Попробуйте заменить на этот код:
gulp.task('default', function () {
livereload.listen();
gulp.watch('./src/sass/*.scss', gulp.series('reload-css'));
gulp.watch('./src/*.html', gulp.series('reload-html'));
});
или так, согласно примеру:
gulp.task('default', function () {
livereload.listen();
gulp.watch('./src/sass/*.scss', ['reload-css']);
gulp.watch('./src/*.html', ['reload-html']);
});
Итак по порядку разберемся как работает наблюдатель watch.
Если попытаться кратко объяснить суть работы наблюдателя - он следит за изменением файлов и структуры каталогов, далее пытается делегировать выполнение кода другим задачам переданным в качестве след. аргументов.
Если подробней рассмотреть пример из официальной документации, можно заметить что сигнатура метода watch принимает три параметра, первый из них является обязательным, остальные два не обязательны.
gulp.watch(globs, [options], [task]);
Немного ниже описаны параметры наблюдателя:
- globs - это маска, по которому будет отслеживаться изменение структуры файловой системы (пути и файлы). Этот аргумент может быть представлен в качестве строки или массива. Если вы указали массив, тогда наблюдатель будет следить по нескольким правилам. Например за несколькими структурами каталогов
['src/html/*.html', 'src/pug/*.pug'] - options - Необязательный параметр, предоставляется в качестве объекта. Если вам нужно задать какие-то специфические правила отслеживания, вы можете задать свои правила в этом параметре. Там их много, подробней смотрите в документации.
- task - здесь вызываются другие задачи из вашего gulp-файла. Предоставляется либо строкой либо массивом. Если вы указали массив, соответственно после изменений будут выполнятся несколько задач.
Примеры:
// после изменения изображения выполняем задачу task1
gulp.watch('src/img/**', 'task1');
// если изображения были удалены, выполнить задачу task2
gulp.watch('src/img/**/*', { events: 'unlink' }, ['task2']);
// после изменения изображений выполняем задачу task3
gulp.watch(['src/img/*.png','src/img/*.jpg'], 'task3');
// после изменения html-файлов выполняем несколько задач
gulp.watch('src/html/*.html', ['task4', 'task5']);
// тоже самое
gulp.watch('src/html/*.html', gulp.series('task4', 'task5'));
// тоже самое, но выполнить несколько задач одновременно (параллельно)
gulp.watch('src/html/*.html', gulp.parallel('task4', 'task5'));
Касательно этого блока:
// Объявляем новую задачу "default"
gulp.task('default', function () {
livereload.listen();
gulp.watch('./src/sass/*.scss', ['reload-css']);
gulp.watch('./src/*.html', ['reload-html']);
});
Прежде всего, как сказано из документации: "каждая задача gulp - это асинхронная функция JavaScript, которая либо принимает обратный вызов при первой ошибке, либо возвращает поток, обещание, эмиттер событий, дочерний процесс или наблюдаемое. Из-за некоторых ограничений платформы синхронные задачи не поддерживаются."
Каждая задача в gulp-файле доступна из командной строки, а также доступна для текущего контекста выполнения Gulp интерфейсом.
Пример оформления gulp-файла версии 4 можно посмотреть здесь