插件卡在node_modules里是因为语言服务器类插件默认递归扫描整个工作区,而node_modules含数万文件且含大量.d.ts、.map等触发反复解析;必须同步配置files.watcherExclude(如"/node_modules/")与插件专属忽略规则(如.eslintrc.js的ignorePatterns、tsconfig.json的exclude),并重启VS Code生效。

为什么插件会卡在 node_modules 里?
很多插件(尤其是语言服务器类,如 ESLint、Prettier、typescript-language-server)启动后会递归扫描工作区文件。一旦你打开的是项目根目录,而 node_modules 就在旁边,它们默认就会把几万个小文件全读进内存——不是插件写得差,是它根本没被告诉“别碰这儿”。
- VS Code 的文件监听器(file watcher)和插件的 LSP 初始化共享同一套路径遍历逻辑
-
node_modules中大量.d.ts、.map、package.json文件会触发插件反复解析,拖慢激活速度 - 即使你禁用了某个插件,只要它声明了
onFolderOpen或workspaceContains激活事件,仍可能提前加载并扫描
files.watcherExclude 必须配,但不能只配 **/node_modules/**
单写一条 "**/node_modules/**": true 远不够。VS Code 的 watcher 是“白名单式”行为:它先列出所有子目录,再逐个比对 exclude 规则。如果规则太粗,匹配失败仍会触发监听;如果漏掉常见干扰项,CPU 就会持续飙高。
- 必须同步排除:
"**/.git/**"(Git 状态监听开销极大)、"**/dist/**"、"**/build/**"、"**/coverage/**" - 日志类文件也要加:
"**/*.log"、"**/yarn-debug.log"、"**/pnpm-debug.log" - 注意语法:
**/node_modules/**匹配子目录,**/node_modules不匹配(少一个/**就失效) - 建议与项目
.gitignore保持一致——可用脚本自动生成:npx gitignore-to-vscode
插件自身路径控制:不是所有插件都听 files.watcherExclude
像 ESLint、Stylelint 这类基于 CLI 的插件,会绕过 VS Code 的 watcher,直接调用本地 eslint 命令。此时 files.watcherExclude 完全无效,真正起作用的是它们自己的配置文件。
-
ESLint插件依赖.eslintrc.*中的ignorePatterns字段,例如:["dist/", "node_modules/", "*.min.js"] -
Prettier需要.prettierignore(不是.prettier.config.js里的注释),内容格式同.gitignore -
typescript-language-server通过tsconfig.json的exclude控制,不是include——漏写exclude会导致它扫描整个node_modules/@types - 某些插件(如
GitLens)甚至有独立设置:gitlens.advanced.fileWatcher,需手动关掉
路径配置失效的典型现象和验证方式
改完配置却没效果?大概率是路径没生效,而不是插件本身有问题。最直接的验证方式不是看“有没有卡”,而是看“它到底扫了哪些路径”。
- 打开命令面板 →
Developer: Open Process Explorer→ 查看Extension Host进程的 CPU 和文件句柄数,变化明显说明生效 - 右键 →
Developer: Toggle Developer Tools→ Console 标签页,搜索watcher或glob,能看到实际监听路径列表 - 保存
settings.json后,务必重启 VS Code(不是 Reload Window),因为 watcher 在启动时初始化,热重载不刷新 - 常见失效原因:
settings.json写在用户级而非工作区级;工作区启用了Workspace Trust但没允许扩展访问文件系统;插件版本过旧不支持新 exclude 语法
files.watcherExclude 和对应插件的 ignore 文件,并用 Process Explorer 快速确认。



















