-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdevelopment.ts
101 lines (93 loc) · 3.02 KB
/
development.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { debuglog } from 'node:util';
import path from 'node:path';
import fs, { FSWatcher, WatchEventType } from 'node:fs';
import { BaseEventSource } from './base.js';
import type { ChangeInfo } from '../types.js';
const debug = debuglog('@eggjs/watcher/lib/event-sources/development');
// only used by local dev environment
export default class DevelopmentEventSource extends BaseEventSource {
#fileWatching = new Map<string, FSWatcher>();
constructor() {
super();
this.ready(true);
}
watch(file: string) {
try {
const stat = fs.statSync(file, { throwIfNoEntry: false });
if (!stat) {
debug('watch %o ignore, file not exists', file);
return;
}
debug('watch %o, isFile: %o', file, stat.isFile());
// https://nodejs.org/docs/latest/api/fs.html#fswatchfilename-options-listener
let recursive = true;
if (process.platform === 'linux' && process.version.startsWith('v18.')) {
// https://github.com/fgnass/filewatcher/pull/6
// disable recursive on linux + Node.js <= 18
recursive = false;
}
const handler = fs.watch(file, {
persistent: true,
recursive,
}, (event, filename) => {
debug('watch %o => event: %o, filename: %o', file, event, filename);
let changePath = file;
if (stat.isFile()) {
this.#onFsWatchChange(event, changePath);
} else {
// dir
if (filename) {
changePath = path.join(file, filename);
}
this.#onFsWatchChange(event, changePath);
}
});
// 保存 handler,用于解除监听
this.#fileWatching.set(file, handler);
} catch (e) {
// file not exist, do nothing
// do not emit error, in case of too many logs
this.emit('warn', '[@eggjs/watcher:DevelopmentEventSource] watch %o error: %s', file, e);
}
}
unwatch(file: string) {
if (!file) return;
const h = this.#fileWatching.get(file);
if (!h) return;
// fs.watch 文件监听
h.removeAllListeners();
h.close();
this.#fileWatching.delete(file);
}
#onFsWatchChange(event: WatchEventType, file: string) {
if (!file) {
this.emit('warn', '[@eggjs/watcher:DevelopmentEventSource] event: %o', event);
return;
}
// { event: 'change',
// path: '/Users/mk2/git/changing/test/fixtures/foo.js',
// stat:
// { dev: 16777220,
// mode: 33188,
// nlink: 1,
// uid: 501,
// gid: 20,
// rdev: 0,
// blksize: 4096,
// ino: 72656587,
// size: 11,
// blocks: 8,
// atime: Wed Jun 17 2015 00:08:11 GMT+0800 (CST),
// mtime: Wed Jun 17 2015 00:08:38 GMT+0800 (CST),
// ctime: Wed Jun 17 2015 00:08:38 GMT+0800 (CST),
// birthtime: Tue Jun 16 2015 23:19:13 GMT+0800 (CST) } }
const stat = fs.statSync(file, { throwIfNoEntry: false });
const info = {
path: file,
event,
stat,
isDirectory: stat?.isDirectory(),
} as ChangeInfo;
this.emit('change', info);
}
}