# D8D Starter 前端架构文档 ## 版本信息 | 版本 | 日期 | 描述 | 作者 | |------|------|------|------| | 1.0 | 2025-09-15 | 初始前端架构文档 | Winston | ## 1. 模板和框架选择 ### 现有技术栈分析 项目已经使用了现代化的React全栈技术栈: **核心框架**: - **React 19.1.0** - 最新版本,支持并发特性 - **TypeScript 5.8.3** - 类型安全,编译时错误检测 **构建工具**: - **Vite 7.0.0** - 快速冷启动,热重载支持 - **Tailwind CSS 4.1.11** - 原子化CSS,实用优先 **UI组件库**: - **shadcn/ui** - 基于Radix UI的无障碍组件库 - **Radix UI Primitives** - 无障碍基础组件 **状态管理**: - **React Query 5.83.0** - 服务端状态管理,数据同步 - **React Hook Form 7.61.1** - 表单管理和验证 **路由系统**: - **React Router 7.7.0** - 声明式客户端路由 - **双路由架构** - 管理后台(/admin/*)和用户前台(/*)分离 **API集成**: - **Hono RPC 4.8.5** - 端到端类型安全API调用 - **自定义axios适配器** - 统一的错误处理 ### 技术决策依据 - **选择React Query而非Redux**: 专注于服务端状态管理,减少客户端状态复杂度 - **Hono RPC而非传统REST**: 提供前后端统一的类型安全,减少接口不一致问题 - **Tailwind CSS v4**: 采用新的运行时配置,简化构建流程 - **shadcn/ui而非Ant Design**: 更现代的设计语言,更好的无障碍支持 ## 2. 前端技术栈 | 类别 | 技术 | 版本 | 用途 | 决策依据 | |------|------|------|------|-----------| | 框架 | React | 19.1.0 | 用户界面构建 | 最新版本,并发特性支持 | | UI库 | shadcn/ui | - | 组件库和设计系统 | 基于Radix UI,无障碍支持 | | 状态管理 | React Query | 5.83.0 | 服务端状态管理 | 数据同步、缓存、自动重试 | | 路由 | React Router | 7.7.0 | 客户端路由 | 声明式路由,数据加载支持 | | 构建工具 | Vite | 7.0.0 | 开发服务器和构建 | 快速冷启动,热重载支持 | | 样式方案 | Tailwind CSS | 4.1.11 | 原子化CSS框架 | 实用优先,设计一致性 | | 类型安全 | TypeScript | 5.8.3 | 类型检查 | 编译时错误检测 | | API客户端 | Hono RPC | 4.8.5 | 类型安全API调用 | 前后端统一类型定义 | | 表单处理 | React Hook Form | 7.61.1 | 表单管理和验证 | 高性能,最小重渲染 | | 图标库 | Lucide React | 0.536.0 | 图标系统 | 简洁一致的图标设计 | | 测试框架 | Jest + Testing Library | - | 组件测试 | 行业标准测试工具 | ## 3. 项目结构 ```text d8d-starter/ ├── src/ │ ├── client/ # 前端代码根目录 │ │ ├── admin/ # 管理后台界面 │ │ │ ├── components/ # 管理后台专属组件 │ │ │ ├── pages/ # 管理页面 │ │ │ ├── layouts/ # 管理后台布局 │ │ │ └── hooks/ # 管理后台专属hooks │ │ ├── home/ # 用户主页界面 │ │ │ ├── components/ # 主页专属组件 │ │ │ ├── pages/ # 主页页面 │ │ │ └── hooks/ # 主页专属hooks │ │ ├── components/ # 共享UI组件 │ │ │ └── ui/ # 基础UI组件 (shadcn/ui) │ │ │ ├── button.tsx │ │ │ ├── input.tsx │ │ │ └── ... │ │ ├── hooks/ # 共享React Hooks │ │ │ └── use-mobile.ts # 移动端检测hook │ │ ├── lib/ # 工具库 │ │ │ └── utils.ts # className工具函数 (cn) │ │ ├── utils/ # 工具函数目录 │ │ │ ├── utils.ts # 通用工具函数 │ │ │ ├── logger.ts # 日志工具 │ │ │ └── ClientOnly.tsx # 客户端渲染组件 │ │ └── api.ts # API客户端配置 │ ├── server/ # 后端代码 │ └── shared/ # 前后端共享代码 ├── public/ # 静态资源 ├── dist/ # 构建输出 └── docs/ # 文档 ``` ## 4. 组件标准 ### 组件模板 ```typescript import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/client/lib/utils" const componentVariants = cva( "base-styles transition-all duration-200", { variants: { variant: { default: "bg-primary text-primary-foreground", secondary: "bg-secondary text-secondary-foreground", destructive: "bg-destructive text-destructive-foreground", outline: "border border-input bg-background", ghost: "hover:bg-accent hover:text-accent-foreground", }, size: { default: "h-9 px-4 py-2", sm: "h-8 rounded-md px-3 text-xs", lg: "h-10 rounded-md px-8", icon: "size-9", }, }, defaultVariants: { variant: "default", size: "default", }, } ) export interface ComponentProps extends React.HTMLAttributes, VariantProps { isLoading?: boolean disabled?: boolean } const Component = React.forwardRef( ({ className, variant, size, isLoading = false, disabled = false, ...props }, ref) => { return (
) } ) Component.displayName = "Component" export { Component, componentVariants } ``` ### 命名约定 **文件命名**: - 组件文件: `PascalCase.tsx` (如: `UserProfile.tsx`) - 工具文件: `camelCase.ts` (如: `formatDate.ts`) - Hook文件: `useCamelCase.ts` (如: `useUserData.ts`) - 类型文件: `camelCase.ts` (如: `apiTypes.ts`) **组件命名**: - 组件: `PascalCase` (如: `UserCard`) - Props接口: `ComponentProps` (如: `ButtonProps`) - 变体类型: `ComponentVariants` (如: `ButtonVariants`) ## 5. 状态管理 ### 实际状态管理架构 基于对现有代码的分析,项目采用混合状态管理模式: **React Context + React Query组合**: - **认证状态**: 使用React Context管理用户认证状态 - **服务端数据**: 使用React Query管理API数据 - **本地UI状态**: 使用useState管理组件内部状态 ### 认证状态管理 (React Context) ```text src/ ├── client/ │ ├── admin/ │ │ └── hooks/ │ │ └── AuthProvider.tsx # 管理后台认证上下文 │ ├── home/ │ │ └── hooks/ │ │ └── AuthProvider.tsx # 用户前台认证上下文 │ ├── hooks/ │ │ └── use-mobile.ts # 共享移动端检测hook │ └── api.ts # API客户端配置 ``` ### React Query使用模式 项目采用简单的React Query使用模式: **配置方式**: 在每个入口文件独立创建QueryClient ```typescript // 在入口文件中创建QueryClient const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 1, refetchOnWindowFocus: false, }, }, }) ``` **查询模式**: 直接在组件中使用useQuery ```typescript // 数据查询示例 const { data: usersData, isLoading, refetch } = useQuery({ queryKey: ['users', searchParams], queryFn: async () => { const res = await userClient.$get({ query: searchParams }) if (res.status !== 200) throw new Error('获取失败') return await res.json() } }) ``` **数据变更模式**: 直接调用API客户端 + 手动refetch ```typescript // 数据变更示例(未使用useMutation) const handleCreateSubmit = async (data: CreateUserFormData) => { try { const res = await userClient.$post({ json: data }) if (res.status !== 201) throw new Error('创建失败') toast.success('创建成功') refetch() // 手动重新获取数据 } catch (error) { console.error('操作失败:', error) toast.error('操作失败,请重试') } } ``` ### 当前状态管理特点 1. **模块化认证**: 管理后台和用户前台有独立的认证Provider 2. **简单配置**: QueryClient在每个入口文件独立配置,无复杂全局配置 3. **混合模式**: Context管理认证状态 + React Query管理数据查询 4. **手动数据同步**: 数据变更后手动调用refetch更新缓存 5. **渐进式采用**: 逐步引入React Query,尚未全面使用useMutation ## 6. API集成 ### Hono RPC集成模式 项目使用自定义的axios适配器实现Hono RPC客户端: ```typescript // 自定义axios适配器 (src/client/api.ts) const axiosFetch = async (url: RequestInfo | URL, init?: RequestInit) => { const requestHeaders: Record = {}; if (init?.headers instanceof Headers) { init.headers.forEach((value, key) => { requestHeaders[key] = value; }) } const response = await axios.request({ url: url.toString(), method: init?.method || 'GET', headers: requestHeaders, data: init?.body, }).catch((error) => { if (isAxiosError(error)) { return { status: error.response?.status, statusText: error.response?.statusText, data: error.response?.data, headers: error.response?.headers } } throw error; }) const responseHeaders = new Headers(); if (response.headers) { for (const [key, value] of Object.entries(response.headers)) { responseHeaders.set(key, value); } } // 处理204 No Content响应 const body = response.status === 204 ? null : responseHeaders.get('content-type')?.includes('application/json') ? JSON.stringify(response.data) : response.data; return new Response( body, { status: response.status, statusText: response.statusText, headers: responseHeaders } ) } // Hono客户端实例导出 export const authClient = hc('/', { fetch: axiosFetch, }).api.v1.auth; export const userClient = hc('/', { fetch: axiosFetch, }).api.v1.users; export const roleClient = hc('/', { fetch: axiosFetch, }).api.v1.roles; ``` ### 类型安全集成 后端使用OpenAPIHono定义路由类型: ```typescript // 服务器端路由定义 (src/server/api.ts) const userRoutes = api.route('/api/v1/users', usersRouter) const authRoutes = api.route('/api/v1/auth', authRoute) const roleRoutes = api.route('/api/v1/roles', rolesRoute) export type AuthRoutes = typeof authRoutes export type UserRoutes = typeof userRoutes export type RoleRoutes = typeof roleRoutes ``` ### 使用模式 在组件中直接使用类型安全的客户端: ```typescript // 使用Hono RPC客户端 const response = await userClient.$get({ query: { page: 1, pageSize: 10, keyword: 'search' } }) if (response.status === 200) { const data = await response.json() // 类型安全的data } ``` ## 7. 路由配置 ### 当前路由架构 **双路由系统**: - 管理后台路由: `/admin/*` (位于 `src/client/admin/routes.tsx`) - 用户前台路由: `/*` (位于 `src/client/home/routes.tsx`) **路由结构**: ```typescript // 管理后台路由 - /admin/login → 登录页面 - /admin → 重定向到仪表板 (保护路由) - /admin/dashboard → 仪表板页面 (保护路由) - /admin/users → 用户管理页面 (保护路由) // 用户前台路由 - / → 首页 - /login → 登录页面 - /register → 注册页面 - /member → 会员页面 (保护路由) ``` ### 认证保护 ```typescript export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => { const { isAuthenticated, isLoading } = useAuth(); const navigate = useNavigate(); useEffect(() => { if (!isLoading && !isAuthenticated) { navigate('/admin/login', { replace: true }); } }, [isAuthenticated, isLoading, navigate]); if (isLoading) { return
Loading...
; } if (!isAuthenticated) { return null; } return children; }; ``` ## 8. 样式指南 ### 主题系统 基于CSS自定义属性的主题系统: ```css :root { --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0); /* ... 更多设计token */ } .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --primary: oklch(0.985 0 0); /* ... 暗色主题变量 */ } ``` ### 样式方法论 - **原子化CSS**: 使用Tailwind工具类构建UI - **CSS变量**: 通过CSS自定义属性实现主题切换 - **设计系统**: 基于shadcn/ui的组件设计规范 - **响应式**: 移动优先的响应式设计 ## 9. 测试要求 ### 测试策略 **测试框架**: Jest + Testing Library **测试位置**: `__tests__`文件夹与源码并列 **覆盖率目标**: 核心组件80%+覆盖率 ### 测试模板 ```typescript describe('Button', () => { it('renders correctly with default variant', () => { render() expect(screen.getByRole('button')).toHaveTextContent('Click me') }) it('calls onClick handler when clicked', () => { const handleClick = jest.fn() render() fireEvent.click(screen.getByRole('button')) expect(handleClick).toHaveBeenCalledTimes(1) }) }) ``` ## 10. 环境配置 ### 环境变量 ```bash # 实际环境变量配置(基于服务器端配置) OSS_BASE_URL=https://oss.d8d.fun APP_NAME=多八多Aider ``` ## 11. 前端开发标准 ### 关键编码规则 1. **类型安全**: 全面使用TypeScript,避免any类型 2. **组件设计**: 遵循单一职责原则 3. **性能优化**: 使用React.memo、useCallback等优化手段 4. **错误处理**: 统一的错误边界和异常处理 5. **可访问性**: 支持ARIA属性和键盘导航 ### 快速参考 **常用命令**: ```bash npm run dev # 启动开发服务器 npm run build # 生产构建 npm run test # 运行测试 ``` --- **文档状态**: 正式版 **下次评审**: 2025-10-15 **架构师**: Winston 🏗️