# 开发规范 > **文档版本**: v1.0.0 > **创建日期**: 2026-05-25 > **适用范围**: FischerX 项目开发人员 ## 目录 - [代码规范](#代码规范) - [Git 规范](#git-规范) - [PR 规范](#pr-规范) --- ## 代码规范 ### TypeScript 规范 #### 类型定义 - 使用 `type` 定义对象类型,使用 `interface` 定义类接口或需要扩展的类型 - 始终使用严格的类型检查,避免使用 `any` - 优先使用联合类型和字面量类型 ```typescript // 好的做法 type User = { id: string; name: string; email: string; role: 'admin' | 'user' | 'guest'; }; interface Repository { findById(id: string): Promise<User | null>; save(user: User): Promise<User>; } // 避免 type User = any; ``` #### 命名规范 - 类型名使用 PascalCase - 常量使用 UPPER_SNAKE_CASE - 变量和函数使用 camelCase - 类使用 PascalCase - React 组件使用 PascalCase ```typescript // 类型 type UserProfile = { ... }; // 常量 const MAX_RETRY_COUNT = 3; const API_BASE_URL = 'https://api.example.com'; // 变量和函数 const userName = 'John'; function calculateTotal(price: number, quantity: number): number { ... } // 类 class UserService { ... } // React 组件 function UserProfileCard() { ... } ``` #### 文件组织 - 一个文件一个主要导出 - 使用 index.ts 作为模块入口 - 按功能组织文件,而不是按类型 ``` // 好的做法 user/ ├── index.ts ├── types.ts ├── service.ts ├── repository.ts └── hooks.ts ``` --- ### React/Next.js 规范 #### 组件设计 - 使用函数组件,避免类组件 - 组件文件使用 `.tsx` 扩展名 - 组件名与文件名保持一致 ```tsx // components/UserCard.tsx interface UserCardProps { user: User; onEdit?: (user: User) => void; } export function UserCard({ user, onEdit }: UserCardProps) { return ( <div className="user-card"> <h3>{user.name}</h3> <p>{user.email}</p> {onEdit && <button onClick={() => onEdit(user)}>Edit</button>} </div> ); } ``` #### Hooks 规范 - 自定义 Hook 以 `use` 开头 - Hook 应该只负责单一职责 - 使用 React Query 进行数据获取 - 使用 Zustand 进行状态管理 ```tsx // hooks/useUser.ts import { useQuery } from '@tanstack/react-query'; import { userApi } from '@/lib/api'; export function useUser(userId: string) { return useQuery({ queryKey: ['user', userId], queryFn: () => userApi.getById(userId), enabled: !!userId, }); } ``` #### 表单处理 - 使用 React Hook Form - 使用 Zod 进行验证 - 显示友好的错误信息 ```tsx import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; const formSchema = z.object({ name: z.string().min(2, 'Name too short'), email: z.string().email('Invalid email'), }); type FormValues = z.infer<typeof formSchema>; function UserForm() { const form = useForm<FormValues>({ resolver: zodResolver(formSchema), }); const onSubmit = (data: FormValues) => { console.log(data); }; return <form onSubmit={form.handleSubmit(onSubmit)}>{/* ... */}</form>; } ``` #### 样式规范 - 使用 Tailwind CSS - 组件内部样式放在 `className` 中 - 复杂样式使用 `clsx` 或 `tailwind-merge` ```tsx import { clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; function cn(...inputs: any[]) { return twMerge(clsx(inputs)); } function Button({ children, variant = 'primary', className, }: { children: React.ReactNode; variant?: 'primary' | 'secondary' | 'danger'; className?: string; }) { const variants = { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300', danger: 'bg-red-600 text-white hover:bg-red-700', }; return ( <button className={cn( 'px-4 py-2 rounded font-medium transition-colors', variants[variant], className )} > {children} </button> ); } ``` --- ### NestJS 规范 #### 模块结构 - 按功能组织模块 - 每个模块包含 Controller、Service、Module - 使用 Prisma 作为数据访问层 ``` user/ ├── user.module.ts ├── user.controller.ts ├── user.service.ts ├── dto/ │ ├── create-user.dto.ts │ └── update-user.dto.ts └── entities/ └── user.entity.ts ``` #### 控制器规范 - Controller 只负责请求/响应处理 - 业务逻辑委托给 Service - 使用 DTO 进行验证 - 使用 Swagger 装饰器生成文档 ```typescript import { Controller, Get, Post, Body, Param, UseGuards } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'; import { UserService } from './user.service'; import { CreateUserDto } from './dto/create-user.dto'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; @ApiTags('users') @Controller('users') export class UserController { constructor(private readonly userService: UserService) {} @Post() @ApiOperation({ summary: 'Create user' }) @ApiResponse({ status: 201, description: 'User created' }) create(@Body() createUserDto: CreateUserDto) { return this.userService.create(createUserDto); } @Get(':id') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Get user by ID' }) findOne(@Param('id') id: string) { return this.userService.findOne(id); } } ``` #### 服务规范 - Service 包含业务逻辑 - 使用依赖注入 - 抛出业务异常 ```typescript import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { CreateUserDto } from './dto/create-user.dto'; import * as bcrypt from 'bcrypt'; @Injectable() export class UserService { constructor(private prisma: PrismaService) {} async create(createUserDto: CreateUserDto) { const hashedPassword = await bcrypt.hash(createUserDto.password, 10); return this.prisma.user.create({ data: { ...createUserDto, password: hashedPassword, }, }); } async findOne(id: string) { const user = await this.prisma.user.findUnique({ where: { id } }); if (!user) { throw new NotFoundException(`User with ID ${id} not found`); } return user; } } ``` #### DTO 规范 - 使用 class-validator 进行验证 - 使用 class-transformer 进行转换 - DTO 放在 dto 目录下 ```typescript import { IsEmail, IsString, MinLength } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; export class CreateUserDto { @ApiProperty() @IsString() @MinLength(2) name: string; @ApiProperty() @IsEmail() email: string; @ApiProperty() @IsString() @MinLength(8) password: string; } ``` --- ## Git 规范 ### 分支策略 我们使用 Git Flow 工作流: ``` main (生产环境) └── develop (开发环境) ├── feature/feature-name (功能分支) ├── bugfix/bug-name (修复分支) ├── hotfix/hotfix-name (紧急修复) └── release/release-x.y.z (发布分支) ``` #### 分支说明 | 分支类型 | 命名规范 | 说明 | |---------|---------|------| | main | `main` | 生产环境代码,始终稳定 | | develop | `develop` | 开发环境代码,集成新功能 | | feature | `feature/xxx-yyy` | 新功能开发 | | bugfix | `bugfix/xxx-yyy` | Bug 修复 | | hotfix | `hotfix/xxx-yyy` | 生产环境紧急修复 | | release | `release/x.y.z` | 发布准备 | #### 创建分支 ```bash # 从 develop 创建功能分支 git checkout develop git pull origin develop git checkout -b feature/user-authentication # 从 main 创建紧急修复分支 git checkout main git pull origin main git checkout -b hotfix/critical-login-bug ``` --- ### 提交规范 我们使用 Conventional Commits 规范: ``` <type>(<scope>): <subject> <body> <footer> ``` #### Type 类型 | 类型 | 说明 | |-----|------| | feat | 新功能 | | fix | Bug 修复 | | docs | 文档更新 | | style | 代码格式调整 | | refactor | 重构 | | perf | 性能优化 | | test | 测试相关 | | chore | 构建/工具相关 | #### Scope 范围 - `web`: Web 应用 - `admin`: 管理后台 - `api`: API 服务 - `ui`: UI 组件库 - `core`: 核心业务包 - `types`: 类型定义 - `utils`: 工具函数 - `config`: 配置 #### 提交示例 ```bash # 新功能 git commit -m "feat(web): add user login page" # Bug 修复 git commit -m "fix(api): handle null user in authentication" # 文档更新 git commit -m "docs: update quick start guide" # 重构 git commit -m "refactor(ui): restructure button component" # 带正文的提交 git commit -m "feat(web): add password reset - Add password reset form - Add email verification - Update API client Closes #123" ``` --- ## PR 规范 ### PR 流程 1. 创建分支并开发 2. 提交代码 3. 推送分支到远程 4. 创建 Pull Request 5. CI 检查 6. 代码审查 7. 修改(如果需要) 8. 合并 ### PR 模板 ```markdown ## 描述 简要描述这个 PR 的改动。 ## 类型 - [ ] feat (新功能) - [ ] fix (Bug 修复) - [ ] docs (文档更新) - [ ] style (代码格式) - [ ] refactor (重构) - [ ] perf (性能优化) - [ ] test (测试) - [ ] chore (构建/工具) ## 改动范围 - [ ] apps/web - [ ] apps/admin - [ ] services/api - [ ] packages/ui - [ ] packages/core - [ ] packages/types - [ ] packages/utils - [ ] 其他: ___ ## 测试 - [ ] 单元测试已添加/更新 - [ ] 集成测试已添加/更新 - [ ] E2E 测试已添加/更新 - [ ] 手动测试已完成 ## 截图(如果适用) 添加 UI 变化的截图。 ## 相关 Issue Closes #123, #456 ## 检查清单 - [ ] 代码符合项目规范 - [ ] 已添加必要的测试 - [ ] 文档已更新 - [ ] CI 检查通过 ``` ### 代码审查清单 审查者应该检查以下内容: #### 功能正确性 - [ ] 代码实现了预期功能 - [ ] 边界情况已处理 - [ ] 错误处理正确 #### 代码质量 - [ ] 代码清晰易读 - [ ] 命名有意义 - [ ] 没有重复代码 - [ ] 复杂度适中 #### 性能 - [ ] 没有明显的性能问题 - [ ] 数据库查询优化 - [ ] 缓存使用合理 #### 安全 - [ ] 输入已验证 - [ ] 没有 SQL 注入风险 - [ ] 敏感数据已保护 - [ ] 权限控制正确 #### 测试 - [ ] 测试覆盖充分 - [ ] 测试可以通过 - [ ] 测试有意义 #### 文档 - [ ] 代码注释充分 - [ ] API 文档已更新 - [ ] 使用文档已更新 ### 合并策略 - **Squash Merge**: 功能分支合并到 develop,保持提交历史整洁 - **Rebase Merge**: 保持线性历史 - **Merge Commit**: 保留完整提交历史(用于 main 分支) ```bash # Squash 合并示例 git checkout develop git merge --squash feature/user-authentication git commit -m "feat(web): add user authentication" ``` --- ## 最佳实践提示 ### 开发工作流 1. **开始工作前** ```bash git checkout develop git pull origin develop ``` 2. **创建分支** ```bash git checkout -b feature/your-feature-name ``` 3. **定期提交** ```bash git add . git commit -m "feat: your commit message" ``` 4. **推送到远程** ```bash git push -u origin feature/your-feature-name ``` 5. **创建 PR** - 在 GitHub/GitLab 上创建 PR - 填写 PR 模板 - 请求审查 6. **更新分支** ```bash git checkout develop git pull origin develop git checkout feature/your-feature-name git rebase develop ``` ### 避免常见错误 - ❌ 不要直接提交到 main 或 develop - ❌ 不要提交大文件(使用 Git LFS) - ❌ 不要提交敏感信息(API 密钥、密码等) - ❌ 不要忽略测试失败 - ✅ 保持提交小而专注 - ✅ 写有意义的提交信息 - ✅ 及时更新文档 --- ## 下一步 - [最佳实践](./best-practices.md) - 学习最佳实践 - [常见问题](./troubleshooting.md) - 查看常见问题 - [贡献指南](./contributing.md) - 了解如何贡献 --- > **文档维护**: 本文档由开发团队维护,如有问题或建议请提交 Issue。 > **最后更新**: 2026-05-25