tsconfig.json的include比exclude更关键,因tsserver索引仅依据include加载ast,exclude仅作用于类型检查;未配置include时会暴力扫描全项目(如monorepo从8秒飙升至217秒),必须显式列出源码路径并禁用autoimports等冗余功能。

“正在解析工作区”卡住,不是提示,是 tsserver 正在暴力扫描整个项目树——尤其当 tsconfig.json 没配 include、node_modules 又在工作区根目录时,它会真去读 10 万+ 文件。
为什么 tsconfig.json 的 include 比 exclude 更关键
tsserver 的索引行为只认 include:没写进这个数组的路径,它压根不会加载 AST;而 exclude 只影响类型检查阶段,对初始解析毫无约束力。实测一个含 node_modules/.pnpm 子目录的 monorepo,删掉 include 后首次打开耗时从 8 秒飙升到 217 秒。
-
include必须显式列出源码路径,例如:["src/**/*", "types/**/*", "test/**/*"] - 不要留空或只写
["**/*.ts"]——这等于全量扫描 - 如果项目用
projectReferences,每个子项目的tsconfig.json都要单独配include - 删掉
files字段(如果存在),它和include冲突且优先级更高
files.watcherExclude 必须用 **/xxx/** 而非 **/xxx
VSCode 的文件监视器(chokidar)对路径匹配极敏感。写成 "**/node_modules" 只能排除顶层 node_modules,像 packages/foo/node_modules 这类嵌套目录仍会被递归监听,触发 inotify 句柄耗尽或 CPU 拉满。
- 正确写法:
"**/node_modules/**": true、"**/dist/**": true、"**/.git/**": true - 必须加末尾
/**,否则匹配失效 - Linux 用户顺手检查:
cat /proc/sys/fs/inotify/max_user_watches,低于524288就执行echo 524288 | sudo tee /proc/sys/fs/inotify/max_user_watches - 这个配置要放在
.vscode/settings.json(工作区级)而非用户级,避免影响其他项目
禁用 autoImports 和 includePackageJsonAutoImports 能砍掉 30%+ 初始化时间
这两个功能会让 tsserver 主动解析 package.json 里的 dependencies,再挨个加载 @types/xxx 包的声明文件——哪怕你根本没 import 过它们。中大型项目里,光是 @types/node + @types/react 就能触发上万行 AST 构建。
- 在
.vscode/settings.json中设:"typescript.suggest.autoImports": false - 同时设:
"typescript.preferences.includePackageJsonAutoImports": "off"(注意不是"auto") - 别信文档说的“默认 off”——某些 VSCode 版本或扩展(如 TypeScript Hero)会偷偷改回
"auto" - 改完后重启 VSCode,观察进程列表里
tsserver的内存占用是否明显回落
真正卡住的点往往不在表面配置,而在 include 是否覆盖了所有实际用到的源码、**/xxx/** 的斜杠是否写全、以及有没有某个扩展(比如 Pylance 或 Vue Server)在后台悄悄启动自己的语言服务并抢走文件监听权。这些细节不手动验证,光清缓存或禁用扩展都只是治标。











