Node.js 调试方法
Node.js 调试走的是 V8 Inspector(Chrome DevTools Protocol)。CLI、Chrome DevTools、VS Code 都是连上同一套协议的不同客户端,不必为每种工具各学一套。默认监听 127.0.0.1:9229,不要把调试端口暴露到公网。
旧命令 node debug、node --debug 已废弃,一律改用 node inspect 与 --inspect。
内置调试(node inspect 命令行客户端)
Node.js 自带进程外调试工具,通过 V8 检查器协议,用交互式命令行客户端调试代码。node inspect 会再拉起一个带 --inspect 的子进程跑脚本,主进程做 CLI。
node inspect [--port=9229] [脚本.js]
node inspect 127.0.0.1:9229
node inspect -p <pid>
--port 指定子进程监听端口;host:port 连接已经开着的检查器;-p 按 进程 ID 附加,不是端口号。启动后默认在第一行可执行代码处停下。若要先跑到 debugger; 再停,设环境变量 NODE_INSPECT_RESUME_ON_START=1。
单步执行命令
cont、c:继续执行脚本next、n:单步执行下一行(不进入函数内部)step、s:单步进入函数内部out、o:单步跳出当前函数pause:暂停正在运行的代码,等效于开发者工具暂停按钮- 空回车:重复上一条调试命令
help:列出命令
断点相关
setBreakpoint()、sb():在当前代码行设置断点setBreakpoint(line)、sb(line):在指定行号设置断点setBreakpoint('fn()')、sb(...):在函数体内第一行设置断点setBreakpoint('script.js', 1)、sb(...):在script.js文件第 1 行设置断点setBreakpoint('script.js', 1, 'num < 4')、sb(...):条件断点,仅当表达式为真时停下clearBreakpoint('script.js', 1)、cb(...):清除script.js文件第 1 行断点
未加载的模块也可以先 sb('mod.js', 22),加载到该文件时会生效。
信息查看
backtrace、bt:打印当前调用栈回溯list(5):打印脚本前后共 5 行源码上下文watch(expr):添加表达式到监视列表unwatch(expr):移除监视列表中的表达式unwatch(index):按序号移除监视表达式watchers:列出所有监视表达式与对应值,触发断点会自动打印repl:打开调试 REPL,在当前脚本上下文执行代码exec expr、p expr:在脚本调试上下文执行表达式并打印结果
现行 CLI 还支持 profile、profileEnd、profiles、takeHeapSnapshot(),用来抓 CPU 剖面和堆快照。
执行控制
run:运行脚本,调试器启动时自动执行restart:重新启动脚本kill:终止脚本执行
杂项
scripts:列出全部已加载脚本version:输出 V8 引擎版本
常见报错
Timeout (2000) waiting for 127.0.0.1:9229 to be free
该报错不完全等价于端口被占用,是 Windows 上旧版 CLI 的已知问题:系统分配调试端口有时要 3-5 秒,而旧版 node inspect 默认只等 2000ms,超时就抛这个错。
产生诱因:
- 终端没有正常退出调试会话。Unix、Git Bash 里用
Ctrl+Z会挂起进程而不是结束,后台仍占端口;Windows 终端请用Ctrl+C退出。 - Windows 端口绑定慢,超时阈值过小。
- 旧版本 Node.js /
node-inspect。
处理方案:
- 退出调试用
Ctrl+C,不要用Ctrl+Z。 - 升级 Node.js:
v12.19.0、v15.0.1起已把超时从 2000ms 提到 9999ms。现行 LTS 都已包含该修复。 - 临时改用
node --inspect-brk 脚本.js(只开 V8 检查器,不用 CLI 客户端node inspect)。 - 很旧的 Node 可全局安装独立包:
npm install -g node-inspect,再用node-inspect 脚本.js。该仓库已归档,新项目用内置node inspect即可。 - 指定其他端口启动 CLI:
node inspect --port=9230 app.js。
注意区分两条命令:
node inspect:交互式 CLI 调试客户端(旧版 Windows 上容易触发上面的超时报错)node --inspect:开启调试协议服务,供 Chrome、VS Code 等外部工具连接,不会出现该超时报错
V8 检查器(Chrome DevTools 调试)
V8 检查器协议允许 Chrome DevTools、Edge DevTools 附加到 Node.js 进程做调试和性能分析,走的是 Chrome DevTools Protocol。
# 开启调试,脚本马上跑,稍后连接
node --inspect [脚本.js]
# 指定调试端口(也可写成 host:port)
node --inspect=9229 [脚本.js]
# 连上调试器后在脚本第一行断住(最常用)
node --inspect-brk [脚本.js]
# 先等调试器连上,再开始执行(不在第一行强制断)
node --inspect-wait [脚本.js]
通过 npm 脚本、nodemon 等间接启动时,可以把旗标放进环境变量,避免改启动命令:
# Unix、Git Bash
NODE_OPTIONS=--inspect-brk npm start
# Windows PowerShell
$env:NODE_OPTIONS='--inspect-brk'; npm start
$ node --inspect-brk debug/index.js
Debugger listening on ws://127.0.0.1:9229/1dc7da88-983c-4fbe-a8e3-2d5f256e98af
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
开始调试
Chrome 地址栏输入 chrome://inspect(也可写 about:inspect),Edge 用 edge://inspect,即可看到远程目标列表。


如果目标没有自动出现,点击 Configure,手动填入 127.0.0.1:9229。点击对应目标的 inspect,弹出 DevTools 调试面板。也可点 Open dedicated DevTools for Node,打开专用窗口。
NIM(Node Inspector Manager)
每次手动打开 chrome://inspect 比较繁琐。
NIM(Node Inspector Manager) 是 Chrome、Edge 浏览器扩展,可以快速唤起 DevTools,支持自动发现 Node 调试目标。
inspect-process
不想手动操作浏览器,可用 inspect-process 包:它包一层 --inspect,自动拉起 Chrome DevTools。该包已多年未更新,日常优先用 chrome://inspect。
npm i inspect-process -g
inspect app.js
调试操作和原生 DevTools 一致。它无法给子进程自动加上 --inspect。
附加到已经运行的 Node 进程(不重启)
进程已经启动、启动时没有加 --inspect,又不想重启丢失现场时,可以事后打开检查器。
Linux、macOS 用 SIGUSR1(Windows 没有这个信号):
ps ax | grep app.js
# 或 pgrep -n node
kill -USR1 <pid>
Windows 查 PID 后,用内部 API 打开检查器:
tasklist | findstr node
node -e "process._debugProcess(53911)"
process._debugProcess(pid) 在 Windows、Unix 都可以用,传入的是目标 Node 进程的 PID。原进程会打印 websocket 调试地址,再用 chrome://inspect 连接。Node 较新版本可用 --disable-sigusr1 关掉信号打开调试的能力。
node inspect 与 node --inspect 的区别
node --inspect:启动脚本,开启远程调试 WebSocket 接口。脚本正常运行;Chrome DevTools、VS Code、JetBrains 等外部工具可以附加;终端脚本本身继续执行。node inspect:交互式 CLI 调试客户端,相当于命令行版调试器。内部会单独启动一个带--inspect的子脚本进程,客户端连上去做交互调试。
已经用 --inspect 跑起来的进程,CLI 按 地址 连,不要把端口误写成 -p:
# 终端 A:开启调试服务,脚本运行
node --inspect app.js
# 终端 B:CLI 连已开启的调试端口
node inspect 127.0.0.1:9229
# -p 是按 PID 附加,不是端口
node inspect -p <pid>
Visual Studio Code 调试
VS Code 原生内置 JavaScript 调试器(js-debug),可直接调 Node.js、Chrome、Edge。旧扩展 Debugger for Chrome 已废弃,不要再装;装了反而可能和内置调试器抢配置。
操作步骤:
- 点击左侧「运行和调试(Run and Debug)」图标,打开调试面板。
- 点击上方齿轮,生成或编辑
.vscode/launch.json。 - 在调试面板上方下拉选择对应配置项。
- 点击「开始调试」或按
F5。
也可在集成终端打开 Auto Attach(状态栏或命令面板搜 Debug: Toggle Auto Attach),之后在终端里跑的 node 进程会自动被附加。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch NodeJs",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\nodeDemo\\debug\\index.js"
},
{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:PickProcess}",
"skipFiles": [
"<node_internals>/**"
]
},
{
"name": "Launch 15-canvas入门篇.html",
"type": "chrome",
"request": "launch",
"sourceMaps": false,
"file": "${workspaceFolder}\\htmlDemo\\15-canvas入门篇.html"
}
]
}
第三条是 浏览器前端 调试示例,不是 Node 进程。


launch.json 核心配置字段说明:
{
"type": "node",
"request": "launch",
"name": "Launch NodeJs",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\nodeDemo\\debug\\index.js"
}
type(必填):调试器类型,node、chrome、msedge,都走内置js-debug。request(必填):launch:VS Code 直接启动目标脚本并调试;attach:附加到已经在运行的外部进程。
name:配置显示名称,调试下拉框可见。program:待调试脚本路径。支持变量占位符:${file}:当前打开文件;${workspaceFolder}:当前项目根目录(旧名${workspaceRoot}仍能用,新配置写 Folder)。
Windows 路径可用双反斜杠 \\,也可以写正斜杠 /(VS Code 在 Windows 上同样认)。
通用常用附加配置:
stopOnEntry:启动调试后是否在第一行自动断住;args:传给被调试脚本的命令行参数;env:环境变量;cwd:程序工作目录;port:调试端口(attach到--inspect进程时常用9229);autoAttachChildProcesses:是否自动附加子进程。