I'd like to have the same gulpfile.js for my projects where I use a pre-compiler (sass) and for older/smaller projects in pure css. Also I use browser-sync and I want to inject css into the browser (not reload the whole page).

My following configuration works, i.e. when I edit a sass file, it compiles and injects the compiled css, and when I edit a css file, it injects it correctly. But a little detail is still frustrating me : when I edit a sass file, browser-sync is notified 2 times that the css file has changed. 1 time in the sass watcher and 1 time in the css watcher. It doesn't seem to be a problem for him, since it correctly injects the css in my browser. But this is not very "clean".

I'd like to find a way to do some sort of exclusion for this. Ideally, just with a bit more logic in my coding, without the need to add some other packages like gulp-watch, gulp-if...

var gulp = require('gulp'),
    rubySass = require('gulp-ruby-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    browsersync  = require('browser-sync').create();

gulp.task('rubySass', function() {
  return rubySass('sources/', {
      style: 'expanded',
      sourcemap: true
    })
    .on('error', function (err) {
      console.error('Error!', err.message);
    })
    .pipe(sourcemaps.write('maps', {
        includeContent: false,
        sourceRoot: '/sources'
    }))
    .pipe(gulp.dest('./css'))
    .pipe(browsersync.stream({match: "**/*.css"}));
    // If I remove this line, browser-sync is still notified 2 times
    // (the console is still showing 2 times "[BS] 1 file changed (main.css)")
    // but, moreover, the css is no longer injected : the whole page is reloading.
});

gulp.task('browsersync', function() {
  browsersync.init({
    server: './',
    logConnections: true
  });
});

gulp.task('default', ['rubySass', 'browsersync'], function (){
  gulp.watch('**/*.html', browsersync.reload);
  gulp.watch('**/*.php', browsersync.reload);
  gulp.watch('js/**/*.js', browsersync.reload);

  gulp.watch('**/*.css', function(file){
    console.log("In gulp watch : css");
    gulp.src(file.path)
        .pipe(browsersync.stream());
  });
  gulp.watch('./sources/**/*.scss', ['rubySass']).on('change', function(evt) {
    console.log("In gulp watch : sass");
  });
});

Here's the console output, when saving a sass file : Console output

As we can see, we enter successively in the 2 watchers and browser-sync is saying 2 times "[BS] 1 file changed (main.css)".

1

There are 1 answers

0
Maksymilian Majer On

Since your SASS always compiles to .css you just need to watch for changes in your .css files. It will fire on SASS change anyway (because .css will be generated and gulp.watch triggered by this .css change). Otherwise you can use exclusions in gulp.watch() and use some kind of pattern (ex. subdirectory) to identify .css files generated from SASS. You can try this one:

var gulp = require('gulp'),
    rubySass = require('gulp-ruby-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    browsersync  = require('browser-sync').create();

gulp.task('rubySass', function() {
  return rubySass('sources/', {
      style: 'expanded',
      sourcemap: true
    })
    .on('error', function (err) {
      console.error('Error!', err.message);
    })
    .pipe(sourcemaps.write('maps', {
        includeContent: false,
        sourceRoot: '/sources'
    }))
    // note the destination change here
    .pipe(gulp.dest('./css/sass')) // note the destination change here
    .pipe(browsersync.stream({match: "**/*.css"}));
});

gulp.task('browsersync', function() {
  browsersync.init({
    server: './',
    logConnections: true
  });
});

gulp.task('default', ['rubySass', 'browsersync'], function (){
  gulp.watch('**/*.html', browsersync.reload);
  gulp.watch('**/*.php', browsersync.reload);
  gulp.watch('js/**/*.js', browsersync.reload);

  // added exclusion for the CSS files generated from SASS
  gulp.watch(['**/*.css', '!./css/sass/**/*.css'], function(file){
    console.log("In gulp watch : css");
    gulp.src(file.path)
        .pipe(browsersync.stream());
  });
  gulp.watch('./sources/**/*.scss', ['rubySass']).on('change', function(evt) {
    console.log("In gulp watch : sass");
  });
});