web-source-inspect README

The project's README from github.com/shaojie-li/web-source-inspect. As one markdown file: README.md.

React Trace

An experimental, zero-integration Chrome extension that maps an element in a React development page back to the JSX/TSX source that created it, then opens that location in VS Code or Cursor.

React Trace demo

No project-code changes required. Load the extension in Chrome; do not add a package, a Babel/Vite plugin, or application instrumentation. React Trace reads the React runtime and source maps already available in your development page.

Experimental. React Trace relies on React development-only internals and accessible source maps. It is intended for local development, not production pages.

Why

When inspecting a React UI, browser DevTools can show the DOM and styles but not always the source line that created an element. React Trace shortens that loop without modifying the project being inspected:

  1. Hold Alt and point at an element.
  2. See its source location and React component chain.
  3. Pin the result with Alt + click.
  4. Open the exact JSX/TSX location in your editor.

Features

Quick start

1. Load the extension

  1. Open chrome://extensions.
  2. Enable Developer mode.
  3. Choose Load unpacked and select this repository directory.
  4. Reload the extension and then reload the target page whenever extension code changes.

2. Run the included demo

pnpm --dir demo install
pnpm --dir demo dev

Open http://localhost:5173. The demo is only for verification; any supported local React development page works after loading the extension. The extension is injected only on http://localhost/* and http://127.0.0.1/*.

3. Configure the project root

For React 19, React Trace may need an absolute project root to turn a source-map path into a local file path. Click Settings in the result card, or open the extension options page, and map the page origin to the project directory:

http://localhost:5173 -> /absolute/path/to/source-inspect/demo

The setting is stored locally in Chrome. If the isolated-world bridge is unavailable, the extension falls back to page localStorage.

Usage

Gesture Result
Hold Alt and move the pointer Shows a blue outline and a live source-location hint.
Alt + click an element Pins an orange outline and opens a result card.
Click a blue location in the card Opens the file, line, and column in the selected editor.
Press Esc, click ×, or click outside the card Closes the pinned result.

The result card can show two different but useful concepts:

They can differ when a parent creates an element and passes it to a child as children or another prop.

Demo coverage

The demo exercises the cases that are easiest to get wrong:

  1. Simple elements in one file.
  2. List rendering across TodoCard.tsx and TodoItem.tsx.
  3. Nested memo and forwardRef components.
  4. DOM inserted with innerHTML, which has no Fiber and must fall back to a React ancestor.
  5. An element passed through a prop, where source location and Fiber ownership differ.
  6. A dropdown with a fullscreen mask that would otherwise steal event.target.

Supported environments and limitations

Area Current behavior
Browser Chrome 111+; the extension uses Manifest V3 world: "MAIN".
Hosts http://localhost/* and http://127.0.0.1/* only. HTTPS localhost, LAN IPs, and custom hosts are not injected.
React React development builds only. React 18.3.1 and 19.2.8 were verified.
Production builds Unsupported: React's debug source data is not available.
Source maps Required for the React 19 path; the served module and its map must be fetchable from the page.
Editors VS Code and Cursor. Other editors can be added to the EDITORS list in content.js.
Caching Parsed source maps are cached in memory without a size cap. HMR query strings can create duplicate cache entries.

How it works

React Trace uses a small two-script architecture because React Fiber expandos are visible only from the page's main world, while chrome.storage is available only from the extension's isolated world.

File Context Responsibility
content.js Main world Reads React Fiber data, resolves source maps, renders the overlay/card, and opens editors.
bridge.js Isolated world Proxies configuration reads and writes through chrome.storage.local.
options.html / options.js Extension page Manages the editor choice and origin-to-project-root mappings.

React 18 and React 19

React runtime Signal Resolution
React 18 fiber._debugSource Already contains a source file, line, and column.
React 19 fiber._debugStack Provides a generated JSX call site; React Trace parses the source map to recover the original source location.

For path inference, the extension prefers explicit paths over guesses: Vite /@fs/ URLs, compiler-injected fileName values, absolute sources, sourceRoot, then a configured project root combined with the module URL or normalized sources path. If it cannot infer a safe absolute path, it reports the failure instead of opening a guessed file.

Verification

Run the focused Node tests:

node test/path-infer.test.mjs
node test/placement.test.mjs

Build the React demo:

pnpm --dir demo build

To compare React runtime behavior without installing dependencies, start a local server from the repository root:

python3 -m http.server 5200

Then open React 19 or React 18.

Roadmap

Contributing

This is an early-stage prototype. When reporting an issue, include the React version, bundler and dev-server version, module URL, source-map shape, and the expected versus actual source location. Run the verification commands above before submitting a change.

License

Licensed under the Apache License 2.0.

web-source-inspect (shaojie-li/web-source-inspect)

Searching Database…

这是什么?React Trace 是一个实验性的 Chrome 扩展,可以把页面上的 React 元素对应回创建它的 JSX/TSX 源码位置,并在 VS Code 或 Cursor 中直接打开那一处。
它是一个浏览器扩展吗,还是我得在项目里装点东西?它是一个纯浏览器扩展:不需要安装任何包,不需要 Babel/Vite 插件,不需要对源码做转换,也不用改动你的应用代码。
我怎么把它装到 Chrome 里?打开 chrome://extensions,开启开发者模式,然后选择“加载已解压的扩展程序”,再选中这个仓库的目录。
主要有哪些限制?只支持 React 的开发版构建(已验证 18.3.1 和 19.2.8),需要 Chrome 111 及以上,而且只会在 localhost 页面上注入。生产版构建不支持,因为 React 的调试源码数据在这种情况下不可用。
结果卡片里的“源码位置”和“组件链”有什么区别?源码位置是创建该元素的 JSX 表达式;组件链是这个元素在 Fiber 树中的归属关系。当父组件创建了一个元素,再把它作为 children 或其他 prop 传给子组件时,两者可能不一致。
它能处理棘手的元素吗,比如 Portal 或者在 React 之外注入的 DOM?可以。对于全屏遮罩和 Portal,它会通过 elementsFromPoint() 来检查,并在页面自己的事件处理器运行之前捕获 Alt+点击;对于没有 Fiber 的 DOM(比如通过 innerHTML 插入的内容),它会回退到最近的 React 祖先。
接下来的计划是什么?把大体量的 source-map 解析移到 worker 中并加上有上限的缓存,在缓存前规范化 HMR 模块的 URL,以及验证更多的打包器和各框架专属的元素检查路径。
Creator
shaojie-li
Size
2.9 MB
Stars
193
Updated
CommitAug 12
Age
2mo
Commits · 90 Days