program字段必须用${workspacefolder}拼接为workspace-relative路径,如"${workspacefolder}/packages/api/src/index.js",并显式设置cwd指向对应package目录,否则报cannot find module。

launch.json 的 program 字段必须用 ${workspaceFolder} 拼路径
VS Code 调试器在 monorepo 中启动插件子包时,program 字段不能写 "src/extension.ts" 这类相对路径,否则会报 Cannot find module 或直接退出。根本原因是调试器不按当前文件位置解析路径,而是以 cwd 为基准——而默认 cwd 是 workspace 根目录,不是你正在编辑的 package 目录。
正确做法是显式拼出 workspace-relative 路径:
"program": "${workspaceFolder}/packages/my-extension/src/extension.ts"- 同时必须配
"cwd": "${workspaceFolder}/packages/my-extension",确保require()能找到本地依赖(比如packages/utils)和node_modules - 如果子包用了 ESM + TypeScript,
runtimeExecutable得设为"tsx"或"ts-node --esm",不能直接用"node"
本地 package 依赖断点失效,是因为 source map 没覆盖到
你能在 my-extension 打断点,但跳进 packages/core 就停不住,变量也看不到——这不是路径问题,是调试器压根没加载对应源码的 source map。
常见错误是只在主包生成 lib/**/*.js,却没告诉调试器去哪找其他包的产物:
- 在
my-extension的launch.json中加"outFiles": ["${workspaceFolder}/packages/*/lib/**/*.js"] - 确保所有被依赖的包都已构建(
pnpm build),且tsconfig.json启用了"sourceMap": true和"inlineSources": true - 禁用
ts-node或tsx的--transpile-only模式,否则 source map 会被丢弃
多插件同时调试时 inspector 端口冲突
VS Code 默认所有 Node 进程都尝试绑定 9229,启动第二个插件调试时就会卡住或报 address already in use,断点只在一个进程生效。
每个插件调试配置必须独立指定端口,并启用子进程自动附加:
-
"port": 9230(第一个插件)、"port": 9231(第二个)、依此类推 - 加
"autoAttachChildProcesses": true,避免插件内部fork()或spawn()出的子进程脱离调试上下文 - 如果用了
nodemon或ts-node-dev,关掉它们的热重载功能,改用 VS Code 的preLaunchTask触发构建,否则调试器会反复 detach/attach
.code-workspace 文件里的 path 必须相对于它自身位置
你在 ~/my-monorepo/monorepo.code-workspace 里写 "path": "./packages/my-extension",但实际该文件放在 ~/my-monorepo 外层,VS Code 就会静默忽略这个条目——资源管理器里少一个文件夹,Ctrl+P 也搜不到。
路径解析不认 ~、${env:HOME} 或任何环境变量,只认绝对路径或相对于 .code-workspace 文件所在目录的相对路径:
- 推荐统一用绝对路径,例如
/Users/you/my-monorepo/packages/my-extension - 确认
.code-workspace文件保存后,VS Code 顶部显示的是“工作区:monorepo.code-workspace”,而不是“文件夹:/xxx”嵌套更深的路径 - 多根工作区不会自动合并各子包的
.vscode/launch.json;你按 F5 时,VS Code 只读当前活动文件所在根目录下的配置
最常被忽略的一点:改完 tsconfig.json 或重装依赖后,VS Code 不会自动刷新 TypeScript Server。你看到的跳转失败、类型报错,大概率只是 TS Server 还在用旧快照——务必手动执行 Developer: Restart TS Server。











