Skip to content

Commit 94fa19f

Browse files
committed
CLI: Re-implement run.watch() with 'node-watch' instead of 'sane'
Similar to the previous commit, I considered a simple approach of our own based on the built-in Node.js API. The fs.watch() API is actually quite good in Node 6+ (certainly much better than it used to be). But, there are two notable issues that I think we should care about: 1. Its "recursive" feature is lacking on Linux (only stable on macOS and Windows). 2. Its ability to distinguish between create, update and remove events isn't very good. This last point would be fairly easily to do on the consumer side with a quick fs.stat() call. We could even omit it entirely given we only use it for one word (a verb) in the CLI output. But the first point (recursion) is slightly more involved than I'd like to maintain locally. All the reviewed packages essentially handle this the same way. They create a non-recursive fs.watch() for each sub directory found on the system, track them in an object. Then, start new ones as needed when new directories are created, and stop old one when directories are removed. That's about 100 lines of simple code. Where they differ is: * How many extra features they provide. * How many simple functions for non-critical code are delegated to other packages. * Whether they use native "recursive" when available (on macOS/Windows). privide in addition to that I'm proposing we go with node-watch. This package is well-maintained, tested with the latest Node versions, optimised for Node 6+, and provides no additional features, and is dependency-free. > [email protected] (current) > Dependencies: ⚠️ > 119 packages. > (concerning in terms of dicipline and security) > License: ✅ > MIT. > Supported: ✅ > 2018 saw 25 commits, 8 contributors, 2 major releases. > Modern: *️⃣ > Requires Node 6+, but not yet tested on Node 10. > [email protected] > Dependencies: *️⃣ > 14 packages. > (okay, but could be better.) > License: ✅ > MIT. > Supported: ✅ > 2018 saw 22 commits, 6 contributors, 1 release. > Modern: ✅ > Requires Node 4+, tested with Node 10. > [email protected]: > Dependencies: ✅ > 3 packages. > License: ✅ > Apache-2.0. > Supported: ⚠️ > 2018 saw no commits or releases. > Modern: ⚠️ > Still supports Node 0.1. No visible CI or commit activity > indicating testing with recent Node releases. > [email protected]: > Dependencies: ✅ > 1 package (dependency-free). > License: ✅ > MIT. > Supported: ✅ > 2018 saw 22 commits, 3 contributors, 3 minor releases. > Modern: ✅ > Requires Node 6+, tested with Node 10. > Uses native fs.watch/recursive support where available. > [email protected]: > Dependencies: ✅ > 2 packages (1 dependency). > License: ✅ > MIT. > Supported: ⚠️ > 2018 saw no commits or releases. > Modern: ⚠️ > Last tested with Node 0.10. > Uses per-file watching and polling for all platforms. Fixes #1342.
1 parent 58fee14 commit 94fa19f

File tree

4 files changed

+37
-780
lines changed

4 files changed

+37
-780
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"commander": "2.12.2",
3535
"js-reporters": "1.2.1",
3636
"resolve": "1.5.0",
37-
"sane": "^4.0.0",
37+
"node-watch": "0.5.9",
3838
"minimatch": "3.0.4"
3939
},
4040
"devDependencies": {

src/cli/run.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -141,27 +141,24 @@ run.abort = function( callback ) {
141141
}
142142
};
143143

144-
function watcherEvent( event, args ) {
145-
return ( file ) => {
146-
console.log( `File ${event}: ${file}` );
147-
run.restart( args );
148-
};
149-
}
150-
151144
run.watch = function watch() {
152-
const sane = require( "sane" );
145+
const watch = require( "node-watch" );
153146
const args = Array.prototype.slice.call( arguments );
154-
155-
const watcher = sane( process.cwd(), {
156-
globs: [ "**/*.js" ],
157-
ignored: IGNORED_GLOBS
147+
const baseDir = process.cwd();
148+
149+
const watcher = watch( baseDir, {
150+
persistent: true,
151+
recursive: true,
152+
delay: 0,
153+
filter: ( fullpath ) => {
154+
return !/\/node_modules\//.test( fullpath ) &&
155+
/\.js$/.test( fullpath );
156+
}
157+
}, ( event, fullpath ) => {
158+
console.log( `File ${event}: ${path.relative( baseDir, fullpath )}` );
159+
run.restart( args );
158160
} );
159161

160-
watcher.on( "ready", () => run.apply( null, args ) );
161-
watcher.on( "change", watcherEvent( "changed", args ) );
162-
watcher.on( "add", watcherEvent( "added", args ) );
163-
watcher.on( "delete", watcherEvent( "removed", args ) );
164-
165162
function stop() {
166163
console.log( "Stopping QUnit..." );
167164

@@ -173,6 +170,12 @@ run.watch = function watch() {
173170

174171
process.on( "SIGTERM", stop );
175172
process.on( "SIGINT", stop );
173+
174+
// initial run must be delayed by at least 200ms
175+
// https://github.com/yuanchuan/node-watch/issues/71
176+
setTimeout( () => {
177+
run.apply( null, args );
178+
}, 210 );
176179
};
177180

178181
module.exports = run;

test/cli/fixtures/expected/watch-tap-outputs.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ok 1 foo
1515
# skip 0
1616
# todo 0
1717
# fail 0
18-
File changed: watching/foo.js
18+
File update: watching/foo.js
1919
Restarting...
2020
TAP version 13
2121
ok 1 bar
@@ -33,7 +33,7 @@ ok 1 foo
3333
# skip 0
3434
# todo 0
3535
# fail 0
36-
File added: watching/bar.js
36+
File update: watching/bar.js
3737
Restarting...
3838
TAP version 13
3939
ok 1 bar
@@ -53,7 +53,7 @@ ok 2 foo
5353
# skip 0
5454
# todo 0
5555
# fail 0
56-
File removed: watching/bar.js
56+
File remove: watching/bar.js
5757
Restarting...
5858
TAP version 13
5959
ok 1 foo
@@ -65,7 +65,7 @@ ok 1 foo
6565
Stopping QUnit...`,
6666

6767
"change-file-mid-run": `TAP version 13
68-
File changed: watching/bar.js
68+
File update: watching/bar.js
6969
Finishing current test and restarting...
7070
ok 1 Foo > one
7171
1..2
@@ -90,8 +90,8 @@ ok 1 Module > Test
9090
# skip 0
9191
# todo 0
9292
# fail 0
93-
File changed: watching/tests/foo.js
94-
File added: watching/bar.js
93+
File update: watching/tests/foo.js
94+
File update: watching/bar.js
9595
Restarting...
9696
TAP version 13
9797
ok 1 Module > Test
@@ -100,7 +100,7 @@ ok 1 Module > Test
100100
# skip 0
101101
# todo 0
102102
# fail 0
103-
File changed: watching/bar.js
103+
File update: watching/bar.js
104104
Restarting...
105105
TAP version 13
106106
ok 1 Module > Test

0 commit comments

Comments
 (0)