20 — 开发者指南
从零开始运行、开发、调试、部署 dodo-agent 前端。
包含:环境搭建、开发流程、移动端调试、主题开发、生产部署。
1. 环境要求
| 工具 | 版本 | 验证 |
|---|
| Node.js | >= 18 | node -v |
| npm | >= 9 | npm -v |
Node.js 安装:
2. 快速开始
2.1 启动开发服务器
1 2 3 4 5 6 7 8
| cd agent/dodo-agent-frontend
npm install
npm run dev
|
启动后你会看到:
1 2 3 4 5
| VITE v5.4.10 ready in 500 ms
➜ Local: http://localhost:5173/ ➜ Network: http://192.168.x.x:5173/ ➜ press h + enter to show help
|
打开浏览器访问 http://localhost:5173 即可。
2.2 可用脚本
1 2 3 4
| npm run dev npm run build npm run preview npm run typecheck
|
3. 项目结构速览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| agent/dodo-agent-frontend/ ├── index.html ← 入口 HTML(viewport-fit=cover + 字体预加载) ├── package.json ← 依赖配置 ├── vite.config.ts ← 构建配置(代理 /api) ├── tsconfig.json ← TS 配置(含 @/ 别名) ├── docs/ ← 前端文档(本目录) │ └── src/ ├── main.tsx ← React 应用入口 ├── App.tsx ← 根组件(协调 Topbar / Sidebar / ThemeSwitcher) ├── App.module.css ← 根布局(position: fixed + safe-area) │ ├── styles/ │ ├── tokens.css ← 设计令牌(6 主题分组,data-theme 切换) │ └── global.css ← 全局 reset、背景水墨 │ ├── types/api.ts ← 后端 API 类型定义 ├── constants/ ← agents / streamTypes │ ├── api/ ← 后端 API 封装 ├── store/ │ ├── chatStore.ts ← 全局聊天状态(Zustand + Immer)⭐ │ └── themeStore.ts ← 全局主题状态 ⭐ │ ├── hooks/ ← 自定义 Hook ├── utils/ ← 工具函数 │ └── components/ ← 18 个组件 ├── Sidebar/ ← 侧边栏 ├── MessageList/ ← 消息列表 + 空状态 ├── Message/ ← 单条消息 + Markdown / Timeline / Reference ├── InputArea/ ← 输入区 + AgentSelector + FilePreview ├── Topbar/ ← 顶栏(豆豆 logo + 主题) ├── ThemeSwitcher/ ← 主题切换面板 ├── ConfirmDialog/ ← 确认弹窗 └── ConnectionError/ ← 连接错误
|
4. 依赖管理
4.1 常用命令
1 2 3 4 5 6
| npm install npm install xxx npm install -D xxx npm uninstall xxx npm update npm outdated
|
4.2 核心依赖说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", "zustand": "^4.5.5", "immer": "^10.2.0", "react-markdown": "^9.0.1", "remark-gfm": "^4.0.0", "rehype-highlight": "^7.0.0", "rehype-sanitize": "^6.0.0", "highlight.js": "^11.10.0", "lucide-react": "^0.460.0" }, "devDependencies": { "vite": "^5.4.10", "@vitejs/plugin-react": "^4.3.3", "typescript": "^5.5.4", "@types/react": "^18.3.12" } }
|
4.3 不要手动改 package-lock.json
npm install 会自动生成/更新 package-lock.json,记录每个依赖的确切版本。始终用 npm 命令,不要手动编辑。
5. 开发流程
5.1 典型工作流
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1. 接到需求(修改 / 新功能) ↓ 2. 在 README.md(docs/frontend/)找对应章节 ↓ 3. 找到要改的文件 ↓ 4. 修改代码(Vite 自动热更新,浏览器立即看到效果) ↓ 5. typecheck 验证 ↓ 6. build 验证 ↓ 7. 提交 git
|
5.2 修改样式(最常见)
5.3 加新功能(业务流程)
5.4 加新主题
详见 16-主题系统与ThemeSwitcher.md 第 7 节。
5.5 加新组件
5.6 加新 API 接口
6. 调试技巧
安装浏览器扩展:React Developer Tools
打开 DevTools → Components 标签 → 查看组件树、Props、State。
6.2 Zustand 调试
1 2 3 4 5 6 7
| useChatStore.getState().sendMessage() useChatStore.getState().loadChats()
console.log(useChatStore.getState()) console.log(useThemeStore.getState())
|
6.3 调试 SSE
- DevTools → Network → 过滤
stream - 发消息 → 点击
chat/stream 请求 → Response 标签 - 实时看到推送的数据
6.4 调试主题切换
1 2
| document.documentElement.setAttribute('data-theme', 'paper')
|
6.5 移动端调试(重要!)
详见 17-移动端适配实战.md 第 9 节。
1 2 3 4 5 6
|
npm run dev -- --host
|
或在 Chrome DevTools 用手机模拟(Ctrl+Shift+M)。
6.6 vConsole(移动端调试神器)
如果想看移动端 console:
1 2 3 4 5 6
| if (import.meta.env.DEV) { import('vconsole').then(({ default: VConsole }) => { new VConsole(); }); }
|
DevTools 元素检查器在移动端不方便,vConsole 提供浮动的 console 面板。
6.7 常见错误
| 错误 | 原因 | 解决 |
|---|
| 页面空白,后端红色提示 | 后端没启动 | 启动后端 |
Failed to fetch | 跨域 / 后端地址错 | 检查 vite.config.ts 的 proxy |
| 热更新失效 | 缓存问题 | Ctrl+R 硬刷新,或重启 dev |
| TS 报错但代码看起来对 | 类型不匹配 | 仔细看报错信息 |
| CSS 没生效 | 类名拼写错 | 检查 className 与 CSS 文件 |
| 主题不切换 | data-theme 没设置 | 检查 themeStore 和 global.css |
| 移动端输入框被盖住 | 100vh 高度问题 | 用 position: fixed; inset: 0 |
| Chrome 移动端看到地址栏遮挡 | 同上 | 已修复(见 global.css) |
7. 性能优化
7.1 项目目前没做的优化
- ❌
React.memo 包裹组件 - ❌
useMemo 缓存计算(仅用了一处) - ❌
useCallback 缓存函数 - ❌ 代码分割(dynamic import)
为什么?数据量小(聊天列表不会很长),不需要过早优化。
7.2 如果遇到性能问题怎么优化
1 2 3 4 5 6 7 8 9 10 11 12
| import { memo } from 'react';
const ChatItem = memo(function ChatItem({ chat, active, onSelect, onDelete }) { return <div>...</div>; });
const filteredList = useMemo( () => chatList.filter(c => c.title.includes(keyword)), [chatList, keyword] );
|
7.3 主题切换性能
主题切换是纯 CSS 变量切换,不触发 React 重渲染(Topbar 显示主题名除外),性能极佳。
8. 构建生产版本
8.1 构建
输出在 dist/ 目录:
1 2 3 4 5
| dist/ ├── index.html # 1.35 kB(gzip: 0.72 kB) └── assets/ ├── index-xxxxxxx.css # 28 kB(gzip: 5.9 kB) └── index-yyyyyyy.js # 530 kB(gzip: 165 kB)
|
文件名带 hash 是为了浏览器缓存:内容变了 hash 才变。
8.2 预览生产版本
1 2
| npm run build npm run preview
|
9. 部署
9.1 方式 A:Nginx 反向代理(推荐)
步骤:
1 2 3 4 5 6 7 8
| npm run build
scp -r dist/* user@server:/var/www/dodo-agent/dist/
ssh user@server 'sudo systemctl reload nginx'
|
Nginx 配置(含 SSE 特殊处理):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| server { listen 80; server_name your-domain.com; root /var/www/dodo-agent/dist; index index.html;
location / { try_files $uri $uri/ /index.html; }
location /api/ { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
location /api/chat/stream { proxy_pass http://localhost:8080; proxy_buffering off; proxy_cache off; proxy_read_timeout 300s; proxy_set_header Connection ''; proxy_http_version 1.1; }
location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; } }
|
9.2 方式 B:与后端一起打包
如果是 Spring Boot 项目,可以把 dist/ 内容放到 src/main/resources/static/,后端启动时自动提供。
1 2 3 4 5 6 7 8 9 10 11 12
| npm run build
cp -r dist/* ../dodo-agent-backend/src/main/resources/static/
cd ../dodo-agent-backend mvn clean package
java -jar target/dodo-agent-0.0.1-SNAPSHOT.jar
|
10. 环境变量
10.1 创建 .env 文件
1 2 3 4 5 6 7
|
VITE_API_BASE=/api
|
10.2 读取环境变量
1 2
| const apiBase = import.meta.env.VITE_API_BASE;
|
10.3 .env 文件优先级
1 2 3
| .env # 所有环境 .env.development # 仅开发 .env.production # 仅生产
|
11. Git 工作流
11.1 提交前检查
1 2 3 4 5 6 7 8 9
| npm run typecheck
npm run build
git add . git commit -m "feat: 添加 XXX 功能"
|
11.2 推荐的提交规范
1 2 3 4 5 6 7
| feat: 新功能 fix: 修复 bug docs: 文档更新 style: 样式修改(不影响逻辑) refactor: 重构 test: 测试相关 chore: 杂项(依赖、配置)
|
11.3 不要提交
1 2 3 4 5
| node_modules/ # 依赖目录 dist/ # 构建产物 .env.local # 本地环境变量 *.log # 日志 .DS_Store # macOS
|
12. 常见任务速查
| 任务 | 步骤 |
|---|
| 改主色 | tokens.css 里改 --color-primary |
| 改圆角 | tokens.css 里改 --radius-md |
| 加新主题 | 3 步:① 主题元数据 ② tokens.css 块 ③ getPrimaryColor 映射 |
| 加新 Agent | constants/agents.ts 加 Agent |
| 加新事件类型 | constants/streamTypes.ts + applyEvent |
| 改 API 地址 | api/client.ts 或 .env |
| 改后端接口 | api/*.ts + types/api.ts |
| 改输入区高度 | InputArea.module.css 的 max-height |
| 改主题 | 在 ThemeSwitcher 点选;或编辑 tokens.css |
| 移动端调试 | Chrome DevTools 模拟 + 真机 --host |
13. 推荐的学习资源
14. 一段话总结
开发流程:npm install → npm run dev → 改代码(自动热更新) → npm run build。
调试:DevTools + React Developer Tools + 控制台 store.getState()。
移动端:Chrome 模拟 + 真机 --host 测试。
部署:npm run build 把 dist/ 上传到 Nginx(含 SSE 关闭缓冲)。
改主题:在 ThemeSwitcher 点选,或编辑 tokens.css。
加新功能:Store 加 action → 组件加 UI → 调 action。
🎉 至此,全部 20 篇文档完成!
文档路径:docs/frontend/
索引文档:docs/frontend/README.md
文档地图
| 阶段 | 文档 |
|---|
| 🌱 前置基础(02-06) | HTML/CSS/JS/TS/工具链 5 篇 |
| ⚛️ React 核心(07-12) | JSX/Props/State/Effects/Events/实战 6 篇 |
| 🎨 项目技术(13-17) | CSS Modules / Zustand / SSE / 主题 / 移动端 5 篇 |
| 📦 项目实战(18-20) | 组件详解 / API / 开发者指南 3 篇 |
如果有任何疑问,查阅对应章节即可。祝开发愉快!