# react-visual-edit-vite **Repository Path**: ai-tools_4/react-visual-edit-vite ## Basic Information - **Project Name**: react-visual-edit-vite - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-26 - **Last Updated**: 2026-02-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### [English](./README.en.md) | 中文 # Visual Edit - 可视化编辑 ## 什么是 Visual Edit - 可视化编辑? 基于 Babel AST 转换的 React 可视化编辑器,支持在浏览器中直接编辑组件样式和文本,并将修改回写到源代码。 ## Visual Edit有什么用? 在大模型能力不断爆发的今天,很多人(包括非程序员)已经开始使用 AI 来制作自己的 Web App,但是不是每一次 AI 的生成都能够符合我们的预期,甚至只是想修改字体的一个颜色都需要 AI 再 re-generate 一遍,这个时候明明只需要改变一个样式代码就可以了。所以在可视化编辑的加持下,将此功能用来做为 AI 生成 Web App 的工程样板文件中的能力之一,这样 AI 更具这个具有可视化编辑的工程样板生成的代码之后,只需要切换编辑模式,就可以轻松的修改页面的样式(背景色、字体大小等等),极大程度节约了 token 的消耗,而且所见即所得,能够精准控制。 ## 说明 此仓库的代码只是一个技术方案示例。 ## 特点 - **可视化编辑** - 直接在浏览器中编辑组件样式和文本 - **实时预览** - 修改即刻反映在界面上 - **内联样式** - 样式以 `style={{ ... }}` 形式写入源码 - **代码回写** - 保存后自动更新源代码文件 - **热模块替换** - 无需刷新页面 - **动态内容保护** - 包含 state 的元素会被标记为不可编辑 ## 技术方案 ### 核心原理 1. **编译时注入** - Vite 插件在 transform 阶段通过 Babel 解析 JSX,为每个元素注入唯一标识符 `data-vid`,同时记录 VID 到源码位置的映射关系 2. **AST 路径定位** - 使用 AST 路径(如 `body.4.body.body.1.argument`)而非行号定位元素,确保代码格式化后仍能准确找到目标节点 3. **运行时编辑** - 浏览器中通过 `data-vid` 识别可编辑元素,样式修改直接操作 DOM 实现实时预览 4. **后端 AST 回写** - 保存时后端根据 VID 查找映射,重新解析源文件为 AST,定位目标节点后更新 `style` 属性,最后生成新代码写入文件 5. **热更新同步** - 文件写入后触发 Vite HMR,页面无刷新更新 ### 整体流程图 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 编译时 (Vite 插件) │ ├─────────────────────────────────────────────────────────────────┤ │ JSX 源码 │ │

Hello

│ │ ↓ │ │ Babel AST 解析 + 遍历 │ │ ↓ │ │ 注入 data-vid 属性 + 检测动态内容 │ │ ↓ │ │

Hello

│ │ │ │ 同时记录 VID → 源码位置映射 (vidMap) │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 运行时 (浏览器) │ ├─────────────────────────────────────────────────────────────────┤ │ 用户点击元素 │ │ ↓ │ │ 获取 data-vid → 显示编辑面板 │ │ ↓ │ │ 用户修改样式 → 实时预览 (直接修改 el.style) │ │ ↓ │ │ 点击保存 → 发送请求到 /__visual_edit │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 后端处理 (Vite 中间件) │ ├─────────────────────────────────────────────────────────────────┤ │ 接收请求 { vid, styles, newText } │ │ ↓ │ │ 从 vidMap 获取文件路径和 AST 路径 │ │ ↓ │ │ 读取源文件 → Babel 解析 → 定位 JSX 节点 │ │ ↓ │ │ 更新 style 属性 (AST 操作) │ │ ↓ │ │ 生成新代码 → 写入文件 │ │ ↓ │ │ 触发 HMR 热更新 │ └─────────────────────────────────────────────────────────────────┘ ``` ## 快速开始 ```bash # 安装依赖 npm install # 启动开发服务器 npm run dev ``` 访问 http://localhost:5173 ## 项目结构 ``` demo-babel/ ├── src/ │ ├── plugins/ # Vite 插件 (编译时 + 后端) │ │ ├── index.ts # 插件主入口 │ │ └── utils/ │ │ ├── ast.ts # AST 操作工具 │ │ └── types.ts # 类型定义 │ ├── utils/ │ │ └── overlay/ # 前端编辑界面 │ │ ├── index.ts # 导出入口 │ │ ├── domElements.ts # UI 元素创建 │ │ └── visualEditOverlay.ts # 交互逻辑 │ ├── App.tsx # 示例应用 │ ├── main.tsx # 应用入口 │ └── index.css # 全局样式 ├── vite.config.ts # Vite 配置 └── package.json ``` --- ## 核心模块详解 ### 1. Vite 插件 (`plugins/index.ts`) 插件在 Vite 的 `transform` 钩子中处理 JSX 文件: ```typescript // 主要功能: // 1. 为每个 JSX 元素注入 data-vid 属性 // 2. 检测动态内容,标记 data-has-state // 3. 建立 VID → 源码位置的映射 // 4. 提供 /__visual_edit API 端点处理编辑请求 ``` **VID 格式**: `文件名:元素名:索引`,例如 `App.tsx:h1:0` **VID 映射表结构**: ```typescript interface VidMapEntry { file: string; // 源文件路径 astPath: string; // AST 导航路径 elementName: string; // 元素名称 classLiteralStart: number; classLiteralEnd: number; } ``` **动态内容检测**: ```typescript // 检测 JSX children 是否包含表达式 // → data-has-state="true" for (const child of jsxElement.children) { if (t.isJSXExpressionContainer(child)) { hasDynamicContent = true; } } ``` ### 2. AST 操作 (`plugins/utils/ast.ts`) 提供精确的源码修改能力: ```typescript // 核心函数: // 生成 AST 路径(编译时) generateASTPath(path) → "body.4.body.body.1.argument.children.3" // 根据路径定位节点(运行时) findNodeByPath(ast, pathString) → JSXElement // 更新代码 updateCodeWithAST(code, astPath, { newClassName?: string, newText?: string, newStyles?: StyleConfig // 内联样式 }) ``` **样式更新逻辑**: ```typescript // 更新或创建 style 属性 // 如果已有 style={{ ... }},会合并样式 // 生成结果示例: // style={{ color: "#ff0000", fontSize: "18px" }} ``` ### 3. 前端编辑界面 (`utils/overlay/`) **domElements.ts** - UI 元素工厂: ```typescript createHighlightBox() // 高亮框 createFileLabel() // 元素名称标签 createToggleButton() // 编辑模式切换按钮 createStylePanel() // 右侧抽屉面板 showToast() // 提示信息 ``` **visualEditOverlay.ts** - 交互逻辑: ```typescript // 状态管理 let enabled = false; let currentEditingElement: HTMLElement | null = null; // 核心函数 highlight(el) // 高亮元素 enterEditMode(el) // 进入编辑 exitEditMode() // 退出编辑 saveStyles() // 保存到后端 ``` --- ## 数据流 ### 编辑保存流程 ``` 用户点击保存 ↓ 收集数据: { vid, styles, newText } ↓ POST /__visual_edit ↓ 后端解析 vid → 获取 VidMapEntry ↓ 读取源文件 → Babel 解析为 AST ↓ findNodeByPath() 定位 JSX 节点 ↓ updateStyleAttribute() 更新 style 属性 ↓ generate() 生成新代码 ↓ 写入文件 → 触发 HMR ``` ### 请求/响应格式 **请求体**: ```typescript interface EditRequest { vid: string; currentClassName?: string; newText?: string; styles?: { color?: string; backgroundColor?: string; fontSize?: string; fontWeight?: string; }; } ``` **响应**: ```json { "ok": true } ``` --- ## 技术栈 | 类别 | 技术 | | -------- | ---------------- | | UI 框架 | React 19 | | 构建工具 | Vite 7 | | AST 解析 | @babel/parser | | AST 遍历 | @babel/traverse | | AST 生成 | @babel/generator | | 类型系统 | TypeScript | | 样式 | Tailwind CSS 4 | --- ## 注意事项 1. **仅开发模式** - 编辑功能只在 `npm run dev` 时可用 2. **版本控制** - 修改会直接写入源文件,建议使用 Git 3. **动态内容** - 包含 `{state}` 表达式的元素不可编辑 4. **文本元素** - 仅支持 p, span, button, h1-h6, a, label, div 等文本元素 --- ## 许可证 MIT