Node.js 调试方法

Node.js 调试走的是 V8 Inspector(Chrome DevTools Protocol)。CLI、Chrome DevTools、VS Code 都是连上同一套协议的不同客户端,不必为每种工具各学一套。默认监听 127.0.0.1:9229,不要把调试端口暴露到公网。

旧命令 node debugnode --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

单步执行命令

  • contc:继续执行脚本
  • nextn:单步执行下一行(不进入函数内部)
  • steps:单步进入函数内部
  • outo:单步跳出当前函数
  • 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),加载到该文件时会生效。

信息查看

  • backtracebt:打印当前调用栈回溯
  • list(5):打印脚本前后共 5 行源码上下文
  • watch(expr):添加表达式到监视列表
  • unwatch(expr):移除监视列表中的表达式
  • unwatch(index):按序号移除监视表达式
  • watchers:列出所有监视表达式与对应值,触发断点会自动打印
  • repl:打开调试 REPL,在当前脚本上下文执行代码
  • exec exprp expr:在脚本调试上下文执行表达式并打印结果

现行 CLI 还支持 profileprofileEndprofilestakeHeapSnapshot(),用来抓 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.0v15.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,即可看到远程目标列表。

image-20200802195554438

image-20200802195718540

如果目标没有自动出现,点击 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 进程。

image-20200803225503444.png

image-20200803225915556.png

launch.json 核心配置字段说明:

{
    "type": "node",
    "request": "launch",
    "name": "Launch NodeJs",
    "skipFiles": [
        "<node_internals>/**"
    ],
    "program": "${workspaceFolder}\\nodeDemo\\debug\\index.js"
}
  • type(必填):调试器类型,nodechromemsedge,都走内置 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:是否自动附加子进程。

参考链接

Debugging Node.js(官方入门)

Debugger API

© lizhao all right reserved,powered by Gitbook文件修订时间: 2026-09-02 00:31:53

results matching ""

    No results matching ""