Search code examples
gulpgulp-watchgulp-sass

gulp-watch stops after detecting only one change in .scss file. Is there any way to keep it running in this code?


I'm learning React development, and I use gulp and sass for the CSS. The gulp-watch task only completes the task compile_scss once and stops doing it. Is there any way to keep the watch active at all times? I've included the code and resulting terminal outputs below.

The code I'm learning from is for the previous version of gulp. The version I'm using now uses updated syntax i.e, gulp.series('compile_scss') instead of [compile_scss].I've updated my code accordingly.

'use strict';

//dependencies
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifyCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var changed = require('gulp-changed');


//SCSS/CSS


var SCSS_SRC = './src/assets/scss/**/*.scss';
var SCSS_DEST = './src/assets/css';

//compile SCSS
gulp.task('compile_scss', function(){

    gulp.src(SCSS_SRC)
    .pipe(sass().on('error', sass.logError))
    .pipe(minifyCSS())
    .pipe(rename({ suffix: '.min' }))
    .pipe(changed(SCSS_DEST))
    .pipe(gulp.dest(SCSS_DEST));
});


//detect changes in SCSS
gulp.task('watch_scss', gulp.series(function(){
    gulp.watch(SCSS_SRC, gulp.series('compile_scss'));
}));


//Run tasks
gulp.task('default', gulp.series('watch_scss'));
````````````

````Terminal Output
[14:08:37] Using gulpfile ~\Desktop\rct\my-react-project\gulpfile.js
[14:08:37] Starting 'default'...
[14:08:37] Starting 'watch_scss'...
[14:08:37] Starting '<anonymous>'...
[14:08:48] Starting 'compile_scss'...
```````````

I expect the gulp-watch to always check for changes in my source.

Solution

  • Every gulp task function is passed a callback as its first argument, to let you signal that the task is over.

    In your compile_scss task, you should signal async completion by making that call on task end.

    //compile SCSS
    gulp.task('compile_scss', function(done){
        return gulp.src(SCSS_SRC)
        .pipe(sass().on('error', sass.logError))
        .pipe(minifyCSS())
        .pipe(rename({ suffix: '.min' }))
        .pipe(changed(SCSS_DEST))
        .pipe(gulp.dest(SCSS_DEST))
        .on('end', function(error) {
          if (error) {
            // Handle errors if any
          }
          // Signal that the task is over
          done();
        })
    });
    

    Also, you don't have to wrap the watch task in a gulp.series. It can (should?) be like this:

    //detect changes in SCSS
    gulp.task('watch_scss', function() {
        return gulp.watch(SCSS_SRC, gulp.series('compile_scss'));
    });
    

    Finally, if none of this works, try passing the usePolling option to the watcher:

    gulp.task('watch_scss', {usePolling: true}, function() { ...
    

    In certain systems, it is required for it to work correctly. you can check the whole Chkidar API here (Chokidar is the library used by gulp to watch files)


    EDIT: in compile_sass, the task must return the pipe.