node.jsgulpbrowser-syncgulp-browser-sync

Node + Gulp - Have to save files two times to see changes in browser


Could you please point me in the right direction to solve this inconsistence?

I'm working in a new project using Node, gulp and a list of gulp's plugins. Everytime I do Ctrl + S the browser does reload but I don't see the changes applied so I need to Ctrl + S again to see them. This second time the browser reloads again displaying the changes.

This is happening with any of my html, scss or js files under my source directory.

I'm working on Windows 10 using Visual Studio Code and everything works fine except for this.

My gulpfile.js content is the following:

    var gulp = require('gulp');
    var sass = require('gulp-sass');
    var inject = require('gulp-inject');
    var wiredep = require('wiredep').stream;
    var plumber = require('gulp-plumber');
    var imagemin = require('gulp-imagemin');
    var browserSync = require('browser-sync');
    var uglify = require('gulp-uglify');

    gulp.task('styles', function(){
      var injectFiles = gulp.src(['!src/styles/main.scss', 'src/styles/*.scss'], {read: false});
      var injectGlobalFiles = gulp.src('src/global/*.scss', {read: false});

     function transformFilepath(filepath) {
        return '@import "' + filepath + '";';
      }

      var injectFilesOptions = {
        transform: transformFilepath,
        starttag: '// inject:app',
        endtag: '// endinject',
        addRootSlash: false
      };

      var injectGlobalOptions = {
        transform: transformFilepath,
        starttag: '// inject:global',
        endtag: '// endinject',
        addRootSlash: false
      };

      return gulp.src('src/styles/main.scss')
        .pipe(plumber())
        .pipe(wiredep())
        .pipe(inject(injectGlobalFiles, injectGlobalOptions))
        .pipe(inject(injectFiles, injectFilesOptions))
        .pipe(sass())
        .pipe(gulp.dest('dist/styles'));
    });

    gulp.task('browser-sync', function() {  
      browserSync.init(["styles/*.css", "js/*.js","index.html"], {
          server: {
              baseDir: "dist"
          }
      });
    });

    gulp.task('html', ['styles'], function(){
      var injectFiles = gulp.src('src/styles/*.scss', {read: false});
      var injectOptions = {
        addRootSlash: false,
        ignorePath: ['src', 'dist']
      };

      return gulp.src('src/index.html')
        .pipe(plumber())
        .pipe(inject(injectFiles, injectOptions))
        .pipe(gulp.dest('dist'));
    });

    gulp.task('imagemin', function() {
      gulp.src('src/assets/*.{jpg,jpeg,png,gif,svg}')
      .pipe(plumber())
      .pipe(imagemin())
      .pipe(gulp.dest('dist/assets'));
    });

    gulp.task('uglify', function() {
      gulp.src('src/js/*.js')
          .pipe(uglify())
          .pipe(gulp.dest('dist/js'));
    });

    gulp.task('sass', function() {
      gulp.src('src/styles/*.scss')
          .pipe(plumber())
          .pipe(sass())
          .pipe(gulp.dest('dist/styles/'));
    });

    gulp.task('watch', function() {
      gulp.watch('src/js/*.js', ['uglify']).on('change', browserSync.reload);
      gulp.watch('src/styles/*.scss', ['sass']).on('change', browserSync.reload);
      gulp.watch('src/assets/*.{jpg,jpeg,png,gif,svg}', ['imagemin']).on('change', browserSync.reload);
      gulp.watch('src/index.html', ['html']).on('change', browserSync.reload);
    });



gulp.task('default', ['html', 'sass','imagemin', 'uglify', 'browser-sync', 'watch']);

Any help will be very appreciated.

Thank you and have a good one.


Solution

  • Try these changes:

    var browserSync = require('browser-sync').create();
    
     gulp.task('watch', function() {
      gulp.watch('src/js/*.js', ['uglify']).on('change', browserSync.reload({ stream:true }));
      gulp.watch('src/styles/*.scss', ['sass']).on('change', browserSync.reload({ stream:true }));
      gulp.watch('src/assets/*.{jpg,jpeg,png,gif,svg}', ['imagemin']).on('change', browserSync.reload);
      gulp.watch('src/index.html', ['html']).on('change', browserSync.reload());
    });
    

    If that doesn't help, I would move the reload calls to the end of each task like this :

    .pipe(browserSync.reload({ stream:true }));
    

    Hope this helps.

    [EDIT]

    Change to this:

    gulp.task('watch', function() {
      gulp.watch('src/js/*.js', ['uglify']);
      gulp.watch('src/styles/*.scss', ['sass']);
      gulp.watch('src/assets/*.{jpg,jpeg,png,gif,svg}', ['imagemin']);
      gulp.watch('src/index.html', ['html']).on('change', browserSync.reload);
    });
    
    gulp.task('imagemin', function() {
      return gulp.src('src/assets/*.{jpg,jpeg,png,gif,svg}')
        .pipe(plumber())
        .pipe(imagemin())
        .pipe(gulp.dest('dist/assets'));
        .pipe(browserSync.reload({ stream:true }));
    });
    
    gulp.task('uglify', function() {
      return gulp.src('src/js/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('dist/js'));
        .pipe(browserSync.reload({ stream:true }));
    });
    
    gulp.task('sass', function() {
      return gulp.src('src/styles/*.scss')
        .pipe(plumber())
        .pipe(sass())
        .pipe(gulp.dest('dist/styles/'));
        .pipe(browserSync.reload({ stream:true }));
    });
    

    The other parts of your gulpfile don't change. Except do make the previously suggested change:

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