Chrome DevTools 调试
小程序的业务代码跑在独立的 V8 里,不是网页。右键「检查」那套流程在这里用不上,元素也选不中。
WeAppDev 把 WMPF 自带的 V8 inspector 接出来,翻译成标准 CDP,通过 :9400 网关对外提供服务。Chrome 那头只当它是一台普通浏览器。
前置条件
- 手机上已经打开目标小程序(运行进程存在);
- App 的「开发配置」里,调试网关处于开启状态;
- 手机与电脑通过 USB 或同一局域网连接。
方式一:adb forward(推荐)
adb devices
adb forward tcp:9400 tcp:9400
# 确认网关在线
curl http://127.0.0.1:9400/json/list返回结果里应该能看到两类 target:
[
{ "id": "appservice", "type": "app_service", "title": "逻辑层" },
{ "id": "R3f2-page", "type": "page", "title": "页面:VISIBLE" }
]然后在 Chrome 地址栏直接粘贴:
devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9400/devtools/appservice这条地址会直接打开逻辑层的调试器。
方式二:chrome://inspect
- 手机与电脑连同一个 Wi-Fi;
- 确认 App 的网关绑定在
0.0.0.0:9400; - Chrome 打开
chrome://inspect; - 在 Configure 里添加
<手机IP>:9400; - 等待 target 出现,点 inspect。
两种方式怎么选
adb forward 最省事,也不受公司网络策略影响;Wi-Fi 直连适合没有数据线、或需要同时调试多台设备的情况。
能做什么
断点与单步
在 Sources 面板打开业务脚本,行号上点一下就是断点。命中后可以:
- 单步跳过 / 步入 / 跳出;
- 查看调用栈,精确到
文件:行:列; - 展开 Scope,看
this、闭包、局部变量; - 在 Console 里对当前帧求值。
业务包通常是压缩后的单行文件,所以断点需要 行 + 列 才能定位到准确位置。Chrome 会自动处理。
作用域与求值
暂停时 Scope 面板会显示:
Local
this Window
opt {url: "...", method: "POST"}
id "wmpf_217_"
Closure
seq 217Console 默认落在业务上下文,可以直接访问 wx、getApp()、getCurrentPages()。
渲染层 Elements
渲染层的 target 对应一个 XWeb WebView。连接之后可以:
- 查看真实 DOM 树;
- 选中元素、修改样式;
- 查看页面截图;
- 在 Console 里执行 DOM 操作。
多客户端
逻辑层的 CDP 做了 id 多路复用,同一个逻辑层可以同时接多个 Chrome 标签页。渲染层受 Chromium 限制,同一个 page target 只能有一个调试器。
已知限制
| 限制 | 说明 |
|---|---|
| 业务层调试为实验性 | 「业务层调试」接管 JS 引擎后会阻塞渲染,默认关闭 |
Runtime.evaluate 不要带 awaitPromise | 这个 v8_inspector 构建下会崩溃,需要异步结果请先发起再轮询 |
| 渲染层单调试器 | 同一个 page target 不能同时被两个客户端 attach |
| 换小程序后 target 短暂消失 | isolate 重建,属于正常现象,重新打开即可 |
排障
Chrome 连不上
curl http://127.0.0.1:9400/json/version无响应说明网关没起来:检查 App 是否在前台、端口是否被改过、adb forward 是否成功。
连上了但 Console 里没有 wx
当前上下文不是业务上下文。在 Console 顶部的上下文下拉里切换到 WxaCtx-*,或在 Sources 里打开业务脚本再试。
断点不命中
确认断点落在会执行的代码上;确认没有残留的「暂停」状态;换小程序后重新下断点。
页面白屏
检查是否开启了「业务层调试」,它与渲染互斥。关闭后重启小程序。
内置 WebUI
App 自带的 WebUI 正在逐步开发中。当前版本请使用 Chrome DevTools;WebUI 上线后会在这里更新。