Search code examples
gulpgulp-watch

Gulp: how to pass parameters from watch to tasks


With gulp you often see patterns like this:

gulp.watch('src/*.jade',['templates']);

gulp.task('templates', function() {
  return gulp.src('src/*.jade')
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('dist/'))
    .pipe( livereload( server ));
});

Does this actually pass the watch'ed files into the templates task? How do these overwrite/extend/filter the src'ed tasks?


Solution

  • I had the same question some time ago and came to the following conclusion after digging for a bit.

    gulp.watch is an eventEmitter that emits a change event, and so you can do this:

    var watcher = gulp.watch('src/*.jade',['templates']);
    
    watcher.on('change', function(f) {
      console.log('Change Event:', f);
    });
    

    and you'll see this:

    Change Event: { type: 'changed',
      path: '/Users/developer/Sites/stackoverflow/src/touch.jade' }
    

    This information could presumably be passed to the template task either via its task function, or the behavior of gulp.src.

    The task function itself can only receive a callback (https://github.com/gulpjs/gulp/blob/master/docs/API.md#fn) and cannot receive any information about vinyl files (https://github.com/wearefractal/vinyl-fs) that are used by gulp.

    The source starting a task (.watch in this case, or gulp command line) has no effect on the behavior of gulp.src('src-glob', [options]). 'src-glob' is a string (or array of strings) and options (https://github.com/isaacs/node-glob#options) has nothing about any file changes.

    Hence, I don't see any way in which .watch could directly affect the behavior of a task it triggers.

    If you want to process only the changed files, you can use gulp-changed (https://www.npmjs.com/package/gulp-changed) if you want to use gulp.watch, or you cold use gulp-watch.

    Alternatively, you could do this as well:

    var gulp = require('gulp');
    var jade = require('gulp-jade');
    var livereload = require('gulp-livereload');
    
    gulp.watch('src/*.jade', function(event){
      template(event.path);
    });
    
    gulp.task('templates', function() {
      template('src/*.jade');
    });
    
    function template(files) {
      return gulp.src(files)
        .pipe(jade({
          pretty: true
        }))
        .pipe(gulp.dest('dist/'))
    }