背景
Mobile 日常维护遇到大部分页面组件无法快速定位到准确位置,经常需要花 1~2 分钟识别页面关键字,全局搜索定位组件,这样的方式实在是太原始了,急需一个 click-to-component 的工具提升效率
调研
研发现市面上并没有可参考的资料,只有闭源的 Radon-ide 提供了 click-to-component 功能
Radon-ide 的实现方案
- 手动替换 Dev 下的 react 编译器版本,让其回到留有 Fiber debug source 的版本,其管理的范围在 react 18 之后的版本

- 实现方法:
- 创建自定义的 react babel transform,将可用版本的 babel_transform.js 拷贝到本地
- 将自定义的 react babel transform 在开发模式下转为用指定版本的 babel_transform.js
- 优点:
- 可直接使用现成的 Fiber debug source 去获得组件跳转所需的数据
- 缺点:
- 开发与生产两个版本的 transform 可能会引发未知问题
- Transform 版本与 react-native 版本不一致埋下隐患
系统设计

- 数据端
- 自定义 Inspector babel 插件
- 核心能力:遍历 JSXElement 节点,自动注入源码定位属性
- 关键逻辑:
- 跳过 Fragment 元素(不支持自定义属性)
- 避免重复注入 __inspectorSource 属性
- 提取元素名、文件路径(保留 src/ 路径)、行号、列号
- 组装属性值为包含 file/line/column/element 的对象
- 自定义 Inspector babel 插件
- 应用端
- 封装 Inspector 核心组件
- InspectorWrapper 组件(核心容器)
- 仅在 DEV 环境生效,生产环境直接返回子组件
- 添加「Toggle Inspector」开发菜单,控制调试开关
- 包裹业务组件,绑定手势响应器(PanResponder)
- 渲染高亮层(InspectorHighlight)和弹窗层(InspectorPopover)
- useInspector 核心 Hook
- 手势处理:监听点击/触摸事件,定位点击位置的组件
- 组件信息获取:
- 调用 RN 底层 API 获取组件帧信息、props、style
- 提取 __inspectorSource 源码定位信息
- 收集最多 5 层祖先组件的源码信息
- 编辑器跳转:
- 判断组件是否在屏蔽列表(blockComponents)
- 向服务端发送 __open-in-editor 请求
- 屏蔽组件则尝试跳转祖先组件源码
- 辅助函数:
- getSourceFromNodeClosestFiber:从 Fiber 节点提取源码信息
- isBlockedComponent:判断组件是否需要屏蔽
- 辅助组件/工具
- InspectorHighlight:渲染组件选中高亮框
- InspectorPopover:展示组件尺寸、props、style、源码信息
- stringifyPropsForDisplay:格式化 props/style 用于展示
- InspectorWrapper 组件(核心容器)
- 封装 Inspector 核心组件
- 服务端
- Metro 中间件服务
- 开启 Inspector 中间件,监听 /__open-in-editor 请求
- 接收应用端传递的 source 数据(file:line:column 格式)
- 执行指定 Editor 指令(可支持本地配置不同的 Edit ),跳转到对应代码位置
- Metro 中间件服务
踩坑问题
- 应用端编写过程中,无法准确获取鼠标点击时挂载在组件上的数据
- 跑在模拟器上的代码并不是 React 代码,实际是 RN 转换过后的 Native 代码
- RN 提供的 API 无法获取点击元素的组件信息
解决方法: - 通过 RN PanResponder 绑定点击获取元素的坐标
- 通过 RN 提供的 Inspector 方法 getInspectorDataForViewAtPoint 获取到 Node 节点
- 通过获取到该 Node 节点最近的 Fiber 实例来获取到挂载的 Props 数据
- 点击后跳转的可能是 node_modules 或者 MoeText 等基础组件
解决办法: - 注入数据时,将父组件向上获取 5 层并一同注入
- 点击组件后处理,如果被点击识别到的是"干扰"组件则替换为使用父组件中寻找首个最近的"有效"组件进行跳转,大大提高了跳转到期望组件的概率
核心难点总结
-
缺少可参考实现,方案需要从零探索验证
业界几乎没有"可直接套用"的完整链路(源码注入 → 端侧命中 → 信息展示 → 打开编辑器),只能通过阅读零散资料与不断试错逐步拼出可行方案
心得:遇到无从下手的大问题,先拆成若干可验证的小问题;每一步做最小闭环验证,最终自然收敛为完整方案
-
端侧如何"命中"被点击的组件,并获取与可视化有效信息
难点不只是拿到点击坐标,而是把坐标映射到具体组件区域,并进一步提取到该组件携带的源码定位、props/style、尺寸位置等信息,最后以高亮框与信息面板形式呈现
心得:先定义目标体验(点哪、亮哪、显示什么),再围绕体验拆解链路,做一组递进 Demo 验证关键环节,逐步组合成稳定方案
-
精准跳转到"目标业务组件",避免落到无效组件
实际点击往往会命中大量包装层/容器层/框架组件(例如 View、Text、Touchable 等),即便拿到 Fiber 也可能定位到"不可读、不可改、无意义"的源码位置
需要设计屏蔽策略与回溯策略(如 blockComponents + 祖先向上查找),确保最终跳转落在最有价值的业务组件上
-
服务端承接跳转请求,并驱动本地编辑器准确定位
应用端发起打开请求后,服务端需要正确解析 source(file/line/column),兼容不同编辑器的打开方式与参数差异,并保证在本地环境可用、稳定、可配置