From 2cd0e1e91214e41265469df880815ffa82f20444 Mon Sep 17 00:00:00 2001 From: Stefan Baumgartner Date: Wed, 16 Sep 2015 10:21:13 +0200 Subject: [PATCH] Breaking: Replace vinyl-fs watch/gaze with chokidar --- docs/API.md | 33 ++++++++++----- .../handling-the-delete-event-on-watch.md | 22 ++++------ index.js | 11 ++++- package.json | 1 + test/watch.js | 42 ++++++++++++------- 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/docs/API.md b/docs/API.md index 75b727ca1..17263fc31 100644 --- a/docs/API.md +++ b/docs/API.md @@ -509,31 +509,42 @@ A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` -Options, that are passed to [`gaze`][gaze]. +Options, that are passed to [`chokidar`][chokidar]. #### fn Type: `Function` An [async](#async-support) function to run when a file changes. -`gulp.watch` returns an `EventEmitter` object which emits `change` events with -the [gaze] `event`: +`gulp.watch` returns a wrapped [chokidar] FSWatcher object. If provided, +the callback will be triggered upon any `add`, `change`, or `unlink` event. +Listeners can also be set directly for any of [chokidar]'s events. + ```js var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); -watcher.on('change', function(event) { - console.log('File ' + event.path + ' was ' + event.type); +watcher.on('change', function(path, stats) { + console.log('File ' + path + ' was changed'); + if (stats) { + console.log('changed size to ' + stats.size); + } +}); + +watcher.on('unlink', function(path) { + console.log('File ' + path + ' was removed'); }); ``` -##### event.type +##### path Type: String -The type of change that occurred, either "added", "changed" or "deleted". +The relative path of the document. -##### event.path -Type: String +##### stats +Type: Object -The path to the file that triggered the event. +[File stats](http://nodejs.org/api/fs.html#fs_class_fs_stats) object when available. +Setting the `alwaysStat` option to true will ensure that a file stat object will be +available. ### gulp.tree(options) @@ -737,7 +748,7 @@ module.exports = new MyCompanyTasksRegistry(); ``` [Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name -[gaze]: https://github.com/shama/gaze +[chokidar]: https://github.com/paulmillr/chokidar [glob-stream]: https://github.com/gulpjs/glob-stream [glob-parent]: https://github.com/es128/glob-parent [gulp-if]: https://github.com/robrich/gulp-if diff --git a/docs/recipes/handling-the-delete-event-on-watch.md b/docs/recipes/handling-the-delete-event-on-watch.md index 40cf115fb..05bd683a1 100644 --- a/docs/recipes/handling-the-delete-event-on-watch.md +++ b/docs/recipes/handling-the-delete-event-on-watch.md @@ -1,9 +1,8 @@ # Handling the Delete Event on Watch -You can listen for `'change'` events to fire on the watcher returned from `gulp.watch`. - -Each change event has a `type` property. If `type` is `'deleted'`, you can delete the file -from your destination directory, using something like: +You can listen for `'unlink'` events to fire on the watcher returned from `gulp.watch`. +This gets fired when files are removed, so you can delete the file from your destination +directory, using something like: ```js 'use strict'; @@ -24,16 +23,11 @@ gulp.task('scripts', function() { gulp.task('watch', function () { var watcher = gulp.watch('src/**/*.js', ['scripts']); - watcher.on('change', function (event) { - if (event.type === 'deleted') { - // Simulating the {base: 'src'} used with gulp.src in the scripts task - var filePathFromSrc = path.relative(path.resolve('src'), event.path); - - // Concatenating the 'build' absolute path used by gulp.dest in the scripts task - var destFilePath = path.resolve('build', filePathFromSrc); - - del.sync(destFilePath); - } + watcher.on('unlink', function (filepath) { + var filePathFromSrc = path.relative(path.resolve('src'), filepath); + // Concatenating the 'build' absolute path used by gulp.dest in the scripts task + var destFilePath = path.resolve('build', filePathFromSrc); + del.sync(destFilePath); }); }); ``` diff --git a/index.js b/index.js index 1b5841621..46309dbcb 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ var util = require('util'); var Undertaker = require('undertaker'); var vfs = require('vinyl-fs'); +var chokidar = require('chokidar'); function Gulp() { Undertaker.call(this); @@ -30,7 +31,15 @@ Gulp.prototype.watch = function(glob, opt, task) { fn = this.parallel(task); } - return vfs.watch(glob, opt, fn); + var watcher = chokidar.watch(glob, opt); + if (fn) { + watcher + .on('change', fn) + .on('unlink', fn) + .on('add', fn); + } + + return watcher; }; // Let people use this class from our instance diff --git a/package.json b/package.json index 9e1adcf77..8ab6637b2 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "man": "gulp.1", "dependencies": { + "chokidar": "^1.0.5", "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.12.0", "vinyl-fs": "^1.0.0" diff --git a/test/watch.js b/test/watch.js index 1b1f9d6dd..788df4b4e 100644 --- a/test/watch.js +++ b/test/watch.js @@ -36,7 +36,7 @@ describe('gulp', function() { createTempFile(tempFile); var watcher = gulp.watch(tempFile, function(cb) { - watcher.end(); + watcher.close(); cb(); done(); }); @@ -44,13 +44,30 @@ describe('gulp', function() { updateTempFile(tempFile); }); + it('should execute the gulp.parallel tasks', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); + + createTempFile(tempFile); + + gulp.task('test', function(cb) { + watcher.close(); + cb(); + done(); + }); + + var watcher = gulp.watch(tempFile, gulp.parallel('test')); + + updateTempFile(tempFile); + }); + + it('should call the function when file changes: w/ options', function(done) { var tempFile = path.join(outpath, 'watch-func-options.txt'); createTempFile(tempFile); - var watcher = gulp.watch(tempFile, {debounceDelay: 5}, function(cb) { - watcher.end(); + var watcher = gulp.watch(tempFile, function(cb) { + watcher.close(); cb(); done(); }); @@ -66,14 +83,11 @@ describe('gulp', function() { createTempFile(tempFile); - var watcher = gulp.watch(relFile, {debounceDelay: 5, cwd: cwd}) - .on('change', function(evt) { - should.exist(evt); - should.exist(evt.path); - should.exist(evt.type); - evt.type.should.equal('changed'); - evt.path.should.equal(path.resolve(tempFile)); - watcher.end(); + var watcher = gulp.watch(relFile, {cwd: cwd}) + .on('change', function(filepath) { + should.exist(filepath); + path.resolve(cwd, filepath).should.equal(path.resolve(tempFile)); + watcher.close(); done(); }); @@ -93,12 +107,12 @@ describe('gulp', function() { gulp.task('task2', function(cb) { a += 10; a.should.equal(11); - watcher.end(); + watcher.close(); cb(); done(); }); - var watcher = gulp.watch(tempFile, {debounceDelay: 25}, gulp.series('task1', 'task2')); + var watcher = gulp.watch(tempFile, gulp.series('task1', 'task2')); updateTempFile(tempFile); }); @@ -116,7 +130,7 @@ describe('gulp', function() { gulp.task('task2', function(cb) { a += 10; a.should.equal(11); - watcher.end(); + watcher.close(); cb(); done(); });