直接用 fs.watch 监听目录不可靠,因其不递归、跨平台行为不一致、事件重复且 filename 常为空;应改用 chokidar——它自动适配各系统原生机制,支持稳定递归监听并处理去抖、路径规范化等细节。

直接用 fs.watch 监听指定目录在 VSCode 里不可靠——它不递归、跨平台行为不一致、事件重复且 filename 参数常为空。真要稳定监听,得绕过原生 API,用更成熟的方案。
为什么不用 fs.watch 直接监听目录
fs.watch 在 Linux/macOS 上默认不递归,在 Windows 虽支持 recursive: true,但遇到重命名或删除重建同名文件时会丢失事件;filename 字段在多数回调中为 null,无法准确判断变更路径;编辑器(如 VSCode)保存文件时常先清空再写入,触发两次 rename 事件,逻辑极易误判。
- 监听单个文件勉强可用,监听整个目录基本不可行
- Node.js 官方文档明确标注
recursive选项“仅在部分平台受支持”,不是跨平台安全选择 - VSCode 自身的文件监视也避开了裸用
fs.watch,转而依赖chokidar封装层
用 chokidar 替代 fs.watch 实现稳定递归监听
chokidar 是目前最主流的 Node.js 文件监听库,它自动适配各系统原生机制(inotify / FSEvents / ReadDirectoryChangesW),并封装了去抖、路径规范化、符号链接处理等细节,是 VSCode 内部实际采用的底层方案之一。
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
- 安装:
npm install chokidar --save-dev - 基础用法示例(监听
src目录及其子目录):
const chokidar = require('chokidar');
const watcher = chokidar.watch('src', {
ignored: /node_modules|\.git/,
persistent: true,
depth: 99 // 防止某些深层嵌套被截断
});
watcher
.on('add', path => console.log('新增:', path))
.on('change', path => console.log('修改:', path))
.on('unlink', path => console.log('删除:', path))
.on('error', err => console.error('监听出错:', err));
-
ignored必须设,否则node_modules会拖垮进程(上万文件同时监听) - 不要依赖
event字符串做精确判断——add和change可能因编辑器保存策略混发,优先以路径 + 操作类型组合识别意图
在 VSCode 里触发监听脚本的两种实用方式
VSCode 本身不提供“保存即执行 Node 脚本”的内置通道,需通过任务(Task)或插件桥接。推荐用 tasks.json 启动长期运行的监听进程,而非每次保存都重启脚本。
- 创建
.vscode/tasks.json,内容如下:
{
"version": "2.0.0",
"tasks": [
{
"label": "watch-src",
"type": "shell",
"command": "node ./scripts/watcher.js",
"isBackground": true,
"presentation": { "echo": true, "reveal": "always", "panel": "shared" },
"group": "build",
"problemMatcher": []
}
]
}
-
isBackground: true让任务后台常驻,避免 VSCode 关闭终端就中断监听 - 别用
Ctrl+S → 触发一次脚本的模式:频繁启停 Node 进程开销大,且容易漏事件;应让监听器持续运行 - 如果想在保存时仅执行轻量操作(如复制文件),可改用 VSCode 的
files.associations+ 插件(如FileSync),但灵活性远不如chokidar自定义
性能陷阱:忽略 node_modules 和临时文件是硬性要求
没配 ignored 的 chokidar.watch('project') 在中大型项目里大概率导致 CPU 持续 80%+、内存暴涨、VSCode 卡顿甚至崩溃——这不是夸张,而是真实日志里高频出现的 EMFILE(打开文件数超限)错误根源。
- 必须排除:
node_modules、.git、dist、build、logs、*.log - VSCode 自带的
files.watcherExclude设置(影响编辑器自身 UI 响应)和chokidar的ignored互不干扰,建议两者都设 - 若监听目录含大量小文件(如图片资源目录),考虑加
awaitWriteFinish: true防止读取未写完的临时文件
真正稳定的监听不是“写个 fs.watch 就完事”,而是选对库、配对规则、跑对生命周期。chokidar 的 ignored 不是可选项,是保命线;监听脚本一旦启动,就该长期存活,而不是绑定保存动作反复拉起。










