前端工程规范
前言
前端工程规范是团队协作的基石。在多人、多项目的开发环境中,统一的技术规范能够有效降低沟通成本、减少代码缺陷、提升可维护性。本文从前端项目的目录组织、命名约定、Git 分支策略、Code Review 流程、版本管理、文档规范以及开发全流程七个维度,系统梳理一套可落地的前端工程规范体系。
目录规范
合理的目录结构是项目可维护性的第一道防线。前端项目通常采用 src 作为源码根目录,业务逻辑与基础设施清晰分离。
标准 src 结构
src/
├── api/ # API 接口层
│ ├── modules/ # 按业务模块划分的接口
│ ├── interceptors/ # 请求/响应拦截器
│ └── index.ts # 统一导出
├── assets/ # 静态资源
│ ├── images/
│ ├── fonts/
│ └── styles/ # 全局样式变量、mixin
├── components/ # 公共组件
│ ├── common/ # 通用组件(Button、Input、Modal 等)
│ ├── business/ # 业务组件
│ └── layout/ # 布局组件(Header、Sidebar、Footer)
├── composables/ # 组合式函数(Vue)
│ └── useAuth.ts
├── hooks/ # 自定义 Hook(React)
│ └── useAuth.ts
├── pages/ # 页面组件(Next.js Pages Router)
│ └── home/
├── views/ # 视图页面(Vue 或 React Router 视图)
│ ├── HomeView.vue
│ └── AboutView.vue
├── router/ # 路由配置
│ └── index.ts
├── store/ # 状态管理
│ └── modules/
├── types/ # 类型定义
│ ├── global.d.ts
│ ├── api.ts
│ └── models/
├── utils/ # 工具函数
│ ├── format.ts
│ └── constants.ts
├── main.ts # 入口文件
├── App.vue / App.tsx # 根组件
└── vite-env.d.ts页面组件划分
页面组件按业务模块存放在 views/ 或 pages/ 目录下。每个页面组件独立文件夹,包含其专属的子组件、样式和测试文件:
pages/
├── dashboard/
│ ├── index.tsx
│ ├── components/
│ │ ├── ChartWidget.tsx
│ │ └── StatsCard.tsx
│ ├── hooks/
│ │ └── useDashboardData.ts
│ ├── index.module.css
│ └── index.test.tsx
└── settings/
├── index.tsx
└── index.module.css公共组件
公共组件存放于 components/common/,要求:
- 无业务依赖:不直接引用 API、Store 或业务类型
- Props 驱动:所有数据通过 Props 传入
- 完整文档:使用 Storybook 或组件文档标注 Props 类型、默认值、用法示例
- 单一职责:一个组件只做一件事
工具函数与类型定义
utils/存放纯函数,禁止包含副作用或直接操作 DOMtypes/存放全局类型声明、接口定义、枚举;业务相关的类型与模块文件放在一起- 工具函数必须编写单元测试,覆盖率达到 90% 以上
路由与状态管理
- 路由配置统一放在
router/index.ts,使用懒加载(import())分割代码 - 状态管理按模块拆分,每个模块一个文件,存放在
store/modules/ - 禁止组件直接修改 Store 状态,必须通过 Action / Mutation
命名规范
统一的命名规范可以极大提升代码的可读性,减少团队成员之间的认知负担。
文件命名
| 类型 | 规范 | 示例 |
|---|---|---|
| Vue 组件 | PascalCase | UserCard.vue、TheHeader.vue |
| React 组件 | PascalCase | UserCard.tsx、ButtonGroup.tsx |
| 普通 TS/JS 文件 | camelCase | formatDate.ts、useAuth.ts |
| 样式文件 | kebab-case | user-card.module.css |
| 类型定义文件 | camelCase | api.types.ts、user.model.ts |
| 配置文件 | kebab-case | vite.config.ts、tailwind.config.ts |
组件命名
- 组件名使用 PascalCase,与文件名一致
- 通用组件使用基础名称,如
Button、Input、Modal - 业务组件使用领域前缀,如
UserCard、OrderTable - 布局组件加
The前缀:TheHeader、TheSidebar - 高阶组件加
with前缀:withAuth、withLoading
变量命名
- 变量使用 camelCase,如
userList、isLoading - 布尔值使用
is、has、should前缀:isVisible、hasError、shouldRender - 数组使用复数名词:
users、items - 函数使用动词开头:
getUser、submitForm、handleClick - 事件处理函数使用
on/handle前缀:onSubmit、handleChange - 禁止使用拼音或无意义缩写:
btn(可接受)、sz(不可接受)
常量命名
- 全局常量使用全大写加下划线:
MAX_FILE_SIZE、API_BASE_URL - 模块内常量使用 const 声明,camelCase 命名
- 枚举值使用 PascalCase
CSS 类名命名与 BEM
采用 BEM(Block Element Modifier)命名法:
/* Block:独立的组件名 */
.card { }
/* Element:依赖 Block 的子元素 */
.card__title { }
.card__body { }
/* Modifier:表示状态或变体 */
.card--featured { }
.card__title--large { }若使用 CSS Modules,可采用 camelCase 简写,但保持语义一致:
import styles from './card.module.css'
// styles.cardFeatured
// styles.cardTitle目录命名
- 目录使用 kebab-case:
user-profile/、data-table/ - 页面目录使用页面功能名称:
dashboard/、order-list/ - 组件分类目录使用复数:
components/、hooks/、utils/
Git 分支模型
选择合适的分支模型直接影响团队协作效率和发布质量。以下是三种主流模型的对比与应用场景。
Git Flow
Git Flow 是功能最为完整的分支模型,适用于有固定发布周期的成熟项目。
master ──●──────────●──────────●──
│ │ │
develop ──●──●──●────●──●──●────●──
│ │ │ │ │ │ │
feature/* └──┘ └─● │ │ │ │
│ │ │ │ │
release/* └──┘ └─●──────┘
│
hotfix/* └──●─────master:生产环境分支,只接受来自release和hotfix的合并develop:开发主分支,功能分支的集散地feature/*:功能开发分支,从develop拉出,完成后合并回developrelease/*:发布准备分支,用于测试和 Bug 修复,完成后同时合并到master和develophotfix/*:紧急修复分支,从master拉出,修复后同时合并到master和develop
GitHub Flow
GitHub Flow 是更轻量的模型,适用于持续部署的团队:
- 从
main拉出功能分支 - 在该分支上开发并提交
- 发起 Pull Request 进行 Code Review
- Review 通过后合并到
main - 立即部署到生产环境
优点:流程简单、部署频率高。缺点:不适用于有固定发布窗口的场景。
Trunk Based Development
主干开发模型,适用于 CI/CD 成熟度高的团队:
- 所有开发者直接在
main分支上提交小型变更 - 通过 Feature Flag 控制功能是否上线
- 短命分支存在时间不超过一天
优点:极致的持续集成,减少合并冲突。缺点:对团队纪律和自动化测试要求极高。
推荐方案
对于大多数前端团队,我们推荐简化版 Git Flow:
- 日常开发使用 GitHub Flow,从
main拉出feat/xxx分支 - 版本发布使用 Release 分支,从
main拉出release/v1.x.x - 紧急修复使用
hotfix/xxx分支 - 每两周或一个月进行一次版本发布
分支命名规范
feat/user-login # 新功能
fix/payment-bug # Bug 修复
refactor/api-layer # 重构
chore/update-deps # 工程配置
docs/api-docs # 文档更新
style/format-code # 代码格式
test/add-utils-test # 测试
release/v1.2.0 # 发布分支
hotfix/critical-crash # 紧急修复Release 策略
- 每个 Release 分支经过完整测试流程:单元测试 → 集成测试 → 人工验收
- Release 分支的版本号遵循 SemVer 规范
- 发布后打 Tag:
v1.2.0 - 如有严重 Bug,从对应 Tag 拉出
hotfix分支
Code Review
Code Review 是保障代码质量的核心环节,不仅仅是找 Bug,更是知识传递和团队成长的过程。
CR 流程
开发完成 → 自测通过 → 发起 PR → 指定 Reviewer → Review 通过 → 合并
↓
修改后重新 Review- 开发者自测:提交前完成本地测试,确保代码编译通过、Lint 无报错
- 发起 Pull Request:填写 PR 模板,描述变更内容和测试方法
- 指定 Reviewer:至少 1 人 Review,核心模块至少 2 人
- Review 过程:Reviewer 逐行阅读代码,在关键行留下评论
- 修改与反馈:开发者根据评论修改,标记已解决的 Discussion
- 合并:所有 Discussion 解决后,由 Reviewer 或作者合并
检查清单
Reviewer 应从以下维度检查代码:
正确性
- 逻辑是否正确?是否覆盖了所有分支条件?
- 异步操作是否有正确的错误处理?
- 边界条件(空数据、超长文本、并发请求)是否处理?
可维护性
- 代码是否遵循项目现有的设计模式?
- 函数/组件是否过长?能否拆分为更小的单元?
- 是否有重复代码可以提取?
性能
- 是否有不必要的重新渲染?
- 大列表是否使用虚拟滚动?
- 图片资源是否优化?
安全
- 用户输入是否经过校验和转义?
- 是否有 XSS / CSRF 风险?
- API 请求是否需要鉴权?
可测试性
- 是否有对应的单元测试?
- 测试用例是否覆盖了关键路径?
- Mock 是否合理?
自动化检查
在人工 Review 之前,自动化工具应当拦截大部分低级问题:
- ESLint:代码质量与风格检查
- Prettier:代码格式统一
- TypeScript:类型安全检查
- Stylelint:样式代码检查
- Jest / Vitest:单元测试,设置覆盖率阈值
- Commitlint:提交信息规范检查
- SonarQube / CodeQL:代码质量与安全扫描
建议通过 Husky + lint-staged 在提交前自动执行部分检查,通过 CI 在推送后执行完整检查。
PR 模板
### 变更描述
<!-- 描述本次变更的内容和动机 -->
### 关联 Issue
Closes #123
### 测试方法
1. 运行 `npm run test` 确认测试通过
2. 本地启动 Dev Server,验证页面渲染正常
3. 测试了以下场景:...
### 检查清单
- [ ] 代码遵循项目编码规范
- [ ] 新增代码有对应的单元测试
- [ ] 更新了相关文档
- [ ] 自测通过,无明显 Bug
- [ ] 无未处理的 Merge Conflict评审标准
- LGTM(Looks Good To Me):代码质量合格,可以合并
- Request Changes:存在需要修改的问题,修改后需重新 Review
- Approve with Comments:可以合并,但建议后续优化
- NIT(Nitpick):非必要的微小建议,作者可自行决定是否处理
版本管理
规范的版本管理是项目可持续交付的基础。
SemVer 语义化版本
版本号格式:MAJOR.MINOR.PATCH
- MAJOR:不兼容的 API 修改,如破坏性 UI 重构、数据类型变更
- MINOR:向下兼容的功能新增,如新增页面、新增 API
- PATCH:向下兼容的问题修复,如 Bug 修复、性能优化
对于前端项目,还需注意:
- 破坏性 UI 变更(如完全重写某个页面)应升级 MAJOR 版本
- 新增依赖或升级主版本依赖也应考虑 MAJOR 升级
- Beta / RC 版本使用预发布标签:
1.0.0-beta.1、1.0.0-rc.1
Changelog 规范
Changelog 应当自动生成,建议使用 standard-version 或 changesets。
Changelog 格式示例:
# Changelog
## [1.3.0] - 2026-07-15
### 新增
- 新增用户仪表盘页面
- 新增数据导出功能
### 修复
- 修复搜索分页偏移量错误
- 修复深色模式下按钮文字颜色
### 重构
- 将 API 层从 Axios 迁移到 Fetch API
### 工程
- 升级 Vite 到 6.0
- 添加 Playwright E2E 测试发布流程
开发 → 合并到 main → 创建 Release 分支 → CI 构建 → 预发布环境验收 → 打 Tag → 部署生产- 确认所有 Feature 已合并到
main - 从
main拉出release/vx.x.x分支 - 在 Release 分支上更新版本号和 Changelog
- 部署到预发布环境,进行集成测试和人工验收
- 验收通过后,合并到
main,打 Tag - 基于 Tag 构建生产版本并部署
- 在 Release Notes 中记录变更
回滚策略
- 立即回滚:生产环境发现严重 Bug,第一时间回滚到上一个稳定版本
- Hotfix:如果回滚成本高(如数据库迁移),在
main上修复后直接热修复 - Canary 发布:新版先发布给 10% 用户,观察半小时无异常再全量
- 蓝绿部署:保留上一版本实例,出现问题时快速切换流量
文档规范
API 文档
- 使用 TypeScript JSDoc 注释自动生成 API 文档
- 所有接口函数必须标注参数类型、返回值类型和用法示例
/**
* 获取用户列表
*
* @param params - 查询参数
* @param params.page - 页码(从 1 开始)
* @param params.pageSize - 每页数量(默认 20)
* @returns 用户列表和分页信息
*
* @example
* ```ts
* const { data, total } = await getUserList({ page: 1, pageSize: 10 })
* ```
*/
export async function getUserList(params: PaginationParams): Promise<PaginatedResult<User>>组件文档
使用 Storybook 编写组件文档:
- 每个公共组件至少有一个 Stories 文件
- 标注 Props 类型、默认值、Controls 配置
- 展示不同状态的 Stories(Loading、Empty、Error、Edge Cases)
README
每个前端项目根目录必须有 README.md,包含:
- 项目简介
- 技术栈
- 环境要求(Node 版本、包管理器版本)
- 快速开始步骤
- 项目目录结构说明
- 可用的 Scripts 命令
- 部署说明
- 贡献指南
Wiki 规范
- 架构决策记录(ADR)记录关键技术选型和设计决策
- 开发环境搭建指南
- 发布检查清单
- 常见问题 FAQ
开发流程规范
完整的开发流程覆盖从需求到上线的全生命周期。
需求阶段
- 产品经理输出 PRD(产品需求文档),包含业务描述、功能列表、验收标准
- 前端开发参与技术可行性评估,预估工时
- 输出技术方案文档,包含页面结构、数据流、组件拆分方案
设计阶段
- UI 设计师输出高保真设计稿,标注交互态和异常态
- 前端评审设计稿,关注布局方案、响应式方案、动效实现成本
- 确定数据 Mock 方案和接口定义
开发阶段
- 从
main拉出feat/xxx分支 - 按照目录规范和命名规范组织代码
- TDD(测试驱动开发)或并行编写测试
- 提交时通过 Husky 执行 Lint 检查和格式化
- 提交信息遵循 Conventional Commits 规范:
<type>(<scope>): <subject>
feat(user): add login page
fix(payment): fix amount calculation error
refactor(api): migrate to new API client- 开发完成后,在本地运行完整测试套件
测试阶段
- 冒烟测试:核心功能主流程验证
- 功能测试:逐条验收 PRD 中的功能点
- 回归测试:确认本次变更未影响已有功能
- 兼容性测试:主流浏览器(Chrome、Firefox、Safari、Edge)
- 性能测试:Lighthouse 评分不低于 80 分
发布阶段
- Code Review 通过后合并到
main - CI 流程自动执行构建和测试
- 部署到预发布环境
- QA / PM 在预发布环境验收
- 运行 E2E 测试
- 发布到生产环境
- 监控生产环境日志和错误率
Demo: 工程脚手架 CLI
以下 Demo 模拟了从零创建前端项目的脚手架 CLI 交互过程,展示了基于上述规范生成的标准项目结构:
总结:工程规范的价值不在于约束,而在于解放。当团队建立并遵守一套合理的规范体系后,开发者可以将更多精力投入到业务创新和技术突破中,而非纠结于代码风格、目录结构等琐碎事务。规范应当随着团队和项目的成长持续迭代,而不是一成不变的教条。