本文档是一套经过实践验证的前端团队协作规范,涵盖代码风格、开发流程、质量门禁和文档管理,适用于 3-20 人规模的前端团队。
1 设计初衷
1.1 解决的问题
| 问题 | 传统方式 | 本规范方案 |
|---|---|---|
| 代码风格不统一 | 口头约定,执行不一 | 文档化规范 + 自动检查 |
| 新人上手慢 | 师徒口传,效率低 | 结构化文档,自主学习 |
| 代码质量参差 | Code Review 主观判断 | 量化标准,客观评估 |
| 文档滞后 | 事后补写,与代码脱节 | 同步更新,文档即入口 |
| 重构无章法 | 凭经验,风险高 | 分层规范,渐进收敛 |
1.2 核心目标
- 可执行:规范必须可自动化检查,不依赖人工记忆
- 可追溯:文档记录最终状态,不保留中间过程
- 可收敛:代码持续向规范靠拢,不因历史问题放任新增
- 可扩展:规范分层维护,新增规则有明确归属
2 规范体系架构
2.1 文档结构
bash
project-root/
├── docs/ # 正式文档
│ ├── README.md # 文档总入口
│ ├── code-style/ # 代码规范
│ │ ├── README.md # 规范入口
│ │ ├── directories.md # 目录规范
│ │ ├── api.md # API 层规范
│ │ ├── services.md # 业务流程层规范
│ │ ├── stores.md # 状态层规范
│ │ ├── models.md # 模型层规范
│ │ ├── components.md # 组件规范
│ │ ├── pages.md # 页面规范
│ │ ├── styles.md # 样式规范
│ │ ├── unit-tests.md # 单元测试规范
│ │ └── docs.md # 文档规范
│ │
│ ├── design/ # 功能设计
│ │ ├── pages/ # 页面设计
│ │ └── models/ # 模型设计
│ │
│ ├── global-design/ # 全局能力设计
│ ├── components/ # 公共组件说明
│ └── quality/ # 质量问题记录
│
├── src/ # 业务代码
├── mock/ # Mock 服务
└── __tests__/ # 单元测试
2.2 规范层级
| 层级 | 文档 | 职责 |
|---|---|---|
| L1 总则 | README.md |
总原则、适用范围、执行约束 |
| L2 分层规范 | code-style/*.md |
各层代码组织和风格要求 |
| L3 设计文档 | design/ |
页面和模型的最终状态 |
| L4 质量记录 | quality/ |
待跟进问题和改进项 |
3 核心设计原则
3.1 Source Of Truth(单一真相源)
原则:每个规则只有一个主维护位置,其他文档通过链接引用。
markdown
# ✅ 正确:引用主维护位置
API 请求层规范详见 [API 规范](./code-style/api.md)。
# ❌ 错误:多处重复维护
API 请求层规范:...(重复内容)
优势:
- 避免规范不一致
- 修改一处,全局生效
- 降低维护成本
3.2 代码向规范收敛
原则:所有新增代码必须遵守规范;改动旧代码时,新增区域和修改区域也要符合规范。
bash
适用范围:
- ✅ 新增代码:严格遵守
- ✅ 改动区域:必须符合
- ✅ 重组代码:向规范收敛
- ⚠️ 未触碰代码:不顺手扩大改造
执行策略:
bash
# 小范围修复:只调整本次触达区域
git diff --name-only # 只看改动文件
# 较大改动:先评估是否需要重构
# 1. 检查是否涉及旧实现迁移
# 2. 确认是否按分层规范重构
# 3. 获得确认后再执行
3.3 业务分层原则
原则:代码按职责分层,依赖方向单向,不跨层调用。
bash
┌─────────────────────────────────────────────────────────┐
│ Pages(页面层) │
│ - 组合组件、hooks、状态 │
│ - 调用 services 和 stores │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Components(组件层) │
│ - 纯 UI 渲染 │
│ - 通过 props 接收数据 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Services(业务流程层) │
│ - 编排业务逻辑 │
│ - 调用 API 和 stores │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Stores(状态层) │
│ - 管理应用状态 │
│ - 提供 selector 和 action │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ API(请求层) │
│ - 封装 HTTP 请求 │
│ - 处理响应转换 │
└─────────────────────────────────────────────────────────┘
依赖规则:
- ✅ Pages → Components, Services, Stores, API
- ✅ Services → Stores, API
- ✅ Stores → API
- ❌ API → Services, Stores(禁止反向依赖)
- ❌ Components → Services, Stores(禁止直接调用)
3.4 优先靠近使用场景
原则:页面专属代码默认放在页面目录内,只有形成稳定复用关系后才上提到共享目录。
typescript
// ✅ 正确:页面专属 hook 放在页面目录
src/pages/dashboard/hooks/use-dashboard-data.ts
// ❌ 错误:尚未复用就提到共享目录
src/hooks/use-dashboard-data.ts
判断标准:
| 场景 | 位置 |
|---|---|
| 仅单页面使用 | src/pages/<page>/hooks/ |
| 2-3 个页面稳定复用 | src/hooks/ |
| 全局通用 | src/hooks/ 或 src/lib/ |
3.5 信任后端接口
原则:后端接口返回数据按接口定义信任,不堆叠额外兜底判断。
typescript
// ✅ 正确:信任接口定义
interface User {
id: string; // 必填
name: string; // 必填
email?: string; // 可选
}
function renderUser(user: User) {
return `${user.name} (${user.id})`;
}
// ❌ 错误:过度兜底
function renderUser(user: User) {
const id = user?.id ?? 'unknown';
const name = user?.name ?? 'Anonymous';
return `${name} (${id})`;
}
4 开发流程规范
4.1 较大任务处理流程
bash
┌─────────────────────────────────────────────────────────┐
│ 1. 确认入口文档 │
│ - 页面文档、组件文档、全局能力文档 │
│ - 涉及的模型和功能点编号 │
│ - 相关的单元测试入口 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 2. 给出处理方案 │
│ - 改动范围评估 │
│ - 分层归属判断 │
│ - 是否涉及旧实现迁移 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 3. 用户确认后执行 │
│ - 实现代码 │
│ - 自动修复和格式化 │
│ - 定向测试验证 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 4. 更新文档 │
│ - 更新设计文档最终状态 │
│ - 更新入口文档索引(如需) │
│ - 记录质量问题到 quality/ │
└─────────────────────────────────────────────────────────┘
4.2 边界控制原则
原则:只处理本次任务边界内的问题,发现边界外问题只记录不修复。
markdown
## 本次边界
- 修改范围:`src/pages/dashboard/`
- 涉及模型:`docs/design/models/analytics.md` M3.1
- 不处理:`src/pages/settings/` 的历史问题
## 发现的边界外问题
- [ ] `src/pages/settings/` 组件超过 800 行
- [ ] `src/stores/user.ts` 缺少类型定义
4.3 角色分离原则
原则:实现、review 和校验角色分离,不混在同一轮处理。
bash
实现阶段:
- 编写代码
- 运行自动修复
- 补充测试
Review 阶段:
- 检查行为回归
- 检查测试缺口
- 检查规则偏离
校验阶段:
- typecheck
- lint
- 定向测试
5 质量门禁
5.1 自动检查流程
bash
# 1. 自动修复
npm run lint:fix -- <修改的文件>
npm run format -- <修改的文件>
# 2. 格式检查
npm run format:check -- <修改的文件>
# 3. 类型检查
npm run typecheck
# 4. 代码检查
npm run lint
# 5. 定向测试
npm run test:unit:boundaries # 静态边界基线
npm run test:unit:module -- <模块名> # 功能模块测试
5.2 测试覆盖原则
测试分类:
| 类型 | 用途 | 适用对象 |
|---|---|---|
| 功能行为测试 | 验证业务功能 | 公共组件、API、services、stores |
| 静态边界测试 | 验证代码规范 | 目录、依赖、命名、样式归属 |
覆盖范围:
bash
必须测试:
- ✅ 公共组件的稳定契约
- ✅ API 请求层的能力
- ✅ Services 的业务流程
- ✅ Stores 的状态管理
不测试:
- ❌ 页面入口和页面内部组件
- ❌ 布局入口和布局内部组件
- ❌ Mock 服务实现
- ❌ 单纯文档调整
5.3 测试组织规范
bash
__tests__/
├── boundaries/ # 静态边界测试(所有 src/ 改动的基线)
├── api-request/ # API 请求层测试
├── global-user/ # 用户能力测试
├── reference-data/ # 参考数据测试
└── <module-name>/ # 功能模块测试
├── feature-a.test.ts
└── feature-b.test.ts
执行规则:
- 最小执行单位是功能模块目录,不是单个测试文件
boundaries/是所有src/改动的固定基线- 同时涉及多个模块时,分别执行所有相关目录
6 文档管理规范
6.1 文档结构规范
markdown
# 文档标题
一句话说明本文档的职责和适用范围。
最终校订时间:YYYY-MM-DD
最终状态:当前已生效状态。
## 1 总章节说明
说明本文档内各章节的功能与作用。
## 2 正文章节
正文内容。
6.2 文档更新规则
| 场景 | 操作 |
|---|---|
| 页面功能调整 | 更新 docs/design/pages/ 对应文档 |
| 模型字段变更 | 更新 docs/design/models/ 对应文档 |
| 组件能力变更 | 更新 docs/components/ 对应文档 |
| 全局能力变更 | 更新 docs/global-design/ 对应文档 |
| 发现质量问题 | 记录到 docs/quality/ |
6.3 文档入口维护
原则:新增或调整正式文档时,必须同步更新对应入口文档。
markdown
# docs/design/pages/README.md
| 页面 | 文档路径 | 源码目录 | 当前状态 |
|------|----------|----------|----------|
| 首页 | [home.md](./home.md) | `src/pages/home/` | 已实现 |
| 设置 | [settings.md](./settings.md) | `src/pages/settings/` | 已实现 |
7 代码组织规范
7.1 目录职责
| 目录 | 职责 | 内容 |
|---|---|---|
src/pages/ |
页面入口 | 页面组件、页面 hooks、页面 stores |
src/components/ |
公共组件 | 跨页面复用的 UI 组件 |
src/hooks/ |
共享 hooks | 跨模块复用的 React hooks |
src/services/ |
业务流程 | 编排 API、stores 和业务逻辑 |
src/stores/ |
状态管理 | 全局状态、selector、action |
src/api/ |
请求层 | HTTP 请求封装、响应转换 |
src/models/ |
数据模型 | 业务对象、DTO、类型定义 |
src/lib/ |
工具库 | 通用工具函数、浏览器能力 |
src/constants/ |
常量 | 全局常量、配置项 |
7.2 文件拆分策略
| 场景 | 拆分方式 |
|---|---|
| 页面文件过大 | 拆为 components/、hooks/、view.ts、actions.ts |
| Store 文件过大 | 拆为 state.ts、selectors.ts、actions.ts、persistence.ts |
| 样式文件过大 | 按页面或组件就近放入模块目录 |
7.3 命名规范
| 类型 | 规范 | 示例 |
|---|---|---|
| 目录名 | kebab-case | user-profile/、api-request/ |
| 文件名 | kebab-case | use-current-user.ts、request-client.ts |
| 组件名 | PascalCase | UserProfile、DashboardPanel |
| Hook 名 | camelCase + use 前缀 | useCurrentUser、useDashboardData |
| 类型名 | PascalCase | UserProfile、ApiResponse |
| 常量名 | UPPER_SNAKE_CASE | API_BASE_URL、MAX_RETRY_COUNT |
8 执行约束
8.1 适用范围
markdown
强制执行:
- ✅ 所有新增代码
- ✅ 改动区域的新增代码
- ✅ 被重组的相邻代码
渐进收敛:
- ⚠️ 历史遗留问题(分阶段治理)
- ⚠️ 未触碰的旧代码(不顺手扩大)
豁免:
- ❌ 第三方运行时代码
- ❌ 明确记录的临时例外
8.2 例外处理
markdown
## 临时例外记录
- 文件:`src/legacy/old-module.ts`
- 原因:第三方库要求特定格式
- 影响范围:仅该文件
- 后续计划:2026-Q4 重构时迁移
8.3 评审检查清单
markdown
## Code Review 检查项
- [ ] 新增代码是否符合分层规范
- [ ] 是否存在跨层依赖
- [ ] 是否有过度兜底判断
- [ ] 页面专属代码是否放在页面目录
- [ ] 共享代码是否有稳定复用关系
- [ ] 是否同步更新相关文档
- [ ] 是否补充必要的单元测试
9 最佳实践
9.1 函数设计
单一职责:
typescript
// ✅ 正确:每个函数只做一件事
function validateInput(input: Input): ValidationResult { ... }
function buildCommand(input: Input): Command { ... }
async function submitCommand(command: Command): Promise<Result> { ... }
// ❌ 错误:一个函数做多件事
async function handleSubmit(input: Input) {
// 验证
if (!input.name) return error('Name required');
// 转换
const command = { ...input, timestamp: Date.now() };
// 提交
const result = await api.submit(command);
// 处理结果
if (result.success) navigate('/success');
}
参数对象化:
typescript
// ✅ 正确:参数对象有明确类型
type CreateUserInput = {
name: string;
email: string;
role: UserRole;
};
function createUser(input: CreateUserInput): Promise<User> { ... }
// ❌ 错误:参数过多或类型模糊
function createUser(name: string, email: string, role: string, ...) { ... }
9.2 状态管理
Store 设计:
typescript
// ✅ 正确:清晰的状态结构
type UserStore = {
// 状态
currentUser: User | null;
isLoading: boolean;
error: string | null;
// Actions
login: (credentials: Credentials) => Promise<void>;
logout: () => void;
// Selectors
isLoggedIn: () => boolean;
displayName: () => string;
};
9.3 组件设计
Props 设计:
typescript
// ✅ 正确:Props 有明确类型和文档
type UserCardProps = {
/** 用户数据 */
user: User;
/** 是否显示邮箱 */
showEmail?: boolean;
/** 点击回调 */
onUserClick?: (userId: string) => void;
};
// ❌ 错误:Props 类型模糊
type UserCardProps = {
data: any;
options?: Record<string, unknown>;
};
10 适用场景
10.1 适用
- 3-20 人前端团队
- 项目周期 3 个月以上
- 使用 React + TypeScript
- 有 Code Review 流程
- 追求代码质量一致性
10.2 不适用
- 1-2 人小项目(规范成本过高)
- 快速原型开发(优先速度)
- 纯静态页面(无复杂逻辑)
10.3 可裁剪项
| 规范 | 可选/必选 | 裁剪条件 |
|---|---|---|
| 文档体系 | 可选 | 小团队可简化 |
| 单元测试 | 可选 | 快速原型可省略 |
| 分层规范 | 必选 | 保证代码质量 |
| 命名规范 | 必选 | 保证一致性 |
11 总结
本规范的核心价值:
- 标准化:统一的代码风格和组织方式
- 可执行:自动化检查,不依赖人工
- 可追溯:文档记录最终状态
- 可收敛:代码持续向规范靠拢
- 可扩展:规范分层维护,易于扩展
适用团队:追求代码质量和协作效率的前端团队。
预期收益:
- 新人上手时间减少 50%
- Code Review 效率提升 30%
- 代码质量问题减少 40%