Search code examples
javascriptnode.jsnpmgulppostcss

How to overwrite file and use that file in same gulp task?


I don't even know how to explain my problem shortly in title. I want to create task which will follow these steps:

  1. Take Sass File as a source (Ex. src/scss/main.scss)
  2. Sort css properties with 'postcss-sorting'
  3. Overwrite source file to same path (Ex. src/scss/main.scss)
  4. Take sorted scss file and compile to css
  5. Write to css folder (Ex. dist/css)

I try to write this task but when i start to watch scss file changes, task having infinite loop. I tried with 2 different tasks too (one for sort css properties and write file, other one for compile and write) it still looping. I don't want to sort only css properties in css file, i want to sort my scss file too. That is my example 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' );


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


// Style
const style = () => {
    return src('src/scss/**/*.scss')
        .pipe(
            postcss([sortProperties(propertySortOrder)], {
                syntax: sassParser,
            })
        )
        .pipe(dest('src/scss'))
        .pipe(sass().on('error', sass.logError))
        .pipe(dest('src/css'))
        .pipe(browserSync.stream());
}

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

    done();
}

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

    done();
}

exports.start = series(startServer, watchFileChanges);

Can anyone help me to fix this? Thanks

P.S. Sorry for my all grammatical mistakes, English is not my native language.


Solution

  • You can use gulp-changed, it will override the file only if there is a change, preventing the infinite loop:

    const changed = require('gulp-changed');
    const clone = require( 'gulp-clone' );
    const merge = require('merge-stream');
    
    
    // Style
    const style = () => {
        const sortedCssPipe = src('src/scss/**/*.scss')
            .pipe(
                postcss([sortProperties(propertySortOrder)], {
                    syntax: sassParser,
                })
            );
    
        const scssPipe = sortedCssPipe
            .pipe(clone())
            .pipe(changed('src/scss', {hasChanged: changed.compareContents}))
            .pipe(dest('src/scss'));
    
        const cssPipe = sortedCssPipe
            .pipe(sass().on('error', sass.logError))
            .pipe(dest('src/css'))
            .pipe(browserSync.stream());
    
        return merge(scssPipe, cssPipe);
    }