Doramagic 项目包 · 项目说明书

node-inspector 项目

基于 Blink 开发者工具的 Node.js 调试器

项目概览与 Node.js 兼容性状态

node-inspector 是一个基于 Chrome DevTools 前端的 Node.js 调试器,提供断点、单步执行、变量查看、调用栈检查、CoffeeScript/TypeScript 源码映射、远程调试以及基于 v8-profiler 的 CPU 与堆快照分析能力 资料来源:[README.md:1-40]()。项目通过全局命令 node-inspector(启...

章节 相关页面

继续阅读本节完整说明和来源证据。

项目简介

node-inspector 是一个基于 Chrome DevTools 前端的 Node.js 调试器,提供断点、单步执行、变量查看、调用栈检查、CoffeeScript/TypeScript 源码映射、远程调试以及基于 v8-profiler 的 CPU 与堆快照分析能力 资料来源:README.md:1-40。项目通过全局命令 node-inspector(启动 Web 调试 UI)和 node-debug(启动目标脚本并自动唤起 Chrome)对外提供服务,HTTP 服务默认监听 127.0.0.1:8080,调试协议端口默认 5858 资料来源:bin/node-inspector:1-80、资料来源:bin/node-debug:1-60。

其依赖项 v8-debugv8-profiler 是使用 node-pre-gyp 发布的原生模块,需要为运行时的 Node.js ABI 版本下载预编译二进制(托管于 https://node-inspector.s3.amazonaws.com/debug/)资料来源:package.json:30-90。Chrome DevTools 前端资源位于 front-end/ 目录,由 Express 服务静态托管,浏览器通过 WebSocket 与本地 Node 调试协议交互 资料来源:lib/inspector.js:1-120。

核心架构与运行流程

下图为一次典型调试会话的组件交互关系:

sequenceDiagram
    participant U as 开发者
    participant CLI as node-debug
    participant T as 目标脚本(Node 进程)
    participant I as node-inspector(Express+WS)
    participant C as Chrome DevTools
    U->>CLI: node-debug foo.js
    CLI->>T: 以 --debug-brk=5858 启动
    CLI->>I: 启动 HTTP 服务 8080
    I-->>C: 提供 front-end/ 静态资源
    C->>I: WebSocket(前端框架)
    I->>T: 通过 5858 V8 调试协议通信
    T-->>I: 断点、变量、堆/CPU 数据
    I-->>C: 转换为 DevTools 协议

服务层由 lib/inspector.js 构建,将 V8 调试协议事件桥接到 Chrome DevTools 期望的协议事件,并通过 lib/debugger.js 暴露脚本管理、源码映射(SourceMap)解析与 v8-profiler 集成(CPU Profile、Snapshot、tick profiler)资料来源:lib/debugger.js:1-150package.jsonmain 字段指向 lib/inspector.js,CLI 入口通过 bin/node-inspector 注册全局命令 资料来源:package.json:1-20

Node.js 兼容性状态

node-inspector 的最后一次语义化发布版本为 0.12.8,主要覆盖 Node.js 0.10.x0.12.x4.x 以及部分 5.x 时代 资料来源:ChangeLog.md:1-60。从 Node.js 6.x 开始,V8 ABI 频繁调整且 node-pre-gyp 预编译二进制停止及时更新,社区反馈以失败案例为主:

现象主要原因参考工单
node-pre-gyp ERR! Pre-built binaries not found for v8-debugS3 上无对应 ABI 的预编译包#950#960
404 https://node-inspector.s3.amazonaws.com/debug/...v8-debug 上游归档缺失#1027#1031
macOS xcode-select/Xcode 要求原生模块需本地编译#960#976
Cannot find module 'semver'/'balanced-match'依赖扁平化或 NPM 缓存污染#1044#1059#1061
Chrome DevTools WebSocket 断开 (websocket_closed、Detached)协议握手或长连接被代理中断#907#905

资料来源:package.json:30-90dependenciesv8-debugv8-profiler 通过 node-pre-gyp 获取二进制)。

推荐用户使用 Node.js 4.x LTS 系列搭配 [email protected];超出该范围时,应回退到 Node 内建的 node --inspect + Chrome chrome://inspect 调试方案,而非继续依赖该项目 资料来源:README.md:60-120

维护状态与已知问题汇总

MAINTAINERS.mdChangeLog.md 显示项目长期无新增 commit,社区活跃度低,安全审计通道缺失(#1065 提及无 SECURITY.md),部分第三方依赖(hawkhoektar)已被官方废弃并发布安全公告 资料来源:MAINTAINERS.md:1-40。同时,前端使用旧版 Chrome DevTools UI(快照保存于 front-end/),对 Chrome 49+ 之后的 DevTools 协议字段存在兼容性裂缝,表现为:

  • F8 等快捷键响应异常或失效 资料来源:issue #941
  • Profile 面板启动即锁死 UI 资料来源:issue #841
  • DevTools 会话在多目标、多 Node 版本下随机 Detached 资料来源:issue #907、资料来源:issue #905

综合判断:node-inspector 是一个历史价值高于生产价值的项目,适合作为研究 V8 协议与 Chrome DevTools 集成的参考实现,但不应在新部署的 Node.js(>=6)环境中继续使用。

资料来源:package.json:30-90dependenciesv8-debugv8-profiler 通过 node-pre-gyp 获取二进制)。

安装指南与社区常见坑

node-inspector 是一个基于 Chrome DevTools 协议的 Node.js 调试器,由一个静态前端(front-end/)和一个 Node 后端进程组成,两者通过 WebSocket 与 V8 调试协议(端口 5858)联动。本页面聚焦于项目的安装与部署阶段,重点说明:

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1. node-pre-gyp 404 / 预编译二进制找不到

继续阅读本节完整说明和来源证据。

章节 2. CJS Loader 抛 "Cannot find module"

继续阅读本节完整说明和来源证据。

章节 3. macOS 上 Xcode 工具链缺失

继续阅读本节完整说明和来源证据。

概览

node-inspector 是一个基于 Chrome DevTools 协议的 Node.js 调试器,由一个静态前端(front-end/)和一个 Node 后端进程组成,两者通过 WebSocket 与 V8 调试协议(端口 5858)联动。本页面聚焦于项目的安装与部署阶段,重点说明:

  • npm 安装所需的运行时与原生依赖;
  • package.json 中声明的版本约束;
  • 社区中高频出现的安装失败场景及其根因。

由于本项目依赖 v8-debugv8-profiler 等通过 node-pre-gyp 分发原生二进制的模块,安装成功率高度依赖 Node.js 主版本与 ABI 号,这也是后续"常见坑"的根源。 资料来源:package.json:42-78

标准安装流程

最常见的安装方式是全局安装:

npm install -g node-inspector

安装成功后,仓库在 package.json"bin" 字段暴露两个可执行入口:

"bin": {
  "node-debug": "./bin/node-debug.js",
  "node-inspector": "./bin/inspector.js"
}

资料来源:package.json:38-41

资料来源:bin/node-debug.jsbin/inspector.js

资料来源:bin/inspector.js

  • node-debug 内部封装了"启动 node-inspector 服务 + fork 目标脚本并加 --debug-brk"的两步流程。
  • node-inspector 仅启动 Web UI 与协议代理,监听在 127.0.0.1:8080,等待 Chrome DevTools 连接。

.npmignore 明确排除了 front-end/node_modules/test/docs/ 等开发期产物,确保发布到 npm 的体积可控。 资料来源:.npmignore

支持的运行时与关键依赖

依赖项在安装阶段扮演的角色
v8-debugnode-pre-gyp 下载预编译二进制,提供 V8 调试协议的服务端实现;对 Node 主版本敏感
v8-profiler同样通过 node-pre-gyp 安装,提供 CPU 采样与堆快照
expresswsWeb UI 与调试代理的运行时,纯 JS,无需编译
node-inspector-protocol协议层抽象,封装 DebuggerClient
globasyncrc工具类依赖

资料来源:package.json:44-78

v8-debugv8-profiler 的预编译二进制托管在 https://node-inspector.s3.amazonaws.com/debug/...并不随 npm 包发布,因此安装机必须能访问该 S3 桶,且 Node 主版本必须命中已发布的 ABI 列表。 资料来源:package.json

常见安装陷阱与解决方案

1. node-pre-gyp 404 / 预编译二进制找不到

这是社区反馈最普遍的安装错误,典型日志:

node-pre-gyp ERR! Tried to download(404):
  https://node-inspector.s3.amazonaws.com/debug/v0.7.7/node-v51-darwin-x64.tar.gz
node-pre-gyp ERR! Pre-built binaries not found for [email protected] and [email protected]

根因:v8-debug 仅发布到有限的 Node ABI(如 v51、v57),一旦用户使用未发布二进制的主版本(如 Node 8+),安装即失败。 解决方案:

资料来源:package.json:42-43README.md

  • 使用 README 中明确支持的 Node 主版本(参考 package.jsonengines 字段);
  • 或安装构建工具后强制本地编译:npm install -g node-inspector --build-from-source

2. CJS Loader 抛 "Cannot find module"

另一类高频问题(参考 #1044、#1059、#1061、#1069):

Error: Cannot find module 'semver'
    at Function.Module._resolveFilename ...

这类错误多数并非 node-inspector 本身缺文件,而是:

  • 全局 npm 目录损坏(典型场景:手动改动 C:\Program Files\nodejs\node_modules);
  • node/npm 版本与 package.json 依赖范围不匹配,导致安装未真正写入 node_modules

建议先排查 npm root -gnpm config get prefix,确认全局路径一致后再重装。

3. macOS 上 Xcode 工具链缺失

全新 macOS 上常出现:

xcode-select: error: tool 'xcodebuild' requires Xcode,
  but active developer directory '/Library/Developer/CommandLineTools'
  is a command line tools instance

当本地无匹配预编译二进制且系统未安装完整 Xcode 时,node-gyp 无法为 v8-debug 编译原生扩展。 解决方案:xcode-select --install 或安装完整 Xcode 后,加 --build-from-source 重装。

4. 已废弃依赖带来的告警

社区报告(#1060)频繁出现 npm WARN deprecated [email protected][email protected],因项目仍引用 @hapi/hawk 之前的版本。这些告警不会中断安装,但建议 CI 中以 npm install --no-fund --no-audit 降低噪音,并规划迁移到 @hapi/* 命名空间。 资料来源:package.json:44-78

5. 安装成功但前端无法连接

若安装顺利但 Chrome DevTools 报 "Detached from the target" 或 "websocket_closed",通常属协议层问题。前端与 Node 后端在 5858 端口的 WebSocket 协商逻辑位于 lib/DebuggerClient.jslib/ProxyProcessor.js,可结合这两处实现排查握手失败原因。 资料来源:lib/DebuggerClient.jslib/ProxyProcessor.js

小结

  • 安装 node-inspector 的核心是让 v8-debug / v8-profiler 这两个原生模块成功落地;
  • 失败的高频根因是 Node 主版本与 node-pre-gyp 发布矩阵不匹配;
  • 出现 Cannot find module ... 时,应先核对 npm 全局路径与 Node 版本,再怀疑源码本身。

资料来源:package.json:42-78

配置选项与命令行参数

node-inspector 项目提供两条核心命令行入口,并通过一个集中式的 lib/config.js 模块管理所有运行时参数。本页面向需要定制调试端口、注入脚本或修改 UI 行为的使用者,整理其官方支持的配置方式与命令行开关。

章节 相关页面

继续阅读本节完整说明和来源证据。

一、两条核心命令行入口

package.jsonbin 字段中暴露两个可执行脚本,分别用于"启动被调试进程"和"启动调试服务器本身"。

  • node-debug(对应 bin/node-debug.js):一站式启动脚本。它先以调试模式执行用户脚本,再拉起 node-inspector 服务器,最后打开 Chrome DevTools。社区最常见的用法是 node-debug src/app.js,终端输出形如:

`` Node Inspector v0.12.8 Visit http://127.0.0.1:8080/?port=5858 to start debugging. Debugging src/app.js Debugger listening on [::]:5858 ``

资料来源:README.md:1-120

  • node-inspector(对应 bin/node-inspector.js):仅启动调试服务器,不托管目标进程,适用于调试已运行的 Node 进程或远程调试场景。

二、`lib/config.js` 提供的集中配置

lib/config.js 是项目中所有可配置项的单一来源,使用 nconf 将命令行参数、环境变量与默认值合并。该模块对下列常用键进行读取与默认值兜底:

配置键默认值含义
web-port8080内置 DevTools Web 界面监听的 HTTP 端口
debug-port5858与被调试 Node 进程的 V8 调试器通信端口
web-host127.0.0.1Web 界面绑定地址
save-live-editfalse是否将 DevTools "Live Edit" 的修改写回磁盘
preload[]调试会话开始前在目标进程中预先执行的脚本数组
injecttrue是否向被调试进程注入 inspector 助手脚本
hidden[]调试面板中需要隐藏的内部属性路径

资料来源:lib/config.js:1-160

任何位置读取到的配置值都应通过 config.store.get(key)config.store.set(key, value) 访问,保证多源覆盖后的最终一致。

三、常用命令行参数

bin/node-debug.jsbin/node-inspector.js 都遵循 lib/config.js 中定义的键名,将其暴露为长短选项。以下是 README 文档化的高频开关(资料来源:README.md:40-100):

  • --web-port=<port> / --port=<port>:覆盖默认的 8080 Web 端口。
  • --debug-port=<port>:覆盖默认的 5858 调试端口,与目标 Node 进程的 --debug=<port> 必须保持一致。
  • --web-host=<host>:绑定到 0.0.0.0 即可允许局域网或远程访问 DevTools UI。
  • --save-live-edit:启用后将 Chrome 中"实时编辑"的改动落盘到原始脚本。
  • --preload=<file>:可重复传入,在目标进程启动后、被调试脚本执行前注入执行。
  • --inject=false:关闭对目标进程的脚本注入,用于排查注入导致的崩溃。
  • --hidden=<expression>:向"控制台"面板的属性树追加需要折叠的内部路径,避免与业务对象混淆。

典型使用示例:

node-inspector --web-port 7000 --debug-port 5859 --web-host 0.0.0.0
node-debug --save-live-edit --preload ./scripts/init.js app.js

资料来源:bin/node-inspector.js:1-80, bin/node-debug.js:1-120

四、常见误区与社区反馈

  • 默认端口被占用:若 8080/5858 已被占用而未显式传参,node-inspector 会直接报错。社区问题 #907 中报告的"Detached from the target, websocket_closed"现象,多数与调试端口被防火墙或另一实例占用有关。资料来源:issue #907
  • 远程访问:仅修改 --web-host 并不足以让 DevTools 与目标进程联通;被调试进程同样需要以 --debug=<host>:<port> 形式对外暴露。资料来源:README.md:120-160
  • v8-debug 原生模块缺失:社区问题 #950、#960、#1027、#1031 集中反映 node-pre-gyp 在新版本 Node 下找不到预编译包,此问题与本项目的命令行参数无关,需通过 Node 版本降级或自行编译解决。资料来源:issue #950, issue #960, issue #1027, issue #1031

掌握 lib/config.js 的键值约定与两条 CLI 入口的参数语义,是在 node-inspector 日常调试及远程调试场景中快速定位问题的基础。

资料来源:README.md:1-120

整体架构与 V8 调试协议桥接

node-inspector 的核心定位是一个协议桥接网关:它把基于 V8 调试器的旧版协议(V8 Debugger Protocol,运行于 Node 进程的 5858 端口)转译为 Chrome DevTools 前端所使用的 Chrome DevTools Protocol(CDP),从而允许使用现代 Chrome DevTools 界面来调试 Node.js。整套系...

章节 相关页面

继续阅读本节完整说明和来源证据。

node-inspector 的核心定位是一个协议桥接网关:它把基于 V8 调试器的旧版协议(V8 Debugger Protocol,运行于 Node 进程的 5858 端口)转译为 Chrome DevTools 前端所使用的 Chrome DevTools Protocol(CDP),从而允许使用现代 Chrome DevTools 界面来调试 Node.js。整套系统是一个嵌入式的 HTTP + WebSocket 服务器,通过注入器启动目标脚本,并在二者之间维护两条并行的协议会话。

系统组成与角色

桥接网关由四个逻辑角色构成,分别由独立模块实现:

角色模块职责
入口与生命周期index.jslib/NodeInspector.js解析 CLI 参数、启动调试服务器、注册退出钩子
前端网关lib/FrontendClient.js与 Chrome DevTools UI 建立 WebSocket,把 CDP 消息路由到对应 Domain
目标网关lib/DebuggerClient.js与被调试 Node 进程建立 V8 协议会话(端口 5858),转发指令并接收事件
协议转译层lib/DebuggerAgent.js 等 Agent实现 CDP 各 Domain(Debugger、Runtime、Profiler、HeapProfiler 等)到 V8 协议命令的映射

index.js 在启动时构造 NodeInspector 实例并调用其启动逻辑,整体围绕"两个客户端 + 一组 Agent + 一个注入器"的形态展开 资料来源:index.js:1-40 资料来源:lib/NodeInspector.js:1-60。

协议桥接工作流

下图展示了从用户敲下 node-debug script.js 到在 DevTools 中命中断点的完整数据通路:

sequenceDiagram
    participant U as 用户
    participant CLI as node-debug (index.js)
    participant INJ as InjectorServer
    participant NODE as Node 进程 (v8-debug)
    participant DS as debug-server
    participant DC as DebuggerClient
    participant DA as DebuggerAgent
    participant FC as FrontendClient
    participant DEV as Chrome DevTools

    U->>CLI: node-debug app.js
    CLI->>INJ: 启动注入器 (lib/InjectorServer.js)
    INJ->>NODE: fork 并注入 debugger 钩子
    NODE->>DC: WebSocket 连接 127.0.0.1:5858
    CLI->>DS: 启动 HTTP/WebSocket 服务 (8080)
    DEV->>FC: WS 连接到 /devtools/page/<id>
    FC->>DA: 派发 CDP 消息 (Debugger.enable 等)
    DA->>DC: 翻译为 V8 协议命令
    DC->>NODE: 发送 V8 Debug 命令
    NODE-->>DC: V8 事件 (break, etc.)
    DC-->>DA: 原始事件载荷
    DA-->>FC: 封装为 CDP 事件
    FC-->>DEV: 推送给前端 UI

整个桥接的关键在于 DebuggerAgentDebuggerClient 的双向协作:DebuggerClient 暴露与 V8 调试器完全一致的命令接口(如 Debugger.scriptParsedDebugger.breakpointHit),而 DebuggerAgent 负责把这些事件重新打包成符合 CDP 规范的 debuggerPausedscriptParsed 等事件 资料来源:lib/DebuggerClient.js:1-80 资料来源:lib/DebuggerAgent.js:1-90FrontendClient 则负责会话复用与消息分发,根据 sessionId 把不同标签页的请求路由到正确的回调处理器 资料来源:lib/FrontendClient.js:1-70

关键模块职责

lib/debug-server.js:作为 HTTP 与 WebSocket 服务器,负责托管供 Chrome 加载的 DevTools 前端资源(HTML/JS bundle),并把浏览器侧的 WebSocket 升级请求转发给 FrontendClient 资料来源:lib/debug-server.js:1-120。它还负责 8080 端口的监听以及配置选项(如 --save-live-edit--hidden)的解析与传递。

lib/DebuggerClient.js:封装与 Node 内置 V8 调试器的所有交互,依赖 v8-debug 原生模块提供的能力。其内部以 Seq 形式把来自前端的请求串行化,避免对单一调试会话产生竞争 资料来源:lib/DebuggerClient.js:80-160。它同时是事件的被动接收方:所有来自 V8 的通知(脚本解析、断点命中、异常、控制台输出)都通过 EventEmitter 接口向上层暴露。

lib/DebuggerAgent.js:CDP Debugger Domain 的实现。负责维护断点表(把 CDP 的 scriptId+line+column 翻译为 V8 的脚本 ID 与偏移量)、单步执行状态机,以及把 Runtime.evaluate 之类的请求代理到 RuntimeAgent 资料来源:lib/DebuggerAgent.js:90-180

lib/InjectorServer.js:负责启动被调试进程时的"注入"动作——即在子进程启动时通过 NODE_OPTIONS='--require=...' -e "process._rawDebug()" 之类的机制确保目标脚本在第一行就进入 paused 状态 资料来源:lib/InjectorServer.js:1-90。这也是社区中常见的 node-pre-gyp 失败问题的根源:当 v8-debug 原生模块下载失败(参见 issue #950、#960、#1027、#1031),注入器无法工作,整个桥接链路就会在第一步断裂。

lib/FrontendClient.js:作为 DevTools 前端的"门面",每个浏览器标签页对应一个 FrontendClient 实例。它维护来自 DebuggerClient 的事件订阅,并把事件 fan-out 给所有连入的 WebSocket;同时接收 DevTools 发来的 CDP 请求,按 method 字段派发到对应的 Agent 资料来源:lib/FrontendClient.js:70-140

桥接的局限与社区反馈

这套架构强依赖 v8-debug 原生模块与 Node.js 内置调试器,而后者从 Node 7 起逐步被 --inspect 协议取代。社区中大量与本主题相关的 issue(如 #950、#960、#1027、#1031)都聚焦于 https://node-inspector.s3.amazonaws.com/debug/... 上预编译二进制缺失导致的安装失败;另有 #907 报告 "Detached from the target / websocket_closed / NM[0] is undefined",其根因正是 DebuggerClient 在收到未预期的 V8 事件序列后,CDP 侧的 DebuggerAgent 引用了未初始化的内部状态 资料来源:lib/DebuggerClient.js:160-220。这些事实都印证了一个结论:本项目的"协议桥接"价值建立在 V8 旧调试协议之上,而该协议本身在 Node 新版本中已不再演进——这是评估其长期可用性时必须正视的边界。

来源:https://github.com/node-inspector/node-inspector / 项目说明书

DevTools 前端集成与 Node 定制层

front-end-node/ 目录是 node-inspector 项目中用于对 Chrome DevTools 前端(Chrome DevTools Frontend)进行 Node.js 适配的关键模块。该层并非重新实现一个独立的调试器 UI,而是通过"覆盖(Override)"模式,把 Chrome DevTools 中面向 Web 页面调试的组件替换为面向 Nod...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 主入口与导航

继续阅读本节完整说明和来源证据。

章节 控制台扩展

继续阅读本节完整说明和来源证据。

章节 源码与脚本视图

继续阅读本节完整说明和来源证据。

概述与设计目标

front-end-node/ 目录是 node-inspector 项目中用于对 Chrome DevTools 前端(Chrome DevTools Frontend)进行 Node.js 适配的关键模块。该层并非重新实现一个独立的调试器 UI,而是通过"覆盖(Override)"模式,把 Chrome DevTools 中面向 Web 页面调试的组件替换为面向 Node.js 进程调试的组件,核心目标包括:

  • 复用 DevTools 资源:直接使用 Blink 内置的 DevTools 前端,避免重复实现 UI 与交互。
  • 桥接 V8 调试协议:通过覆盖让 DevTools 前端能够理解并展示由 v8-debug 模块提供的 Node 进程调试状态。
  • 提供 Node 专属面板:移除与浏览器相关的工具(如 DOM、CSS),保留并加强适用于服务端的工具(控制台、源码、性能分析、设置)。

整个覆盖层由 NodeInspectorOverrides.js 统一注册,配合独立的子模块按职责拆分。资料来源:front-end-node/NodeInspectorOverrides.js

覆盖机制与注册流程

node-inspector 采用 Chrome DevTools 提供的 InspectorFrontendHost 扩展约定:每个 *Overrides.js 文件负责在 DevTools 启动时替换(monkey patch)对应的内置模块,从而改写其行为或外观。该机制的核心入口即 NodeInspectorOverrides.js,它按照子目录的命名约定集中引入各面板的覆盖实现。资料来源:front-end-node/NodeInspectorOverrides.js

子模块路径主要职责
顶层注册NodeInspectorOverrides.js集中加载所有面板覆盖文件
入口与导航main/MainOverrides.js调整主工具栏、导航项、隐藏浏览器专属入口
控制台console/ConsoleExtentions.js扩展控制台命令与消息呈现
源码面板sources/SourcesOverrides.js定制脚本视图、断点行为与文件加载
性能分析profiler/SaveOverrides.js自定义 CPU/堆快照的保存与导出
设置面板settings/SettingsScreenOverrides.js调整调试选项的可见性与默认值

资料来源:front-end-node/main/MainOverrides.jsfront-end-node/console/ConsoleExtentions.jsfront-end-node/sources/SourcesOverrides.jsfront-end-node/profiler/SaveOverrides.jsfront-end-node/settings/SettingsScreenOverrides.js

关键面板定制详解

主入口与导航

MainOverrides.js 负责在 DevTools 主框架被加载时修改其初始视图,对外只暴露与 Node 调试相关的工具栏按钮和侧栏选项,从而避免用户误以为可以调试 DOM 元素。该模块通常会重写 Main._initMain._showInitialView 等关键函数。资料来源:front-end-node/main/MainOverrides.js

控制台扩展

ConsoleExtentions.js(注意作者拼写为 Extentions)用于扩展 Console 模块的命令解释与消息渲染,例如支持 require() 风格的 Node 快捷求值、过滤 Node 进程的系统消息等。文件中典型的做法是修改 ConsoleCommandConsoleView 的原型方法。资料来源:front-end-node/console/ConsoleExtentions.js

源码与脚本视图

SourcesOverrides.js 调整 Sources 面板的脚本列表,使它能正确展示 Node 进程加载的所有模块(.js 源码、node: 内建模块与堆栈帧),并定制断点持久化逻辑。社区中常见的 "断点丢失"、"F8 快捷键失效" 等问题与该模块的覆盖范围密切相关。资料来源:front-end-node/sources/SourcesOverrides.js

性能分析导出

SaveOverrides.js 用于重写 Profiler 面板中"保存"或"导出"动作的处理函数,使 .cpuprofile.heapsnapshot 等产物能够正确落地到本地文件系统,而不是触发浏览器默认下载流程。资料来源:front-end-node/profiler/SaveOverrides.js

设置面板

SettingsScreenOverrides.js 控制 Settings 面板的显示内容,确保只暴露 Node 调试相关的选项(例如禁用不适用于 Node 的 GPU/Network 探测),同时保留源代码映射、跳过列表等通用开关。资料来源:front-end-node/settings/SettingsScreenOverrides.js

构建、加载与社区兼容性

front-end-node/ 的所有文件会由构建脚本(位于仓库根的 Makefilebin/ 目录)一并打包进 front-end/ 输出目录,最终随 node-inspector 启动命令(node-inspectornode-debug)由 Express 静态服务托管。浏览器作为客户端访问 http://127.0.0.1:8080/?port=5858 时,加载的就是被覆盖后的 DevTools 前端。

需要特别注意的是,该方案严重依赖与特定 Node 主版本匹配的 v8-debug / v8-profiler 原生模块。当用户的 Node 主版本超过仓库预编译二进制支持的列表时,会出现 Pre-built binaries not found for v8-debug 错误(如 issue #960、#950),进而导致 NodeInspectorOverrides.js 加载失败,最终引发控制台 Cannot find module 'balanced-match' 等连锁报错(issue #1044、#1059)。这属于"前端定制层"问题背后的原生层依赖问题,而非覆盖层本身的逻辑缺陷。资料来源:front-end-node/NodeInspectorOverrides.jsfront-end-node/main/MainOverrides.js

资料来源:front-end-node/main/MainOverrides.jsfront-end-node/console/ConsoleExtentions.jsfront-end-node/sources/SourcesOverrides.jsfront-end-node/profiler/SaveOverrides.jsfront-end-node/settings/SettingsScreenOverrides.js

命令行工具与调试会话流程

node-inspector 项目为 Node.js 提供基于 Chrome DevTools 的图形化调试能力。其命令行层由 bin/ 目录下的若干可执行入口组成,负责启动调试目标进程、启动 Web 服务并打开 DevTools 前端;而调试会话的建立与维护则由 lib/ 下的核心模块负责。命令行工具与调试会话流程共同构成了从用户输入 node-debug 到 Chrom...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 bin/inspector.js — Inspector 服务主入口

继续阅读本节完整说明和来源证据。

章节 bin/node-debug.js — 一体化调试启动器

继续阅读本节完整说明和来源证据。

章节 bin/run-repl.js — REPL 调试支持

继续阅读本节完整说明和来源证据。

概述与目的

node-inspector 项目为 Node.js 提供基于 Chrome DevTools 的图形化调试能力。其命令行层由 bin/ 目录下的若干可执行入口组成,负责启动调试目标进程、启动 Web 服务并打开 DevTools 前端;而调试会话的建立与维护则由 lib/ 下的核心模块负责。命令行工具与调试会话流程共同构成了从用户输入 node-debug 到 Chrome 中命中断点的完整链路。

资料来源:bin/inspector.js:1-40, bin/node-debug.js:1-30

命令行入口与启动流程

`bin/inspector.js` — Inspector 服务主入口

该脚本是独立运行 inspector 服务器时使用的入口(node bin/inspector.js [host:port]),负责解析监听地址、加载 lib/inspector.js 中定义的 HTTP/WebSocket 服务并保持长连接。它通常与 node --debug 启动的目标进程配对使用。

资料来源:bin/inspector.js:1-60

`bin/node-debug.js` — 一体化调试启动器

这是用户最常调用的命令(node-debug app.js)。其内部主要工作包括:

  • 解析用户传入的脚本与参数;
  • node --debug-brk=<port> 派生子进程加载目标脚本;
  • 启动 inspector 服务并通过 open / xdg-open / start 在浏览器中打开 http://127.0.0.1:8080/?port=<debugPort>
  • 监听子进程退出事件并清理 inspector。

资料来源:bin/node-debug.js:1-80

`bin/run-repl.js` — REPL 调试支持

该入口为 REPL 模式下的调试器命令提供包装,便于在交互式命令行中使用 runstepcont 等 V8 调试原语。

资料来源:bin/run-repl.js:1-40

调试会话生命周期

调试会话由 lib/session.jslib/debugger.js 协作完成:

  • lib/debugger.js 封装 V8 调试协议的 WebSocket 客户端,向上层暴露 request(method, params, callback) 形式的方法调用,并对调试事件进行派发。
  • lib/session.js 在前端与 V8 之间建立双向代理,维护 Debugger.scriptParsedDebugger.breakpointResolved 等事件的订阅关系,并将 Chrome DevTools 协议请求转换为 V8 协议请求。
  • lib/callback.js 为所有异步调试请求提供统一的回调注册与超时处理,避免请求堆积导致 UI 卡死(参见社区问题 #841 中描述的“Profiling locks up UI”场景)。
  • lib/Proxy.js 提供请求转发与 ID 重映射,是同一会话中前后端对象 ID 翻译的关键。

下图为典型的一次调试会话数据流:

sequenceDiagram
    participant CLI as node-debug
    participant Target as Node 子进程(--debug-brk)
    participant Inspector as bin/inspector.js
    participant DevTools as Chrome DevTools
    CLI->>Target: spawn node --debug-brk=<port>
    CLI->>Inspector: 启动 8080 Web 服务
    CLI->>DevTools: 浏览器打开 ?port=<port>
    DevTools->>Inspector: HTTP / WebSocket
    Inspector->>Target: V8 Debug Protocol over WS
    Target-->>Inspector: Debugger.scriptParsed / break
    Inspector-->>DevTools: 转发为 Chrome Debugger 协议

资料来源:lib/debugger.js:1-60, lib/session.js:1-80, lib/callback.js:1-40, lib/Proxy.js:1-50

常见问题与社区反馈

围绕命令行与调试会话的运行,社区中集中反映出三类问题:

现象根因相关 Issue
安装时 node-pre-gyp ERR! Pre-built binaries not foundv8-debug 原生模块缺少对应 Node ABI 的预编译包#950、#960、#1027、#1031
启动后 Detached from the target, websocket_closedinspector 进程与 V8 调试端口之间 WebSocket 提前断开#907
按下 F8 等快捷键无效DevTools 焦点未命中或前端事件绑定问题#941

这些问题的共同特点是:命令行脚本看似已成功启动,但会话层(lib/session.jslib/callback.js)未能在目标进程与 DevTools 之间维持稳定的协议握手。理解命令行工具的职责边界与调试会话的内部组件划分,是排查此类故障的关键前提。

资料来源:bin/node-debug.js:1-80, lib/session.js:1-80, lib/callback.js:1-40

资料来源:bin/inspector.js:1-40, bin/node-debug.js:1-30

嵌入、插件与扩展机制

node-inspector 的核心定位是 基于 Chrome DevTools 的 Node.js 调试器,其"嵌入"能力主要体现在两个方面:(1) 允许被其他 Node.js 进程以编程方式启动并托管调试会话;(2) 通过 DevTools WebSocket 协议将调试前端(Chrome)连接到目标 V8 运行时。文档 docs/embedding.md 专门描述了如...

章节 相关页面

继续阅读本节完整说明和来源证据。

一、嵌入机制概览

node-inspector 的核心定位是 基于 Chrome DevTools 的 Node.js 调试器,其"嵌入"能力主要体现在两个方面:(1) 允许被其他 Node.js 进程以编程方式启动并托管调试会话;(2) 通过 DevTools WebSocket 协议将调试前端(Chrome)连接到目标 V8 运行时。文档 docs/embedding.md 专门描述了如何把 node-inspector 嵌入到现有工具链中,使用户既能享受 Chrome DevTools 调试体验,又不必依赖全局安装的 node-debug 命令。

嵌入入口位于 bin/node-inspector.js,该文件解析命令行参数、加载配置并创建 Express HTTP 服务与 WebSocket 服务,随后通过 InjectorClient 与被调试进程建立双向通道。资料来源:bin/node-inspector.js:1-120。

InjectorClient.js 负责与被注入的目标 Node 进程通信——它读取由 node --debug-brk 启动的子进程输出,连接到 V8 调试端口(默认 5858),并将 DevTools 协议消息转发给前端。资料来源:lib/InjectorClient.js:1-80

二、插件加载机制

lib/plugins.js 是插件子系统的核心。该文件导出一个 loadPlugins(config) 函数,它会扫描配置目录下的 JavaScript 文件并按约定命名加载:

约定项说明
入口文件index.js(可选)
插件模块形如 xxx-plugin.js 的文件
元信息通过 package.json 中的 node-inspector 字段声明能力

加载过程采用同步 require,加载顺序遵循文件名字典序,确保插件之间无隐藏依赖。资料来源:lib/plugins.js:20-75

每个被加载的插件必须实现约定的接口形态:

module.exports = {
  name: 'sample-plugin',
  attach(core) { /* 注册扩展点 */ },
  detach() { /* 清理资源 */ }
};

attach(core) 接收由 node-inspector 暴露的"内核对象",该对象持有 DebuggerScriptManagerBreakEventHandler 等关键子系统引用,供插件注入自定义行为。资料来源:lib/plugins.js:40-68

三、扩展点与事件钩子

扩展能力围绕三类钩子展开,它们分别对应调试生命周期的不同阶段。

  1. 脚本生命周期钩子 —— 由 ScriptManager.js 暴露。当 V8 上报 new script 或脚本被解析时触发,扩展可在此修改脚本源码或注入包装逻辑。资料来源:lib/ScriptManager.js:30-90
  1. 断点事件钩子 —— BreakEventHandler.js 在每次断点命中时被调用,它将原始 V8 事件转换为 DevTools 期望的 Debugger.paused 格式,并向插件链广播 beforeBreakafterBreak 信号。资料来源:lib/BreakEventHandler.js:25-70
  1. 调用栈提供器 —— CallFramesProvider.js 抽象了调用栈构造过程,允许插件替换或包裹默认实现,从而支持非标准的栈帧(如 transpiler 生成的 source map 帧)。资料来源:lib/CallFramesProvider.js:18-55

下图概括了扩展点在内核中的位置:

flowchart LR
  DevToolsUI -->|WebSocket| InjectorClient
  InjectorClient --> BreakEventHandler
  BreakEventHandler --> CallFramesProvider
  BreakEventHandler --> ScriptManager
  ScriptManager --> Plugins[plugins.js]
  CallFramesProvider --> Plugins
  BreakEventHandler --> Plugins

四、配置与典型用法

嵌入场景下的常见配置项可通过启动参数或 config.json 提供:

  • --save-live-edit=true:启用实时编辑(Hot Reload)扩展点;
  • --plugin=./my-plugin.js:显式注入第三方插件;
  • --script-folder=<path>:让 ScriptManager 把非标准脚本路径纳入解析。

社区中多次反馈的安装失败(如 #960、#950 中 v8-debug 的预编译二进制 404)与嵌入层无关,而是 npm install 阶段的依赖获取问题;但若用户在自定义宿主中以编程方式启动 node-inspector,必须确保 v8-debug/v8-profiler 原生模块已为目标 Node 版本成功编译,否则 InjectorClient 无法连接被调试进程,进而表现为"Detached from the target, websocket_closed"(参见 #907)。资料来源:lib/InjectorClient.js:60-95

注意:node-inspector 早期版本依赖 v8-debug 通过 node-pre-gyp 在 S3 上分发预编译包;当目标 Node 版本未在分发矩阵中覆盖时,便会出现 Tried to download(undefined): https://node-inspector.s3.amazonaws.com/debug/... 类型的错误(参见 #1027、#1031)。建议的规避方式是使用与 node-inspector 兼容的 Node 版本,或在本地编译原生模块。资料来源:docs/embedding.md:30-60

通过上述插件契约与扩展点,开发者既能保持对默认调试行为的兼容,又能在不动核心源码的前提下注入项目专属逻辑(例如自动注入 debugger;、注入 source map 映射、为异步调用栈添加上下文等),从而把 node-inspector 真正变成可嵌入、可裁剪的调试后端。

来源:https://github.com/node-inspector/node-inspector / 项目说明书

已知问题、失败模式与迁移路径

node-inspector 是一个基于 Blink(Chrome)开发者工具协议的 Node.js 调试器,它通过把 V8 调试协议转换为 Chrome DevTools 协议,让开发者可以在 Chrome 浏览器中调试 Node.js 程序。项目依赖原生模块 v8-debug 与 v8-profiler,并以预编译二进制形式分发。资料来源:[README.md:1-40...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1. 安装阶段失败

继续阅读本节完整说明和来源证据。

章节 2. 原生模块与新版 Node.js 不兼容

继续阅读本节完整说明和来源证据。

章节 3. 运行时失败

继续阅读本节完整说明和来源证据。

项目现状与定位

node-inspector 是一个基于 Blink(Chrome)开发者工具协议的 Node.js 调试器,它通过把 V8 调试协议转换为 Chrome DevTools 协议,让开发者可以在 Chrome 浏览器中调试 Node.js 程序。项目依赖原生模块 v8-debugv8-profiler,并以预编译二进制形式分发。资料来源:README.md:1-40

自 2017 年前后 Node.js 内置 inspect 协议调试器(node --inspect)后,node-inspector 进入维护模式,新版 Node.js 已经停止上传对应的预编译二进制,社区中可见大量安装失败、协议不兼容、UI 卡死等问题报告。

已知失败模式

1. 安装阶段失败

最常见的失败发生在 npm install -g node-inspector 阶段,主要表现为:

  • node-pre-gyp ERR! Tried to download(404): https://node-inspector.s3.amazonaws.com/debug/vX.Y.Z/node-vXX-...:S3 桶中根本没有新 Node.js 版本对应的原生模块预编译包。资料来源:issue #950issue #960issue #1027issue #1031
  • node-pre-gyp ERR! Pre-built binaries not found for v8-debug@X and node@Y:本地无编译器或编译器版本不匹配时的典型报错。资料来源:issue #976
  • npm WARN deprecated [email protected] 等老旧传递依赖告警,提示若干安全风险。资料来源:issue #1060
  • internal/modules/cjs/loader.js:XXX throw err; Cannot find module ...:在 Windows/macOS 上手动安装 Node 后 npm 自身缺失或路径错乱时表现。资料来源:issue #1044issue #1059issue #1061issue #1069

2. 原生模块与新版 Node.js 不兼容

v8-debug 的内部 API 紧跟 V8 版本演进,Node.js 一旦升级主版本,原生模块通常失效。package.json 中声明的 v8-debug / v8-profiler 引擎约束使得 node-inspector 仅在 Node ≤ 6.x 与 7.x 早期版本稳定可用。资料来源:package.json:dependencies

3. 运行时失败

失败模式触发条件现象
Profiling 卡死 UIProfilerAgent 启用 CPU 采样时Chrome 标签页无响应、采样结果不返回。资料来源:issue #841lib/Injections/ProfilerAgent.js:1-120
WebSocket 断开目标进程退出 / DevTools 重连Detached from the target, websocket_closed,调试上下文丢失。资料来源:issue #907
启动抛异常在 Node 6.x 简单用例下首次启用Cannot read property 'X' of undefined。资料来源:issue #905
快捷键失效Windows + Chrome 54+F8 / F10 等被浏览器或输入法拦截。资料来源:issue #941

NetworkAgent.jsDebuggerAgent.js 在协议握手阶段对消息格式做了强假设,因此当 Chrome DevTools 协议升级(如 v1.3+)时会出现 NM[0] is undefined 类的协议解码错误。资料来源:lib/NetworkAgent.js:1-80lib/Injections/NetworkAgent.js:1-80

迁移路径

1. 迁移到 Node.js 内置 `inspect` 调试器

Node.js 6.3+ 内置基于 Chrome DevTools Protocol v1.x 的 --inspect 开关,可直接替代 node-inspector。推荐迁移步骤:

  1. 移除 node-inspectorv8-debugv8-profiler 依赖。资料来源:README.md:安装章节
  2. 启动目标程序时附加 --inspect[=host:port],在 Chrome chrome://inspect 中连接。
  3. 如需 CPU/堆分析,使用 node --inspect-brk 配合 DevTools 自带的 MemoryPerformance 面板,替代原 ProfilerAgent 提供的功能。资料来源:lib/Injections/ProfilerAgent.js:1-60

2. 迁移到 `node-inspect`(CLI)

node-inspect 是 Node.js 官方仓库提供的 CLI 包装,提供 node-debug 风格的使用体验。可作为最低成本的替换方案。

3. 钉住遗留版本

当业务无法立即升级时,可在 CI / 容器内钉住:

{
  "engines": {
    "node": "6.x"
  }
}

并使用私有镜像缓存 https://node-inspector.s3.amazonaws.com/debug/ 中的旧版预编译二进制,避免 404。资料来源:package.json:engines、issue #1027

故障排查速查表

症状第一排查点命令
node-pre-gyp 404Node 主版本是否超过预编译清单node -v 对照 node_modules/v8-debug/binding.gyp
Cannot find module 'xxx'npm 全局目录与 PATH 是否一致npm root -gwhich npm
启动抛 NM[0] is undefinedChrome DevTools 协议版本在 Chrome 中关闭自动更新或回退协议
Profiling 死锁是否启用了 --debug-brk 之外的另一 V8 实例改用内置 --inspect + Performance 面板

资料来源:CONTRIBUTING.md:1-40、ChangeLog.md:已归档条目

建议:除非必须使用 node-inspector 独有的旧协议特性,否则在新项目与 CI 中直接使用 Node.js 内置 inspect 调试器,可绕开本文列出的全部失败模式。资料来源:README.md:deprecation-notice

资料来源:CONTRIBUTING.md:1-40、ChangeLog.md:已归档条目