必须用根目录打开monorepo,否则跨包跳转、类型提示、自动导入全部失效;需确保pnpm-workspace.yaml存在且合法,tsconfig分层配置references和composite: true,并手动重启TS Server。

必须用根目录打开,否则所有跳转都失效
VSCode 本身不识别 monorepo 结构,它只认你打开的文件夹路径。如果你在 packages/ui 里执行 code .,TS Server 就只加载这一个包,node_modules 里没有其他本地包的符号链接,tsconfig.json 的 paths 映射也找不到目标——所有跨包跳转、自动导入、类型提示都会断掉。
检查方法:看资源管理器顶部显示的是“文件夹:/my-monorepo”还是“文件夹:/my-monorepo/packages/ui”。前者正确,后者就是错的。状态栏右下角应显示 “TypeScript SDK: Workspace version”,若显示 “Project version” 或路径指向子包内的 node_modules/.pnpm/,说明识别失败。
- 退出当前窗口,回到最外层目录(含
pnpm-workspace.yaml或nx.json的那个)再执行code . -
pnpm-workspace.yaml必须存在且合法,例如:packages: ["packages/*", "apps/*"] - 多根工作区(.code-workspace)也可用,但必须把根目录作为第一个
folder,不能只加子包
tsconfig 需分层配 references + composite
TypeScript 默认把每个 tsconfig.json 当独立项目处理。monorepo 要让它理解“这些包之间有依赖关系”,就得靠 references 和 composite: true 显式声明。缺一不可,否则即使路径映射对了,跳转仍可能卡在构建产物里。
根目录(如 tsconfig.base.json)需设:
"compilerOptions": {
"baseUrl": ".",
"paths": {
"my-utils": ["packages/my-utils/src"],
"@shared/*": ["packages/shared/src/*"]
}
}
每个子包(如 packages/my-utils/tsconfig.json)必须:
- 包含
"composite": true -
"extends": "../tsconfig.base.json"(路径要对) - 根
tsconfig.json中显式列出所有子包:"references": [{ "path": "packages/my-utils" }, { "path": "apps/web" }]
改完配置后必须重启 TS Server
VSCode 不会自动刷新 TypeScript 语言服务。你看到的“无法找到模块”“跳转到 node_modules/my-utils 而不是源码”,大概率只是 TS Server 还在用旧快照。缓存没清,配得再准也没用。
- 按
Ctrl+Shift+P→ 输入TypeScript: Restart TS Server手动触发 - 删掉所有子包下的
node_modules和锁文件(pnpm-lock.yaml等),再跑pnpm install - 如果用了
.vscode缓存,可顺手删掉整个.vscode目录再重开
插件不自动适配多根,得手动开开关
很多插件(比如 Path Autocomplete、Typescript Import Sorter)默认只扫描当前激活根目录,不会主动跨文件夹查 node_modules 或 src。它们不是不支持,而是默认关着。
-
Path Autocomplete:必须开启path-autocomplete.showFilesFromAllRoots -
ESLint插件:确保eslint.workingDirectories设为[{ "mode": "auto" }],否则只在第一个根目录跑 - 自己写插件时,绝不能硬编码
${workspaceFolder};必须用vscode.workspace.getWorkspaceFolder(uri)动态获取目标文件所属根目录
真正跨项目联动的关键,从来不是插件有多“智能”,而是你有没有让 TypeScript 解析路径、VSCode 加载上下文、插件读取范围三者对齐。漏掉任何一环,跳转就会在某个环节静默失败——而且往往不报错,只让你反复怀疑是不是快捷键按错了。


















