开发工具

VSCode 断点调试上手:从 launch.json 到鼠标停在变量上

比起到处 console.log,断点调试能让你停下来看到函数调用栈、每一步的变量值。本文从改 launch.json 开始,带你把 Node/前端项目的调试跑起来,并讲清边栏、watch 与条件断点的用法。

作者:巧匠团队·7 分钟阅读·更新于 2026-09-06

什么是断点调试,它和 console.log 差在哪

console.log 只能在你预判到的地方打印,调试一次要跑一遍程序,改一行再跑一遍。断点调试则是让程序在可疑代码处暂停,此时你可以观察所有作用域内的变量、查看函数调用栈、逐行前进,根本不用预先把什么值打进日志。

对复杂业务尤其划算:一个值在多个函数间传递时,你能顺着调用栈看到它从哪来、哪里被覆盖。VSCode 内置调试器,Node、浏览器、Python、Go 等都有对应扩展,但核心入口都是同一个 .vscode/launch.json。

// .vscode/launch.json —— 最小可用配置
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "启动当前文件",
      "program": "${file}"
    }
  ]
}

把 Node 和前端项目的调试跑起来

Node 场景最常见的坑是"我明明加了断点,怎么不触发"。原因通常是入口跑的不是你加断点的文件:用 启动当前文件 并确保 program 指向正确,或者直接配置 npm script 形式。

前端(Vite/Webpack)需要额外的 source map 才能把网关编译后的代码映射回源码。启动方式是用 launch config 先启动浏览器调试(pwa-chrome 打开 URL),再加上 webServer 或直接 attach 到已有的 dev server。附加 vs 启动的区别:request 为 launch 表示由调试器拉起进程,attach 表示连到已在运行的进程。

{
  "type": "pwa-chrome",
  "request": "launch",
  "name": "调试 Vite",
  "url": "http://localhost:5173",
  "webRoot": "${workspaceFolder}/src",
  "sourceMapPathOverrides": {
    "webpack:///./src/*": "${webRoot}/*"
  }
}

打断点后的五个动作:继续、单步、迈过、跳出、重启

断点命中后,顶部调试工具栏提供几个关键动作:继续(F5)跑到下一个断点,单步进入(F11)进入被调用函数,迈过(F10)执行当前行不进入函数,跳出(Shift+F11)跑完整个函数返回调用处,以及重启/停止。

看清这三个的区别是调试内功:单步进入会带你掉进当前行的函数内部,适合排查函数内部逻辑;迈过执行整行一次,适合只看本层流程;跳出则快速结束当前函数看它到底返回了什么值再回到上一层落脚点。

若在条件判断处想跳到自定义分支,可临时给断点设条件,或用"跳转到光标处"(右键→Jump to Cursor)把执行指针直接移到目标行,省去一次次 F5。按键可以到键盘快捷键面板改,但默认这套已够覆盖 90% 场景。

F5            继续 / 开始调试
F10           迈过(不进入被调函数)
F11           单步进入(进入被调函数)
Shift + F11    跳出当前函数
Shift + F5     停止调试
右键行号 -> Add Conditional Breakpoint  条件断点

边栏、变量与 Watch:不打印也能看清值

调试边栏有三个面板:Variables 显示当前作用域所有变量及当前值,Watch 让你手动固定几个表达式持续观察,而 CALL STACK 展示函数调用链,配合"函数参数往哪传"最容易定位值被谁改了。

在 Variables 面板里,对象和数组可以展开,鼠标悬停源码中的变量也能浮窗预览。要观察队列长度、计算后的中间值这种非直接变量,就在 Watch 里写表达式,如 this.items.length 或 JSON 形式更直观。条件断点(右键断点→条件)则让程序只有在满足某条件时才暂停,极大减少无谓的中断。

# Watch 表达式示例(在 WATCH 面板逐个添加)
this.items.length
JSON.stringify(this.currentRow)
Date.now() - this.startedAt   # 计算已耗时
# 条件断点:右键断点 -> "条件",输入
row.status === "PENDING"

排查"断点不生效"与"改了不生效"的四个检查点

最常见的调试卡点:一是断点处当前行根本没执行到,检查是不是走到了别的分支;二是源码映射失败,断点显示为灰色空心(未命中),说明 source map 或 webRoot 配置不对;三是改了代码但调试器仍用旧版本,Node 在用 -w 或重启前要重新启动调试会话;四是类型/路径大小写不一致导致镜像不到文件。

快速自检顺序:看断点是否实心→确认被调试进程是最新启动→确认断点文件与 program/webRoot 在同一来源→看 DEBUG CONSOLE 里是否有 source map 相关报错。通常做到前两步就能解决绝大多数"不生效"问题。

# 强制刷新窗口并确认调试进程重启方式
# Node:启动命令确认 --inspect / --watch 行为
"runtimeArgs": ["--inspect=9229", "--watch"]
# 若断点为灰色空心,检查 webRoot 是否指向源码目录

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。