反解 UI 节点树
运行时一个 Lynx 页面就是一棵 UI 节点树,也就是引擎真正渲染出来的那些元素。UI source map 让你把树里的每个节点映射回创建它的 JSX(repo、source、line、column)。
它分三步:
- 构建:打开
enableUiSourceMap,把 UI source map 写进debug-metadata.json,并给元素打上nodeIndex。 - 导出:让 Lynx 客户端把运行时 UI 树序列化成 JSON。
- 反解:把这份 JSON 加上
debug-metadata.json喂给remapUiTree,它会给每个节点标注源码位置。
1. 开启开关
UI source map 生成默认是关的。在 pluginReactLynx 里打开:
打开后,主线程的 transform 会给每个创建出来的元素打上 nodeIndex,并记录一张 nodeIndex → (source, line, column) 表。这张表会作为 debug-metadata.json 的 uiSourceMap 字段产出:
要让运行时指向这个文件,模板里还得带上它的 debugMetadataUrl:连到 dev server 时会自动写入,生产环境则要你自己注入(见 线上错误反解 → 方案 2)。否则导出的节点 debugMetadataUrl 为空,没法反解。
2. 从客户端导出 UI 树
三端用法一致:从 LynxView 异步拿到根 LynxElement,再对它调 toJSONString 把整棵树序列化出来。两个 callback 都会回调到 UI 线程(主线程)。
序列化出来的每个节点长这样,反解需要的 nodeIndex 和 debugMetadataUrl 这两个字段嵌在 debugInfo 里:
nodeIndex 是第 1 步里给的编译期标识;debugMetadataUrl 是写进模板的那个 URL。没有 debugInfo.nodeIndex 的节点(比如纯文本)不会被反解。
3. 反解这棵树
@lynx-js/debug-metadata 的 remapUiTree 读取的是每个节点顶层的 nodeIndex 和 debugMetadataUrl,而引擎把它们嵌在 debugInfo 里,所以先把它们提上来再反解。它的第二个参数是一个由你提供的 loader,负责把一个 debugMetadataUrl 取成对应的 DebugMetadataAsset:
凡是 nodeIndex 能在对应 debugMetadataUrl 的 uiSourceMap 里命中的节点,都会拿到 repo / source / line / column;命中不了的节点,连同节点上原有的其它字段,都原样保留。remapUiTree 对每个不同的 debugMetadataUrl 只调用一次 loader。
npx @lynx-js/debug-metadata remap --ui <tree.json> CLI 做的是同样的事,适用于节点已经在顶层带有 nodeIndex / debugMetadataUrl 的树。更底层的 buildUiSourceMapLookup(nodeIndex → 位置)和 normalizeRepo(git remote → owner/repo)辅助函数也都有导出。