附加失败基本可确定是node.js进程未暴露调试端口,必须用--inspect或--inspect-brk启动;vscode的attach配置中port和address须与实际监听端口及ip严格一致,且不能含program字段。

VSCode 附加到正在运行的 Node.js 进程失败,基本可以确定是进程没暴露调试端口,或者 VSCode 根本连不到那个端口——不是配置写错了,而是目标进程压根没进调试状态。
node 进程没加 --inspect 参数,attach 必然失败
你手动在终端执行 npm start 或 node server.js,默认不会开启调试能力。VSCode 的 “Attach to Process” 功能依赖进程已监听 localhost:9229(或自定义端口)上的 WebSocket 调试协议,没开就等于门关着,VSCode 敲门也没用。
- 验证方式:在终端运行
curl http://localhost:9229/json,返回空或Connection refused就说明没开调试 - 正确启动方式:改用
node --inspect-brk server.js(断在第一行)或node --inspect server.js(不中断) - 如果用 npm script,必须显式写进命令里,例如:
"scripts": {"debug": "node --inspect-brk server.js"}
launch.json 中 attach 配置必须匹配实际端口和地址
即使进程开了 --inspect,VSCode 的 attach 配置若与实际不符,也会静默失败或报 Cannot connect to the target。
-
port字段必须和进程启动时指定的一致(默认 9229,但--inspect=3001就得填 3001) -
address默认"localhost",若进程绑定了0.0.0.0或其他 IP,这里也得同步改 - 不要填
webRoot或outFiles——attach 场景下这些对连接无影响,反而可能干扰 sourceMap 解析 - 示例最小可用配置:
{
"type": "node",
"request": "attach",
"name": "Attach to Process",
"port": 9229,
"address": "localhost",
"restart": true
}
常见干扰项:进程被 fork、cluster 或 pm2 启动
这些场景下,主进程可能开了调试端口,但真正处理请求的是子进程,而子进程默认不继承 --inspect 参数。
- pm2:必须加
--node-args="--inspect=9230",且 attach 时要选对子进程 PID(不是 pm2 进程本身) - cluster 模式:每个 worker 需单独启用调试,例如在 fork 时传
{ execArgv: ['--inspect=9231'] },然后为每个端口建独立 attach 配置 - child_process.fork:同理,需显式传
execArgv,否则子进程无调试能力 - VSCode 不会自动发现并 attach 所有子进程——
autoAttachChildProcesses只对request: "launch"有效,对 attach 无效
为什么选中进程后断点还是空心圆
成功 attach 后断点变空心(Unverified breakpoint),说明 VSCode 找到了进程、连上了调试器,但源码路径和运行时 JS 文件路径对不上。
- 检查
program字段是否存在于 attach 配置中——它不该出现,attach 不需要program,留着反而触发校验逻辑 - 确认你打开的 .ts/.js 文件,和进程实际加载的文件路径完全一致(注意 symlinks、软链接、构建产物路径)
- TypeScript 项目务必确保
sourceMaps已启用且.map文件存在;若用 ts-node,建议直接用 launch 模式而非 attach - Windows 下路径大小写敏感性低,但 VSCode 调试器仍可能因大小写不一致拒绝绑定
最易被忽略的一点:attach 是“事后介入”,它不控制进程启动参数、不生成 sourceMap、也不重载代码——所有依赖都得在 attach 前就位。一旦路径或 map 错一位,断点就只是个红圈。











