Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript, gulp, watch, changed

I cannot get my head around this. This is supposed to be a gulp task that is executed every time a watched file is modified. Can anyone explain why it is required to pipe the watched files through the changed plugin?

gulp.task('build-css', function () {
  return gulp.src(paths.css)
  .pipe(changed(paths.output, {extension: '.css'}))
  .pipe(gulp.dest(paths.output));
});

gulp.task('watch', ['serve'], function() { 
  gulp.watch(paths.css, ['build-css']); 
}); 

Disclaimer: this is not my code. Just trying to understand what is going on, in order to create my own custom watch task.

like image 586
mishoo78 Avatar asked Dec 06 '22 18:12

mishoo78


1 Answers

The difference between gulp.watch(), gulp-changed and gulp-watch seems to cause a lot of confusion, so here's my attempt at untangling the mess:

gulp.watch()

This is the only one of the three that is part of gulp itself and not a plugin. This is important, because it means that unlike the other two it is not passed to the pipe() function of a gulp stream.

Instead it is usually called directly from inside a gulp task:

 gulp.task('build-css', function() { 
    return gulp.src('src/**/*.css')
      .pipe(doSomethingHere())
      .pipe(gulp.dest('dist/css'));
 }); 

 gulp.task('watch', function() { 
    gulp.watch('src/**/*.css', ['build-css']); 
 }); 

In the above gulp.watch() is used to listen for changes in .css files. As long as gulp.watch() is running any change to a .css file automatically results in the execution of the build-css task.

This is where the trouble starts. Notice how no information about which files where changed is passed to build-css? That means even if you change just a single .css file all of your .css files will pass through doSomethingHere() again. The build-css task has no clue which of them changed. This may be fine as long as you have only a hand full of files, but can slow down your build as the number of files grows.

That's where gulp-changed comes in.

gulp-changed

This plugin was written to act as a filter stage in a gulp stream. Its purpose is to remove all those files from a stream that haven't changed since the last build. It does this by comparing the files in the source directory with the resulting files in the destination directory:

 gulp.task('build-css', function() { 
    return gulp.src('src/**/*.css')
      .pipe(changed('dist/css'))  //compare with files in dist/css
      .pipe(doSomethingHere())
      .pipe(gulp.dest('dist/css'));
 }); 

 gulp.task('watch', function() { 
    gulp.watch('src/**/*.css', ['build-css']); 
 }); 

In the above the build-css task is still called for every change of a .css file and all .css files are read in. However only those files that were actually changed now reach the expensive doSomethingHere() stage. The rest is filtered out by gulp-changed.

This approach has the benefit of speeding up build-css even if you're not watching for file changes. You can explicitly invoke gulp build-css on the command-line and only those files that have changed since the last invocation of build-css will be rebuilt.

gulp-watch

This plugin is an attempt to improve on the built-in gulp.watch(). While gulp.watch() uses gaze to listen for file changes, gulp-watch uses chokidar which is generally considered to be the more mature of the two.

You can use gulp-watch to achieve the same effect as using gulp.watch() and gulp-changed in combination:

 gulp.task('watch-css', function() { 
    return gulp.src('src/**/*.css')
      .pipe(watch('src/**/*.css'))
      .pipe(doSomethingHere())
      .pipe(gulp.dest('dist/css'));
 }); 

This again watches all .css files for changes. But this time whenever a .css file is changed, that file (and only that file) is read in again and reemitted to the stream where it passes through doSomethingHere() on its way to the destination directory.


Note that this comparison paints all three of the alternatives in rather broad strokes and leaves out certain details and features (e.g. I haven't talked about the callback functions that you can pass to both gulp.watch() and gulp-watch), but I think this should be enough to get the major differences between the three across.

like image 198
Sven Schoenung Avatar answered Dec 27 '22 07:12

Sven Schoenung