You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决同一Gulp任务中覆盖SCSS文件引发的无限循环问题?

Fixing Infinite Loop in Gulp SCSS Sort & Compile Task

Got it, let's break down why your task is stuck in an infinite loop first, then fix it step by step.

The Root Cause

Your original style task writes the sorted SCSS files back to the src/scss directory—exactly the folder your watcher is listening to. Every time the task finishes writing sorted files, the watcher detects a "change" and triggers the task again, creating an endless cycle. Even splitting tasks won't help if the sort task still modifies the watched source files.

The Solution

We'll split the workflow into two isolated tasks (sorting and compiling) and use a plugin to prevent unnecessary file writes that trigger the watcher. Here's how:

Step 1: Install Required Plugin

First, add gulp-changed to detect actual content changes (not just file timestamp updates):

npm install gulp-changed --save-dev

Step 2: Updated Gulpfile Code

// Load plugins
const { gulp, watch, src, dest, series } = require('gulp'),
      browserSync = require('browser-sync').create(),
      postcss = require('gulp-postcss'),
      sortProperties = require('postcss-sorting'),
      sassParser = require('postcss-scss'),
      sass = require('gulp-sass'),
      changed = require('gulp-changed'); // New: Detect real content changes

// Load CSS property orders for 'postcss-sorting'
const propertySortOrder = require('./propertySortOrder');

// 1. Task: Sort SCSS properties (only modify files with actual content changes)
const sortScss = () => {
  return src('src/scss/**/*.scss')
    // Only process files where content differs from the existing file
    .pipe(changed('src/scss', { hasChanged: changed.compareContents }))
    .pipe(postcss([sortProperties(propertySortOrder)], { syntax: sassParser }))
    .pipe(dest('src/scss'));
};

// 2. Task: Compile sorted SCSS to CSS
const compileScss = () => {
  return src('src/scss/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(dest('dist/css')) // Matches your requirement to output to dist/css
    .pipe(browserSync.stream());
};

// Combined workflow: Sort first, then compile
const style = series(sortScss, compileScss);

// Start Server
const startServer = (done) => {
  browserSync.init({
    server: { baseDir: './' },
    injectChanges: true
  });
  done();
};

// Watch File Changes
const watchFileChanges = (done) => {
  watch('src/scss/**/*.scss', style);
  done();
};

// Export tasks
exports.start = series(startServer, watchFileChanges);
exports.style = style;
exports.sortScss = sortScss;
exports.compileScss = compileScss;

Key Fixes Explained

  • gulp-changed with compareContents: This ensures the sortScss task only writes to the source directory if the sorted content is different from the original file. No unnecessary writes = no false "change" triggers for the watcher.
  • Isolated Tasks: Separating sorting and compiling makes the workflow easier to debug and maintain. The combined style task runs them in sequence only when a real change is detected.
  • Corrected Output Path: I updated the compile output to dist/css to match your original requirement (your code had src/css which was likely a typo).

Testing It Out

When you modify a file in src/scss:

  1. The watcher triggers the style task
  2. sortScss runs, sorts the properties, and writes back to src/scss (only if content changed)
  3. compileScss runs, takes the sorted SCSS, and compiles it to dist/css
  4. No further triggers happen because sortScss won't rewrite the file again (content is already sorted)

Content的提问来源于stack exchange,提问作者Lachrimae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 14:57:52