Skip to content

Commit e71b62b

Browse files
authored
Merge pull request #197 from markjm/markjm/watch-change
Allow function in `watchOptions.ignored`
2 parents 523793e + b308647 commit e71b62b

4 files changed

Lines changed: 42 additions & 18 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ var wp = new Watchpack({
4949
// ignored: "string" - a glob pattern for files or folders that should not be watched
5050
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
5151
// ignored: /regexp/ - a regular expression for files or folders that should not be watched
52+
// ignored: (entry) => boolean - an arbitrary function which must return truthy to ignore an entry
53+
// For all cases expect the arbitrary function the path will have path separator normalized to '/'.
5254
// All subdirectories are ignored too
5355
});
5456

lib/DirectoryWatcher.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class DirectoryWatcher extends EventEmitter {
7171
this.directories = new Map();
7272
this.lastWatchEvent = 0;
7373
this.initialScan = true;
74-
this.ignored = options.ignored;
74+
this.ignored = options.ignored || (() => false);
7575
this.nestedWatching = false;
7676
this.polledWatching =
7777
typeof options.poll === "number"
@@ -96,12 +96,6 @@ class DirectoryWatcher extends EventEmitter {
9696
this.doScan(true);
9797
}
9898

99-
checkIgnore(path) {
100-
if (!this.ignored) return false;
101-
path = path.replace(/\\/g, "/");
102-
return this.ignored.test(path);
103-
}
104-
10599
createWatcher() {
106100
try {
107101
if (this.polledWatching) {
@@ -178,7 +172,7 @@ class DirectoryWatcher extends EventEmitter {
178172
setFileTime(filePath, mtime, initial, ignoreWhenEqual, type) {
179173
const now = Date.now();
180174

181-
if (this.checkIgnore(filePath)) return;
175+
if (this.ignored(filePath)) return;
182176

183177
const old = this.files.get(filePath);
184178

@@ -237,7 +231,7 @@ class DirectoryWatcher extends EventEmitter {
237231
}
238232

239233
setDirectory(directoryPath, birthtime, initial, type) {
240-
if (this.checkIgnore(directoryPath)) return;
234+
if (this.ignored(directoryPath)) return;
241235
if (directoryPath === this.path) {
242236
if (!initial) {
243237
this.forEachWatcher(this.path, w =>
@@ -398,7 +392,7 @@ class DirectoryWatcher extends EventEmitter {
398392
}
399393

400394
const filePath = path.join(this.path, filename);
401-
if (this.checkIgnore(filePath)) return;
395+
if (this.ignored(filePath)) return;
402396

403397
if (this._activeEvents.get(filename) === undefined) {
404398
this._activeEvents.set(filename, false);

lib/watchpack.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,28 @@ const stringToRegexp = ignored => {
4141
return matchingStart;
4242
};
4343

44-
const ignoredToRegexp = ignored => {
44+
const ignoredToFunction = ignored => {
4545
if (Array.isArray(ignored)) {
46-
return new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
46+
const regexp = new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
47+
return x => regexp.test(x.replace(/\\/g, "/"));
4748
} else if (typeof ignored === "string") {
48-
return new RegExp(stringToRegexp(ignored));
49+
const regexp = new RegExp(stringToRegexp(ignored));
50+
return x => regexp.test(x.replace(/\\/g, "/"));
4951
} else if (ignored instanceof RegExp) {
52+
return x => ignored.test(x.replace(/\\/g, "/"));
53+
} else if (ignored instanceof Function) {
5054
return ignored;
5155
} else if (ignored) {
5256
throw new Error(`Invalid option for 'ignored': ${ignored}`);
5357
} else {
54-
return undefined;
58+
return () => false;
5559
}
5660
};
5761

5862
const normalizeOptions = options => {
5963
return {
6064
followSymlinks: !!options.followSymlinks,
61-
ignored: ignoredToRegexp(options.ignored),
65+
ignored: ignoredToFunction(options.ignored),
6266
poll: options.poll
6367
};
6468
};
@@ -192,9 +196,7 @@ class Watchpack extends EventEmitter {
192196
const fileWatchers = this.fileWatchers;
193197
const directoryWatchers = this.directoryWatchers;
194198
const ignored = this.watcherOptions.ignored;
195-
const filter = ignored
196-
? path => !ignored.test(path.replace(/\\/g, "/"))
197-
: () => true;
199+
const filter = path => !ignored(path);
198200
const addToMap = (map, key, item) => {
199201
const list = map.get(key);
200202
if (list === undefined) {

test/Watchpack.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,32 @@ describe("Watchpack", function() {
118118
});
119119
});
120120

121+
it("should not watch a single ignored file (function)", function(done) {
122+
var w = new Watchpack({
123+
aggregateTimeout: 300,
124+
ignored: (entry) => entry.includes("a")
125+
});
126+
var changeEvents = 0;
127+
var aggregatedEvents = 0;
128+
w.on("change", () => {
129+
changeEvents++;
130+
});
131+
w.on("aggregated", () => {
132+
aggregatedEvents++;
133+
});
134+
w.watch([path.join(fixtures, "a")], []);
135+
testHelper.tick(() => {
136+
testHelper.file("a");
137+
testHelper.tick(1000, () => {
138+
changeEvents.should.be.eql(0);
139+
aggregatedEvents.should.be.eql(0);
140+
testHelper.getNumberOfWatchers().should.be.eql(0);
141+
w.close();
142+
done();
143+
});
144+
});
145+
});
146+
121147
it("should watch multiple files", function(done) {
122148
var w = new Watchpack({
123149
aggregateTimeout: 1000

0 commit comments

Comments
 (0)