20 — 开发者指南

从零开始运行、开发、调试、部署 dodo-agent 前端。
包含:环境搭建、开发流程、移动端调试、主题开发、生产部署。


1. 环境要求

工具版本验证
Node.js>= 18node -v
npm>= 9npm -v

Node.js 安装

  • 官网下载安装:https://nodejs.org
  • 推荐 LTS 版本
  • macOS 也可以用 Homebrew:brew install node@18

2. 快速开始

2.1 启动开发服务器

1
2
3
4
5
6
7
8
# 1. 进入前端目录
cd agent/dodo-agent-frontend

# 2. 安装依赖(首次运行或依赖变更时)
npm install

# 3. 启动开发服务器
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 # 构建生产版本到 dist/
npm run preview # 本地预览生产版本
npm run typecheck # TypeScript 类型检查

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              # 安装所有依赖(按 package.json)
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", // Markdown 渲染
"remark-gfm": "^4.0.0", // GFM Markdown 扩展
"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 修改样式(最常见)

1
2
3
4
# 1. 找到对应组件的 .module.css
# 例如改发送按钮:src/components/InputArea/InputArea.module.css

# 2. 修改后浏览器会自动更新(Vite HMR)

5.3 加新功能(业务流程)

1
2
3
# 1. 在 chatStore.ts 加新 action
# 2. 在组件中调用新 action
# 3. 在 chatStore.ts 的接口声明加新方法

5.4 加新主题

1
2
3
# 1. src/store/themeStore.ts - THEMES 数组加新主题元数据
# 2. src/styles/tokens.css - 末尾加 [data-theme='newtheme'] 块
# 3. src/components/ThemeSwitcher/ThemeSwitcher.tsx - getPrimaryColor 加映射

详见 16-主题系统与ThemeSwitcher.md 第 7 节。

5.5 加新组件

1
2
3
# 1. 创建 components/MyComponent/MyComponent.tsx
# 2. 创建 components/MyComponent/MyComponent.module.css
# 3. 在父组件导入并使用

5.6 加新 API 接口

1
2
3
4
# 1. 在 types/api.ts 加类型
# 2. 在 api/ 下创建或修改文件
# 3. 在 Store 加 action 调用
# 4. 在组件使用

6. 调试技巧

6.1 React Developer Tools

安装浏览器扩展:React Developer Tools

打开 DevTools → Components 标签 → 查看组件树、Props、State。

6.2 Zustand 调试

1
2
3
4
5
6
7
// 在浏览器控制台:直接调 store action
useChatStore.getState().sendMessage()
useChatStore.getState().loadChats()

// 查看当前状态
console.log(useChatStore.getState())
console.log(useThemeStore.getState())

6.3 调试 SSE

  1. DevTools → Network → 过滤 stream
  2. 发消息 → 点击 chat/stream 请求 → Response 标签
  3. 实时看到推送的数据

6.4 调试主题切换

1
2
// 在控制台手动切换主题
document.documentElement.setAttribute('data-theme', 'paper')

6.5 移动端调试(重要!)

详见 17-移动端适配实战.md 第 9 节。

1
2
3
4
5
6
# 1. 电脑和手机连同一 WiFi
# 2. 启动 dev server 时绑定所有网卡
npm run dev -- --host

# 3. 手机浏览器访问
# http://<电脑 IP>:5173

或在 Chrome DevTools 用手机模拟(Ctrl+Shift+M)。

6.6 vConsole(移动端调试神器)

如果想看移动端 console:

1
npm install vconsole
1
2
3
4
5
6
// main.tsx
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
// 用 React.memo 包裹组件
import { memo } from 'react';

const ChatItem = memo(function ChatItem({ chat, active, onSelect, onDelete }) {
return <div>...</div>;
});

// 用 useMemo 缓存昂贵计算
const filteredList = useMemo(
() => chatList.filter(c => c.title.includes(keyword)),
[chatList, keyword]
);

7.3 主题切换性能

主题切换是纯 CSS 变量切换,不触发 React 重渲染(Topbar 显示主题名除外),性能极佳。


8. 构建生产版本

8.1 构建

1
npm run build

输出在 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 # 本地预览,默认 http://localhost:4173

9. 部署

9.1 方式 A:Nginx 反向代理(推荐)

步骤

1
2
3
4
5
6
7
8
# 1. 本地构建
npm run build

# 2. 上传 dist/ 到服务器
scp -r dist/* user@server:/var/www/dodo-agent/dist/

# 3. 重启 Nginx
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;

# SPA 路由:所有路径都返回 index.html
location / {
try_files $uri $uri/ /index.html;
}

# 后端 API(普通请求)
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# SSE 必需特殊配置
location /api/chat/stream {
proxy_pass http://localhost:8080;
proxy_buffering off; # 关闭缓冲(SSE 必须)
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
# 1. 构建前端
npm run build

# 2. 复制到后端
cp -r dist/* ../dodo-agent-backend/src/main/resources/static/

# 3. 后端打 JAR
cd ../dodo-agent-backend
mvn clean package

# 4. 部署 JAR
java -jar target/dodo-agent-0.0.1-SNAPSHOT.jar

10. 环境变量

10.1 创建 .env 文件

1
2
3
4
5
6
7
# agent/dodo-agent-frontend/.env

# 后端 API 地址(默认 /api,走 Vite 代理)
VITE_API_BASE=/api

# 自定义后端地址示例
# VITE_API_BASE=https://api.example.com

10.2 读取环境变量

1
2
const apiBase = import.meta.env.VITE_API_BASE;
// ↑ Vite 的特殊对象

10.3 .env 文件优先级

1
2
3
.env                 # 所有环境
.env.development # 仅开发
.env.production # 仅生产

11. Git 工作流

11.1 提交前检查

1
2
3
4
5
6
7
8
9
# 1. 类型检查
npm run typecheck

# 2. 构建验证
npm run build

# 3. 提交
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 映射
加新 Agentconstants/agents.ts 加 Agent
加新事件类型constants/streamTypes.ts + applyEvent
改 API 地址api/client.ts.env
改后端接口api/*.ts + types/api.ts
改输入区高度InputArea.module.cssmax-height
改主题在 ThemeSwitcher 点选;或编辑 tokens.css
移动端调试Chrome DevTools 模拟 + 真机 --host

13. 推荐的学习资源

主题资源
React 官方教程https://react.dev/learn
React Hooks 详解https://react.dev/reference/react/hooks
TypeScript 手册https://www.typescriptlang.org/docs/
Vite 文档https://vitejs.dev/guide/
Zustandhttps://github.com/pmndrs/zustand
react-markdownhttps://github.com/remarkjs/react-markdown
CSS Moduleshttps://github.com/css-modules/css-modules
Lucide 图标https://lucide.dev/icons/
CSS 变量https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
iOS 安全区https://webkit.org/blog/7929/designing-websites-for-iphone-x/
100vh 问题https://web.dev/articles/viewport-units

14. 一段话总结

开发流程npm installnpm run dev → 改代码(自动热更新) → npm run build
调试:DevTools + React Developer Tools + 控制台 store.getState()。
移动端:Chrome 模拟 + 真机 --host 测试。
部署npm run builddist/ 上传到 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 篇

如果有任何疑问,查阅对应章节即可。祝开发愉快!