VSCode插件调试CPU爆表主因是files.watcherExclude未生效,必须用"/node_modules/": true格式写入项目级.vscode/settings.json并完全重启窗口,同时配齐search.exclude和调高Linux的inotify.max_user_watches。

VSCode 插件调试时 CPU 爆表,八成不是插件写得烂,而是文件监听没拦住 node_modules —— 你改的 files.watcherExclude 很可能根本没生效。
为什么 files.watcherExclude 配了却没用
常见错误写法:"node_modules/**"、"*/node_modules/*"、"node_modules",这些通配符 VSCode 全部忽略,不报错也不警告,等于白写。
真正生效的只有一种格式:"**/node_modules/**": true。双星号开头 + 双星号结尾是硬性要求,它表示“匹配任意深度路径下的该子目录及其全部内容”。
- 必须写在项目根目录下的
.vscode/settings.json中,用户级设置(如~/Library/Application Support/Code/User/settings.json)对多项目无效 - 改完保存后,必须关闭并重新打开整个工作区窗口,仅“重载窗口”或“刷新”不会加载新规则
- 如果项目用了
.gitignore,建议把里面所有路径(如dist、build、__pycache__)都同步加进files.watcherExclude
code --status 是唯一靠谱的排查入口
别猜哪个插件在吃 CPU,先跑这行命令:
code --status
它会直接列出所有子进程的实时占用,重点关注两行:
-
Extension Host持续 >70% CPU:说明某个插件的监听回调正在堆积,大概率是未排除的目录触发了海量chokidar事件 -
Search进程内存 >300MB:基本可断定rg.exe(RipGrep)正在暴力扫描node_modules或符号链接目录
拿到 PID 后,用 ps -p [PID] -o comm=(macOS/Linux)确认实际命令名,比如 tsserver 或 node /path/to/pylance,才能精准定位问题源头。
Linux 下 inotify 句柄耗尽会静默失败
VSCode 文件监视底层依赖系统 inotify,而 Linux 默认 max_user_watches 常为 8192。一个中等前端项目的 node_modules 就能轻松干掉它。
后果不是报错,而是 watcher 反复重建、事件丢失、Git 状态不更新、保存延迟——CPU 可能不高,但编辑体验已崩。
- 查当前值:
cat /proc/sys/fs/inotify/max_user_watches - 临时调高:
echo 524288 | sudo tee /proc/sys/fs/inotify/max_user_watches - 永久生效需写入
/etc/sysctl.conf并执行sudo sysctl -p
注意:这个限制和 files.watcherExclude 是两回事——前者是系统资源上限,后者是 VSCode 的过滤逻辑,缺一不可。
search.exclude 和 files.watcherExclude 必须配齐
很多人只配了 files.watcherExclude,忘了 search.exclude。结果是:文件不监听了,但按 Cmd+Shift+F 搜索时,rg.exe 仍会把 node_modules 当普通文本暴力遍历,瞬间吃光 I/O 和内存。
两者配置结构一致,但作用域完全独立:
-
files.watcherExclude:关掉文件系统变更通知(影响 Git 状态、自动保存响应等) -
search.exclude:关掉全文搜索范围(影响Cmd+Shift+F、Cmd+P文件跳转等)
示例配置(均需写入项目级 .vscode/settings.json):
{
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.git/**": true,
"**/dist/**": true,
"**/build/**": true
},
"search.exclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/build/**": true,
"**/*.log": true
}
}
最常被忽略的一点:search.exclude 的路径值里,**/node_modules/** 和 **/node_modules 效果不同——后者不匹配子目录下的嵌套 node_modules(比如 packages/foo/node_modules),必须带尾部 /** 才完整。



















