В версии 3.x Gulp.js действительно может возникнуть проблема зацикливания при одновременной сборке SCSS и CSS файлов.
Это происходит из-за особенностей последовательности выполнения задач в Gulp. При запуске Gulp.js вам может понадобиться создать несколько задач, например, для компиляции SCSS в CSS и для минификации CSS файлов. Вы можете определить эти задачи следующим образом:
const gulp = require('gulp'); const sass = require('gulp-sass'); const minifyCSS = require('gulp-clean-css'); gulp.task('sass', function() { return gulp.src('src/scss/**/*.scss') .pipe(sass()) .pipe(gulp.dest('dist/css')); }); gulp.task('minify-css', function() { return gulp.src('dist/css/*.css') .pipe(minifyCSS()) .pipe(gulp.dest('dist/css-min')); }); gulp.task('default', gulp.series('sass', 'minify-css'));
При запуске задач Gulp в режиме наблюдения за изменениями файлов (например, командой gulp
или gulp watch
), Gulp будет следить за изменениями SCSS файлов и автоматически компилировать их в CSS. Затем Gulp будет следить за изменениями CSS файлов, минифицировать их и сохранять в отдельной папке.
Проблема возникает, когда компиляция SCSS файла вызывает перезапись CSS файла, и Gulp снова замечает изменение в CSS файле, вызывая задачу minify-css
, которая в свою очередь изменяет и перезаписывает CSS файл, и так далее. Это создает зацикливание задач и бесконечный цикл сборки.
Чтобы предотвратить это, можно воспользоваться одним из следующих решений:
1. Используйте условие, чтобы проверить, если SCSS файл изменился, прежде чем запустить компиляцию и сохранение CSS файла:
const gulp = require('gulp'); const sass = require('gulp-sass'); const minifyCSS = require('gulp-clean-css'); let isCompilingSCSS = false; gulp.task('sass', function() { if (isCompilingSCSS) return; isCompilingSCSS = true; return gulp.src('src/scss/**/*.scss') .pipe(sass()) .pipe(gulp.dest('dist/css')) .on('end', function() { isCompilingSCSS = false; }); }); gulp.task('minify-css', function() { return gulp.src('dist/css/*.css') .pipe(minifyCSS()) .pipe(gulp.dest('dist/css-min')); }); gulp.task('default', gulp.series('sass', 'minify-css'));
В этом случае мы добавляем флаг isCompilingSCSS
, который показывает, что в данный момент выполняется задача компиляции SCSS. Если флаг уже установлен (т.е. предыдущая задача еще не завершена), задача sass
будет прервана. Флаг будет установлен в значение true
в момент начала выполнения задачи, и будет сброшен в значение false
по завершении.
2. Используйте плагин gulp-newer
, чтобы отслеживать только измененные файлы и минимизировать количество повторных задач:
const gulp = require('gulp'); const sass = require('gulp-sass'); const minifyCSS = require('gulp-clean-css'); const newer = require('gulp-newer'); gulp.task('sass', function() { return gulp.src('src/scss/**/*.scss') .pipe(newer('dist/css')) .pipe(sass()) .pipe(gulp.dest('dist/css')); }); gulp.task('minify-css', function() { return gulp.src('dist/css/*.css') .pipe(newer('dist/css-min')) .pipe(minifyCSS()) .pipe(gulp.dest('dist/css-min')); }); gulp.task('default', gulp.series('sass', 'minify-css'));
Здесь мы используем плагин gulp-newer
, который отслеживает изменения только для уже существующих файлов в указанной папке. Это позволяет избежать повторной обработки файлов, что приводит к зацикливанию задач. Плагин будет сохранять временную метку изменения файла и сравнивать ее с рабочими файлами, пропуская только новые или измененные файлы.
3. Используйте Gulp 4.x, который предлагает более гибкую систему тасков и позволяет использовать gulp.series
и gulp.parallel
для управления последовательностью выполнения задач:
const gulp = require('gulp'); const sass = require('gulp-sass'); const minifyCSS = require('gulp-clean-css'); gulp.task('sass', function() { return gulp.src('src/scss/**/*.scss') .pipe(sass()) .pipe(gulp.dest('dist/css')); }); gulp.task('minify-css', function() { return gulp.src('dist/css/*.css') .pipe(minifyCSS()) .pipe(gulp.dest('dist/css-min')); }); gulp.task('default', gulp.series('sass', 'minify-css'));
В Gulp 4.x можно явно указать последовательность выполнения задач с помощью gulp.series
. Это позволяет установить желаемую последовательность, чтобы избежать зацикливания. В данном случае задача minify-css
не будет выполняться до завершения задачи sass
, что исключает возможность зацикливания.
Выбор определенного решения зависит от ваших потребностей и предпочтений. Каждое из этих решений имеет свои особенности и подходит для различных сценариев использования.