node.js v20.10.0+才真正支持http/2调试,此前版本断点命中率低、stream状态不可见;必须≥v20.10.0并配合mkcert证书、--inspect=127.0.0.1绑定及独立grpc配置方可稳定调试。

Node.js 20+ 才真正支持 HTTP/2 调试,别用旧版硬扛
VSCode 对 HTTP/2 的本地调试依赖 Node.js 原生 http2 模块的稳定实现。Node.js 18 开始实验性支持,但断点命中率低、stream 状态不可见;Node.js 20.10+(LTS)才修复了 DAP 与 HTTP/2 ServerSession 的上下文同步问题。若你用 node -v 输出是 v18.19.0 或更低,debugger 在 http2.createSecureServer() 回调里大概率失效。
- 确认版本:终端运行
node -v,必须 ≥v20.10.0 - 启用调试:启动时加
--inspect参数,且必须绑定到127.0.0.1(node --inspect=127.0.0.1:9229 server.js),0.0.0.0会因 TLS SNI 协商失败导致 VSCode 无法 attach - 证书要求:HTTP/2 强制 TLS,本地调试必须提供有效证书。别用自签名 cert +
rejectUnauthorized: false—— VSCode 调试器会跳过证书验证但无法映射源码。推荐用mkcert生成 localhost 证书:mkcert -install && mkcert localhost,生成localhost.pem和localhost-key.pem
gRPC 服务调试必须走 grpc-js,别碰 grpc 原生绑定
grpc(C++ binding)模块在 VSCode 调试中无法正确暴露 call stack 和 proto message 结构,断点停在 server.bindAsync() 后就失去控制流;grpc-js 是纯 JS 实现,完全兼容 DAP,且支持 proto 文件源码映射。
诊断并恢复通过 SSH 隧道连接的 OpenClaw 节点。用于解决配对必需错误、隧道冲突、远程端点错误以及 SSH 目标配置错误等问题。
- 安装:确保
npm install grpc-js(不是grpc),并在代码中const grpc = require('grpc-js') - launch.json 配置关键项:
"env": { "GRPC_TRACE": "api,call", "GRPC_VERBOSITY": "DEBUG" }—— 这能让调试控制台输出真实请求路径和 status code,否则 gRPC 错误只显示14 UNAVAILABLE这种无意义码 - proto 映射:把
.proto文件放在src/proto/下,用protoc --js_out=import_style=commonjs,binary:./src/proto src/proto/greeter.proto生成 JS,VSCode 才能识别request.message字段结构
HTTP/2 + gRPC 混合服务的 launch.json 必须拆成两个配置
一个进程同时跑 HTTP/2 Web 页面 + gRPC 服务端,VSCode 无法在一个 configuration 里兼顾两者调试:HTTP/2 的 TLS 握手会阻塞 gRPC 的 bindAsync,导致断点永远等不到 server ready;强行合并会导致变量作用域错乱、热重载失效。
- 写两个独立配置:一个 type="node" 启动 HTTP/2 server(监听
https://localhost:8443),另一个 type="node" 启动 gRPC server(监听localhost:50051) - 用
compounds组合:"compounds": [{ "name": "HTTP2 + gRPC", "configurations": ["HTTP2 Server", "gRPC Server"] }],这样 Ctrl+F5 一键启动,两个终端日志分离,断点互不干扰 - 注意端口冲突:HTTP/2 默认用 8443,gRPC 默认用 50051,别改成一样 —— 否则第二个进程启动失败,VSCode 不报错,只在 Debug Console 显示
listen EADDRINUSE
调试 gRPC-Web 客户端时,Chrome DevTools 断点比 VSCode 更可靠
gRPC-Web 是通过 fetch 封装的 HTTP/2-over-HTTP/1.1 代理协议,VSCode 的 Node.js 调试器看不到浏览器端的 request payload 和 response stream。真正要查 client-side 逻辑(比如 client.sayHello() 返回空对象),得切到 Chrome DevTools。
- 启动 Chrome 加参数:
chrome --remote-debugging-port=9222 --unsafely-treat-insecure-origin-as-secure=http://localhost:3000 --user-data-dir=/tmp/chrome-debug - VSCode 安装
Debugger for Chrome扩展,launch.json 新增配置:"type": "pwa-chrome","url": "http://localhost:3000",断点打在grpc-web-client的invoke()内部 - 关键技巧:在 Chrome 的 Network 标签页过滤
grpc,右键某条请求 → “Save as HAR with content”,再用har-to-json工具解析,能看清实际发送的 base64 编码 payload —— 这比 VSCode 变量监视器更准
GRPC_MAX_RECEIVE_MESSAGE_LENGTH 环境变量都会让断点突然失效。最常被忽略的是 mkcert 生成的证书没被 Chrome 信任,导致页面白屏但 VSCode 显示 “Debugger attached” —— 此时看 Chrome 地址栏锁图标是否灰色,比看 VSCode 的 debug toolbar 更管用。










