react-spot
v0.0.10
Published
Option-key React component inspector with open-in-editor support.
Maintainers
Readme
react-spot
按住 Option/Alt 即可检查鼠标下的 React 组件:左键优先打开当前 DOM 标签的精确 JSX 位置,右键显示从当前组件到顶层组件的树形菜单。
react-spot 不需要 React DevTools 浏览器扩展。它把 React/React DevTools 中与 Fiber 查找、当前分支判断、组件命名和 owner stack 解析有关的逻辑移植到了 src/react-devtools,并用 Shadow DOM 隔离 Inspector UI。
功能
- 按住
⌥ Option(Windows/Linux 为Alt)显示目标元素边框和用户组件面包屑。 - 按住 Option 时左键点击,优先打开当前 DOM Host Fiber 的 JSX 创建位置;不可用时降级到最近用户组件源码。
- 按住 Option 时右键点击,显示当前组件 → 顶层组件菜单;点击任意菜单项打开它在父组件中的使用位置。
- 自动过滤 DOM 标签、React 内建组件、Next.js 路由/运行时以及
node_modules组件。 - React 18
_debugSource、React 19 owner stack 和 React 19 Server Component debug info 兼容。 - 组件定义定位采用 React DevTools 的 owner-instance 推断:在 commit 阶段以及按需扫描时,将
owner → owned child的可信源码栈缓存到当前/alternate Fiber;因此目标节点自身变成UnknownOwner后,仍可精确打开组件定义位置。 - 复用 React DevTools 的 Source Map symbolication 流程,将 webpack/Turbopack chunk 位置还原为原始源码,并根据 source-map
ignoreList排除框架组件。 - 编辑器 URL 校验、路径处理和打开行为与 React DevTools 一致;默认使用
vscode://file/{path}:{line}:{column}。
安装与接入
pnpm add react-spot在 Next.js App Router 的根布局中挂载:
import {ReactSpot} from 'react-spot';
export default function RootLayout({children}: {children: React.ReactNode}) {
return (
<html>
<body>
{children}
{process.env.NODE_ENV === 'development' ? (
<ReactSpot projectRoot={process.cwd()} />
) : null}
</body>
</html>
);
}projectRoot 用于把 Turbopack/webpack stack 中的相对文件名还原为编辑器可打开的绝对路径。
自定义编辑器
<ReactSpot editorScheme="cursor" />
支持 `cursor`、`vscode`、`vscode-insiders`、`windsurf` 等编辑器协议。默认仍为 VS Code;如果需要完整控制 URL,也可以使用模板:
```tsx
<ReactSpot editorUrl="cursor://file/{path}:{line}:{column}" />
也可以完全接管打开动作:
```tsx
<ReactSpot
openInEditor={({component, location, sourceKind}) => {
console.log(component?.name, sourceKind, location);
}}
/>Turbopack example
pnpm install
pnpm dev访问终端中 Next.js 输出的 Local 地址,把鼠标放在大标题上并按住 Option。根目录的 dev 命令会先构建库,再以 next dev --turbopack 启动 example;默认端口被占用时 Next.js 会自动选择其他端口。
首页右侧的入口会打开 /owner-stacks 压力测试页。该页面先创建 10,500 个 JSX 节点,再创建测试按钮。选中测试按钮后,DOM JSX 位置可能因 UnknownOwner 回退,但组件菜单中的定义位置应能通过之前的 owned child 精确推断;切换到 100 个节点后,可对比直接 DOM JSX 定位。
API
| Prop | 类型 | 说明 |
| --- | --- | --- |
| enabled | boolean | 是否启用;默认仅非 production 环境启用。 |
| projectRoot | string | 项目绝对路径,用于解析相对源码路径。 |
| openInEditor | (context) => void \| Promise<void> | 自定义编辑器打开逻辑。 |
| editorScheme | string | 编辑器协议,例如 cursor、vscode、windsurf;默认 vscode。editorUrl 未设置时生效。 |
| editorUrl | string | {path}、{line}、{column} URL 模板。 |
| filterComponent | (component) => boolean | 对已过滤结果做额外筛选。 |
| onInspect | (components) => void | 鼠标进入新的组件链时触发。 |
| popoverFooter | ReactNode | 右键菜单底部自定义内容。 |
注意
- 源码定位依赖 React development build 的 Fiber 调试字段,生产 React 构建通常不会提供这些字段。
- React 内部 Fiber 字段不是公开 API;本库对 React 18/19 做了兼容和降级,但未来 React 大版本仍可能需要更新适配。
- React 19 开发模式达到内部 owner-stack 预算后会复用
UnknownOwner栈;本库沿用 React DevTools 的 bottom sentinel 校验,并额外识别共享的UnknownOwner栈,不会把两者标记为精确位置。此时会降级到仍可信的组件位置,无法恢复 React 已经丢弃的原始 JSX 调用点。 - 顶层框架入口组件没有用户父组件时,菜单会回退到组件定义中的第一个可定位 JSX 位置。
sourceKind === 'dom'表示精确 DOM JSX;definition和usage分别表示组件定义与父组件使用位置。
移植代码的许可说明见 THIRD_PARTY_NOTICES.md。
