gulpgulp-watchgulp-browser-syncgulp-4

Gulp 4 watch not working, only run one time


I changed from Gulp 3 to Gulp 4, but I can't get it to work.

When I run gulp and save SCSS or HTML file it creates a new file successfully. If I save again nothing happens. It only runs ones.

Below is my gulpfile.js

'use strict';

var gulp = require('gulp');
var sass = require('gulp-sass');
var browserSync = require('browser-sync').create();

sass.compiler = require('node-sass');


gulp.task('sass', function() {
 return gulp.src('template/assets/scss/**/*.scss')
   .pipe(sass.sync({outputStyle: 'expanded'}).on('error', sass.logError))
   .pipe(gulp.dest('template/assets/css/'))
   .pipe(browserSync.stream());
});


// Static Server and watching scss/html files
gulp.task('server', gulp.series('sass', function(){
    browserSync.init({
        server: {
            baseDir: "./template"
        }
    });
    gulp.watch("template/assets/scss/**/*.scss", gulp.task('sass'));
    gulp.watch("template/assets/scss/**/*.scss", browserSync.reload);
    gulp.watch("template/**/*.html", browserSync.reload);
}));


gulp.task('watch', function() {
    gulp.watch(['sass']);
});


gulp.task('default', gulp.series(gulp.parallel('sass', 'watch', 'server')))

Solution

  • The 'watch' task you have is unnecessary (and its syntax is wrong):

    gulp.task('watch', function() {
        gulp.watch(['sass']);
    });
    

    so delete it. You already have gulp.watch statements in your 'server' task:

    gulp.watch("template/assets/scss/**/*.scss", gulp.task('sass'));
    //  gulp.watch("template/assets/scss/**/*.scss", browserSync.reload);
    

    I commented out the second one above because you already call

    .pipe(browserSync.stream()); 
    

    at the end of the 'sass' task so the commented out browserSync.reload line is duplicative as well.

    You need to signal async completion in your 'server' task too, see where I added the done callback to do this:

    // Static Server and watching scss/html files
    gulp.task('server', function (done) {
        browserSync.init({
            server: {
                baseDir: "./template"
            }
        });
        gulp.watch("template/assets/scss/**/*.scss", gulp.series('sass'));
        //  gulp.watch("template/assets/scss/**/*.scss", browserSync.reload);
        gulp.watch("template/**/*.html", browserSync.reload);
        done();
    });
    

    I removed the gulp.series('sass') call from the beginning of the 'serve' task because you already call 'sass' first in your default task so you don't need it in the 'server' task.

    Also note the use of gulp.series('sass') in the first watch instead of gulp.task('sass').

    Finally, since we are removing the separate 'watch' task, change the 'default' task to :

    gulp.task('default', gulp.series('sass', 'server'));
    

    and remove the gulp.parallel in there - you simply want 'sass' to run before 'server'.

    Here are all the changes:

    // Static Server and watching scss/html files
    gulp.task('server', function (done) {
        browserSync.init({
            server: {
                baseDir: "./template"
            }
        });
        gulp.watch("template/assets/scss/**/*.scss", gulp.series('sass'));
        // gulp.watch("template/assets/scss/**/*.scss", browserSync.reload);
        gulp.watch("template/**/*.html", browserSync.reload);
        done();
    }));
    
    
    // gulp.task('watch', function() {
    //    gulp.watch(['sass']);
    // });
    
    gulp.task('default', gulp.series('sass', 'server'));