forked from rollup/rollup
/
fileWatcher.ts
66 lines (60 loc) · 1.99 KB
/
fileWatcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import chokidar, { FSWatcher } from 'chokidar';
import { platform } from 'os';
import { ChangeEvent, ChokidarOptions } from '../rollup/types';
import { Task } from './watch';
export class FileWatcher {
private chokidarOptions: ChokidarOptions;
private task: Task;
private transformWatchers = new Map<string, FSWatcher>();
private watcher: FSWatcher;
constructor(task: Task, chokidarOptions: ChokidarOptions) {
this.chokidarOptions = chokidarOptions;
this.task = task;
this.watcher = this.createWatcher(null);
}
close() {
this.watcher.close();
for (const watcher of this.transformWatchers.values()) {
watcher.close();
}
}
unwatch(id: string) {
this.watcher.unwatch(id);
const transformWatcher = this.transformWatchers.get(id);
if (transformWatcher) {
this.transformWatchers.delete(id);
transformWatcher.close();
}
}
watch(id: string, isTransformDependency: boolean) {
if (isTransformDependency) {
const watcher = this.transformWatchers.get(id) || this.createWatcher(id);
watcher.add(id);
this.transformWatchers.set(id, watcher);
} else {
this.watcher.add(id);
}
}
private createWatcher(transformWatcherId: string | null): FSWatcher {
const task = this.task;
const isLinux = platform() === 'linux';
const isTransformDependency = transformWatcherId !== null;
const handleChange = (id: string, event: ChangeEvent) => {
const changedId = transformWatcherId || id;
if (isLinux) {
// unwatching and watching fixes an issue with chokidar where on certain systems,
// a file that was unlinked and immediately recreated would create a change event
// but then no longer any further events
watcher.unwatch(changedId);
watcher.add(changedId);
}
task.invalidate(changedId, {isTransformDependency, event});
};
const watcher = chokidar
.watch([], this.chokidarOptions)
.on('add', id => handleChange(id, 'create'))
.on('change', id => handleChange(id, 'update'))
.on('unlink', id => handleChange(id, 'delete'));
return watcher;
}
}