144 lines
6.4 KiB
Markdown
144 lines
6.4 KiB
Markdown
# 前端开发规则
|
||
|
||
## 技术栈
|
||
|
||
- 使用 React 18、TypeScript 和 Vite。
|
||
- UI 组件库使用 shadcn/ui。
|
||
- 样式使用 Tailwind CSS;新增样式优先使用 Tailwind 工具类和主题变量。
|
||
- 图标使用 Lucide React,禁止手写重复的图标 SVG。
|
||
- 优先使用项目现有依赖;引入新依赖前说明必要性和影响。
|
||
|
||
## 项目结构(不可变)
|
||
|
||
前端源码必须遵循以下目录结构:
|
||
|
||
```text
|
||
src/
|
||
├── assets/ # 静态资源
|
||
├── components/ # 可复用 UI 组件
|
||
├── constants/ # 业务常量、枚举
|
||
├── hooks/ # 自定义 Hook
|
||
├── http/ # 请求封装
|
||
├── interfaces/ # 类型声明(model、api)
|
||
├── routes/ # 路由页面
|
||
├── stores/ # 全局状态,按业务拆分
|
||
├── utils/ # 工具函数
|
||
└── 根级入口文件
|
||
```
|
||
|
||
结构约束:
|
||
|
||
- 常量必须放在 `constants/`,状态必须放在 `stores/`,接口类型必须放在 `interfaces/`。
|
||
- `interfaces/` 下按业务模块组织类型;每个模块至少包含 `model.ts` 和 `api.ts`。
|
||
- 可复用组件放在 `components/`;仅供单个路由使用的组件放在 `routes/<name>/components/`。
|
||
- 路由页面必须放在 `routes/` 下;每个路由模块包含 `Page`、`Loader` 和 `index.module.scss`。
|
||
- 新增文件前先确认其职责与目录匹配,不得为了方便将业务代码放入根级入口文件。
|
||
|
||
## 组件规范
|
||
|
||
### 组件结构
|
||
|
||
- 组件必须放在 `src/components/` 或对应路由的 `components/` 目录下,每个组件使用独立目录。
|
||
- 组件目录至少包含 `index.tsx` 和 `index.module.scss`。
|
||
- 组件样式必须使用 SCSS Modules,禁止新增全局样式。
|
||
- Props 必须定义明确的 TypeScript 接口,禁止使用隐式或无类型 Props。
|
||
- 使用 `classnames` 管理动态 class;不要通过字符串拼接维护复杂 class 列表。
|
||
|
||
### 组件层级
|
||
|
||
- 页面级组件:仅单页使用时,放在 `routes/<page>/components/`。
|
||
- 通用组件:跨页面复用时,放在 `src/components/`。
|
||
- 单个文件建议不超过 400 行;超过后应根据职责拆分为更小的组件或工具模块。
|
||
|
||
## 编码规范
|
||
|
||
### TypeScript
|
||
|
||
- 所有前端源码必须使用 TypeScript,禁止新增 JavaScript 文件。
|
||
- 禁止使用 `any`;确有必要时必须说明理由并添加代码注释。
|
||
- 接口和类型使用 PascalCase 命名;组件 Props 必须定义清晰、完整的接口。
|
||
|
||
### 命名
|
||
|
||
| 类型 | 规则 | 示例 |
|
||
| ------------ | ---------- | ---------------------- |
|
||
| 文件夹、路由 | kebab-case | `user-profile` |
|
||
| 变量、函数 | camelCase | `userList`、`onSubmit` |
|
||
| 常量 | UPPER_CASE | `API_TIMEOUT` |
|
||
| 接口、类 | PascalCase | `UserInfo` |
|
||
| React 组件 | PascalCase | `UserProfile` |
|
||
| 自定义 Hook | `use` 开头 | `useUserStore` |
|
||
|
||
### 业务函数
|
||
|
||
- 事件处理函数使用 `onXxx` 命名,例如 `onSubmit`。
|
||
- 组件或业务内部处理函数使用 `handleXxx` 命名,例如 `handleDelete`。
|
||
|
||
## 文档规范
|
||
|
||
### 注释规范
|
||
|
||
- 必要注释统一使用 JSDoc(`/** ... */`)格式。
|
||
- 注释重点解释设计原因、业务约束和非显而易见的取舍,不要重复代码本身表达的内容。
|
||
- 文件头、函数或方法、复杂逻辑块和类型定义应根据需要补充说明。
|
||
- 注释必须使用中文;代码标识符仍使用英文命名。
|
||
|
||
## 路由规范(不可变)
|
||
|
||
### 路由结构
|
||
|
||
- 路由目录必须位于 `src/routes/` 下,每个页面使用独立目录,目录名使用 kebab-case。
|
||
- 每个页面目录必须包含 `Page.tsx`、`Loader.tsx` 和 `index.module.scss`。
|
||
- `Loader.tsx` 只负责懒加载对应的 `Page.tsx`,不得嵌套 `Routes` 或 `Route`。
|
||
|
||
### 路由与菜单
|
||
|
||
- 路由配置必须全局集中管理,禁止在多个文件中重复维护同一套路由。
|
||
- 同一个页面只能在一处使用 `lazy` 引入;菜单、面包屑等导航数据引用统一的路由配置。
|
||
|
||
## 状态管理规范(不可变)
|
||
|
||
### 基础规范
|
||
|
||
- 必须使用项目约定的状态库(例如 Zustand)管理全局状态。
|
||
- 所有 store 必须放在 `src/stores/` 下,禁止在 `src/` 的其他目录中存放 store。
|
||
|
||
### Store 组织
|
||
|
||
- 按业务模块划分 store,每个业务模块使用独立文件。
|
||
- 每个 store 对外暴露对应的 `useXxxStore` Hook。
|
||
- Store 只负责数据和业务行为,不得耦合 UI 组件、页面结构或展示逻辑。
|
||
- 需要持久化时使用 `persist` 等状态库中间件,并明确持久化字段范围。
|
||
|
||
## 代码组织
|
||
|
||
- 组件使用 PascalCase 命名,变量、函数和文件中的普通标识使用 camelCase。
|
||
- 保持组件职责单一;页面、可复用组件、请求服务和类型定义分开组织。
|
||
- 避免在 `App.tsx` 或单个组件中堆积所有业务逻辑。
|
||
- 为组件 props、接口请求和响应定义明确的 TypeScript 类型,避免使用 `any`。
|
||
- 复用逻辑优先提取为自定义 Hook 或独立工具函数。
|
||
|
||
## API 调用
|
||
|
||
- API 路径遵循根目录 `AGENTS.md` 中的版本和响应规范。
|
||
- 请求地址、认证信息和环境差异通过 `.env.example` 中定义的 Vite 环境变量配置。
|
||
- 不在源码中硬编码密码、令牌或生产环境地址。
|
||
- 统一处理加载、成功、空数据和错误状态。
|
||
|
||
## 样式与交互
|
||
|
||
- 优先复用现有样式和设计约定,避免为单个页面重复定义相同样式。
|
||
- 样式必须使用 SCSS Modules,组件样式文件命名为 `index.module.scss`;动态 class 使用 `classnames` 管理。
|
||
- 自定义样式中的主色、文本、背景、边框等颜色必须使用主题 CSS 变量,禁止硬编码颜色值。
|
||
- 优先使用 `var(--ant-color-xxx)`;项目已有自定义主题变量时使用 `var(--xxx)`。
|
||
- 新增颜色变量时同步考虑浅色和暗色主题的取值,确保主题切换后的对比度和视觉一致性。
|
||
- 保证桌面端和移动端布局可用,避免固定宽度导致内容溢出。
|
||
- 表单和按钮提供清晰的禁用、提交中和错误状态。
|
||
- 交互文案、错误提示和空状态使用清晰、面向用户的中文描述。
|
||
|
||
## 验证
|
||
|
||
- 修改后至少运行 `npm run build`。
|
||
- 涉及页面或交互修改时,使用 `npm run dev` 手动验证主要流程和响应式布局。
|
||
- 提交前检查浏览器控制台无新增错误或警告。
|