aidenybai/react-grab

GitHub: aidenybai/react-grab

一款 React 开发者工具,可从网页 UI 元素中一键提取组件上下文信息,用于提升 AI 编程助手的准确性和效率。

Stars: 6175 | Forks: 285

# React Grab [![大小](https://img.shields.io/bundlephobia/minzip/react-grab?label=gzip&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/package/react-grab) [![版本](https://img.shields.io/npm/v/react-grab?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/react-grab) [![下载量](https://img.shields.io/npm/dt/react-grab.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/react-grab) 直接从您的网站为编码智能体选择上下文。 如何使用?指向任意元素并按下 **⌘C** (Mac) 或 **Ctrl+C** (Windows/Linux) 即可复制文件名、React 组件和 HTML 源代码。 它能让 Cursor、Claude Code、Copilot 等工具的运行速度提升 [**3 倍**](https://react-grab.com/blog/intro) 且更加准确。 ### [试用演示!→](https://react-grab.com) ![React Grab 演示](https://github.com/aidenybai/react-grab/blob/main/packages/website/public/demo.gif?raw=true) ## 安装 在您的项目根目录(即 `next.config.ts` 或 `vite.config.ts` 所在位置)运行此命令: ``` npx -y grab@latest init ``` ## 连接到 MCP ``` npx -y grab@latest add mcp ``` ## 使用方法 安装完成后,在浏览器中悬停任意 UI 元素并按下: - Mac 上按 **⌘C** (Cmd+C) - Windows/Linux 上按 **Ctrl+C** 这会将元素的上下文(文件名、React 组件和 HTML 源代码)复制到剪贴板,以便粘贴到您的编码智能体中。例如: ``` Forgot your password? in LoginForm at components/login-form.tsx:46:19 ``` ## 手动安装 如果您正在使用 React 框架或构建工具,请查看下方说明: #### Next.js (App Router) 将此内容添加到您的 `app/layout.tsx` 中: ``` import Script from "next/script"; export default function RootLayout({ children }) { return ( {process.env.NODE_ENV === "development" && (
``` #### Webpack 首先,安装 React Grab: ``` npm install react-grab ``` 然后在您的主入口文件顶部(例如 `src/index.tsx` 或 `src/main.tsx`)添加: ``` if (process.env.NODE_ENV === "development") { import("react-grab"); } ``` ## 插件 React Grab 可以通过插件进行扩展。插件可以添加上下文菜单操作、工具栏菜单项、生命周期钩子和主题覆盖。 通过 `window.__REACT_GRAB__` 注册插件: ``` window.__REACT_GRAB__.registerPlugin({ name: "my-plugin", hooks: { onElementSelect: (element) => { console.log("Selected:", element.tagName); }, }, }); ``` 在 React 中,在 React Grab 加载后的 `useEffect` 中注册: ``` useEffect(() => { const api = window.__REACT_GRAB__; if (!api) return; api.registerPlugin({ name: "my-plugin", actions: [ { id: "my-action", label: "My Action", shortcut: "M", onAction: (context) => { console.log("Action on:", context.element); context.hideContextMenu(); }, }, ], }); return () => api.unregisterPlugin("my-plugin"); }, []); ``` Actions 使用 `target` 字段来控制其显示位置。省略 `target`(或设置为 `"context-menu"`)用于右键菜单,或设置 `"toolbar"` 用于工具栏下拉菜单: ``` actions: [ { id: "inspect", label: "Inspect", shortcut: "I", onAction: (ctx) => console.dir(ctx.element), }, { id: "toggle-freeze", label: "Freeze", target: "toolbar", isActive: () => isFrozen, onAction: () => toggleFreeze(), }, ]; ``` 请参阅 [`packages/react-grab/src/types.ts`](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/types.ts) 以获取完整的 `Plugin`、`PluginHooks` 和 `PluginConfig` 接口。 ## 原语 (Primitives) React Grab 提供了一组原语,用于构建您自己的迷你版 React Grab。 这是一个简单的示例,展示如何构建您自己的元素选择器,具有悬停高亮和一键检查功能: ``` npm install react-grab@latest ``` 然后,将其放入您的 React 应用中: ``` import { useState } from "react"; import { getElementContext, freeze, unfreeze, openFile, type ReactGrabElementContext, } from "react-grab/primitives"; const useElementSelector = ( onSelect: (context: ReactGrabElementContext) => void, ) => { const [isActive, setIsActive] = useState(false); const startSelecting = () => { setIsActive(true); const highlightOverlay = document.createElement("div"); Object.assign(highlightOverlay.style, { position: "fixed", pointerEvents: "none", zIndex: "999999", border: "2px solid #3b82f6", transition: "all 75ms ease-out", display: "none", }); document.body.appendChild(highlightOverlay); const handleMouseMove = ({ clientX, clientY }: MouseEvent) => { highlightOverlay.style.display = "none"; const target = document.elementFromPoint(clientX, clientY); if (!target) return; const { top, left, width, height } = target.getBoundingClientRect(); Object.assign(highlightOverlay.style, { top: `${top}px`, left: `${left}px`, width: `${width}px`, height: `${height}px`, display: "block", }); }; const handleClick = async ({ clientX, clientY }: MouseEvent) => { highlightOverlay.style.display = "none"; const target = document.elementFromPoint(clientX, clientY); teardown(); if (!target) return; freeze(); onSelect(await getElementContext(target)); unfreeze(); }; const teardown = () => { document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("click", handleClick, true); highlightOverlay.remove(); setIsActive(false); }; document.addEventListener("mousemove", handleMouseMove); document.addEventListener("click", handleClick, true); }; return { isActive, startSelecting }; }; const ElementSelector = () => { const [context, setContext] = useState(null); const selector = useElementSelector(setContext); return (
{context && (

Component: {context.componentName}

Selector: {context.selector}

{context.stackString}
)}
); }; ``` 请参阅 [`packages/react-grab/src/primitives.ts`](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/primitives.ts) 以获取完整的 `ReactGrabElementContext`、`getElementContext`、`freeze`、`unfreeze` 和 `openFile` 原语。 ## 资源与贡献 想试试看?请查看[我们的演示](https://react-grab.com)。 想要回馈贡献?请查看[贡献指南](https://github.com/aidenybai/react-grab/blob/main/CONTRIBUTING.md)。 想与社区交流?欢迎加入我们的 [Discord](https://discord.com/invite/G7zxfUzkm7),分享您的想法以及您用 React Grab 构建的内容。 发现了错误?请前往我们的[问题追踪器](https://github.com/aidenybai/react-grab/issues),我们会尽力提供帮助。我们也非常欢迎 Pull Requests! 我们希望所有贡献者遵守我们的[行为准则](https://github.com/aidenybai/react-grab/blob/main/.github/CODE_OF_CONDUCT.md)。 [**→ 在 GitHub 上开始贡献**](https://github.com/aidenybai/react-grab/blob/main/CONTRIBUTING.md) ### 许可证 React Grab 是采用 MIT 许可的开源软件。 _感谢 [Andrew Luetgers](https://github.com/andrewluetgers) 捐赠了 `grab` npm 包名。_
标签:AI编程助手, Chrome插件, Claude, Copilot, Cursor, CVE检测, DOM操作, HTML源码, MCP, React, React Grab, Syscalls, Vite, 上下文提取, 代码片段, 前端调试, 响应拦截, 大模型上下文, 威胁情报, 开发者工具, 提效工具, 智能编码, 浏览器扩展, 源码复制, 生产力, 组件定位, 网络调试, 自动化, 自动化攻击, 调试插件