文章
前端 Code Review 完全指南
前端 Code Review 完全指南 一份适合中国小型前端团队的代码审查实战手册,从流程搭建到落地执行,手把手教你做好 Code Review 目录 1. 核心概念 2. 基础流程 3. 审查清单 4. 实战场景 5....
前端 Code Review 完全指南 #
一份适合中国小型前端团队的代码审查实战手册,从流程搭建到落地执行,手把手教你做好 Code Review
目录 #
一、核心概念 #
1.1 什么是 Code Review?(大白话) #
Code Review(代码审查) 就是同事之间互相检查代码,就像写文章让朋友帮忙校对一样。
你写了一段代码,提交之前让另一个同事看一遍:
- 代码逻辑对不对?
- 有没有明显的 bug?
- 代码风格是否符合团队规范?
- 性能有没有问题?
这就像 考试前互相检查试卷,你可能没发现错误,但同学一眼就看到了。
1.2 为什么小型团队也需要 Code Review? #
很多人觉得:"我们团队只有 3-5 个人,没必要搞 Code Review"。其实恰恰相反!
| 团队规模 | 不做 Code Review 的风险 | 做 Code Review 的收益 |
|---|---|---|
| 大团队(20+) | 代码风格混乱、Bug 难追溯 | 标准化、质量可控 |
| 小团队(3-5) | 一人出错全项目翻车 | 互相学习、快速成长 |
小型团队的特殊价值:
- 知识共享 — 小团队往往只有 1 个资深 + 几个初级,Review 是初级工程师学习的最佳途径
- 兜底保障 — 小团队没有专门的 QA,Review 是最后一道防线
- 避免单点故障 — 不会"某人的代码只有他自己能看懂"
- 文化沉淀 — 小团队更容易养成好习惯,做大后自然延续
1.3 Code Review 的核心名词 #
| 名词 | 大白话解释 | 举例 |
|---|---|---|
| PR/MR | Pull Request / Merge Request,代码合并请求 | "我提交了一个 PR,你来帮我 Review" |
| Reviewer | 审查代码的人 | "老王是这个 PR 的 Reviewer" |
| Author | 写代码并提交 PR 的人 | "小李是 Author" |
| Approve | 同意合并,审查通过 | "我 Approve 了,可以合并" |
| Request Changes | 要求修改,审查不通过 | "Request Changes,这个地方有问题" |
| Comment | 评论,非强制性的建议或提问 | "留了个 Comment,建议优化变量名" |
| Merge | 合并代码到主分支 | "Review 通过,已 Merge" |
| Diff | 代码变更对比,新增/删除的内容 | "看 Diff,只改了 3 行代码" |
1.4 Code Review ≠ 批评大会 #
很多新人害怕 Code Review,觉得像是被"批作业"。这是误解。
Code Review 的正确心态:
| 错误心态 | 正确心态 |
|---|---|
| "Reviewer 在挑刺" | "Reviewer 在帮我发现问题" |
| "被 Request Changes 很丢脸" | "发现问题比上线出 bug 好得多" |
| "Review 是浪费时间" | "Review 是节约未来的时间" |
| "我只改 Reviewer 提的问题" | "Review 是学习的机会" |
核心原则:Review 是为了提高质量,不是为了评判能力。
二、基础流程 #
2.1 一个完整的 Code Review 流程 #
从写代码到合并,完整流程如下:
┌─────────────────────────────────────────────────────────────┐
│ Code Review 完整流程 │
└─────────────────────────────────────────────────────────────┘
Author(写代码的人) Reviewer(审查的人)
│ │
│ ① 开发分支 │
│ git checkout -b feature/xxx │
│ │
│ ② 编写代码 │
│ 写功能 + 自测 │
│ │
│ ③ 提交 PR │
│ 填写 PR 描述 │
│───────────────────────────────────>│
│ │ ④ 审查代码
│ │ 看 Diff + 检查清单
│ │
│ │ ⑤ 给出反馈
│<───────────────────────────────────│ Approve / Changes / Comment
│ │
│ ⑥ 修改代码(如果需要) │
│ 根据 Review 意见修改 │
│ 推送新提交 │
│───────────────────────────────────>│
│ │ ⑦ 再次审查
│ │ 确认修改正确
│ │
│ │ ⑧ Approve
│<───────────────────────────────────│
│ │
│ ⑨ 合并代码 │
│ Merge PR │
│ │
▼ ▼2.2 Author 的职责(提交 PR 前) #
提交 PR 前,Author 必须自查:
| 检查项 | 自查方法 | 避免的尴尬 |
|---|---|---|
| 功能是否正常 | 本地跑一遍,测主要场景 | "这个功能根本跑不起来" |
| 是否有 lint 错误 | npm run lint |
"格式错误,请先修复" |
| 是否有类型错误 | npm run type-check(TS 项目) |
"TypeScript 报错" |
| 是否有测试 | npm run test |
"测试失败了" |
| 改动范围是否过大 | git diff --stat |
"改动 50 个文件,拒绝 Review" |
| PR 描述是否清晰 | 按 PR 模板填写 | "这个 PR 干嘛的?" |
自查模板:
## PR 描述模板(Author 填写)
### 本次改动
- 功能:[简述做了什么]
- 影响范围:[哪些模块被改了]
- 关联 Issue:[如果有,填写 Issue 号]
### 自测情况
- ✅ 本地功能测试通过
- ✅ lint 检查通过
- ✅ 单元测试通过(如有)
- ⚠️ 注意事项:[需要 Reviewer 关注的点]
### 截图/演示
[如果有 UI 改动,贴截图]2.3 Reviewer 的职责(审查代码时) #
Reviewer 审查时的步骤:
步骤 1:看 PR 描述
↓ 了解改动的背景和目的
步骤 2:看 Diff 概览
↓ git diff --stat 或 GitHub/GitLab 的文件列表
步骤 3:逐文件审查
↓ 重点文件详细看,次要文件快速浏览
步骤 4:运行代码(必要时)
↓ 本地拉代码跑一遍
步骤 5:给出反馈
↓ Approve / Request Changes / Comment审查优先级:
| 优先级 | 检查内容 | 说明 |
|---|---|---|
| P0 | 逻辑正确性 | 功能是否正确,有没有 bug |
| P1 | 安全问题 | XSS、SQL 注入、敏感信息泄露 |
| P2 | 性能问题 | 不必要的重渲染、内存泄漏 |
| P3 | 代码风格 | 命名、注释、格式 |
| P4 | 优化建议 | 可读性提升、重构建议 |
2.4 PR 描述的黄金模板 #
好的 PR 描述让 Reviewer 一眼就懂:
## ✅ 好的 PR 描述示例
### 功能说明
新增用户登录页面,支持手机号 + 验证码登录。
### 改动文件
- `src/pages/Login.tsx` — 新增登录页面
- `src/api/auth.ts` — 新增登录 API
- `src/hooks/useAuth.ts` — 新增认证 Hook
### 自测情况
- ✅ 手机号登录流程正常
- ✅ 验证码倒计时正常
- ✅ 错误提示显示正常
- ✅ lint + test 通过
### 需要关注
- 验证码 API 有 60 秒冷却时间,测试时注意
- 登录成功后的跳转逻辑,请重点看一下
### 截图
[登录页面截图]## ❌ 差的 PR 描述示例
修复了一些问题,改了几个文件。
(Reviewer 心里:???)三、审查清单 #
3.1 前端 Code Review 必查清单 #
把这份清单保存下来,每次 Review 对照检查:
🔴 P0:必须检查(阻塞合并) #
| 类别 | 检查项 | 问题示例 |
|---|---|---|
| 逻辑正确 | 功能是否按预期工作 | 登录失败后没有清空表单 |
| 逻辑正确 | 边界条件是否处理 | 空数组、null、undefined 未处理 |
| 逻辑正确 | 异步操作是否正确 | Promise 未 catch、loading 状态未处理 |
| 安全 | 是否有 XSS 风险 | 直接渲染用户输入 innerHTML |
| 安全 | 是否有敏感信息泄露 | Token 写在 URL、密码打印日志 |
| 安全 | API 请求是否安全 | 前端直接调用内网 API |
🟡 P1:强烈建议检查(优先处理) #
| 类别 | 检查项 | 问题示例 |
|---|---|---|
| 性能 | 是否有不必要的重渲染 | 组件内创建新对象/函数每次触发 render |
| 性能 | 是否有内存泄漏 | 定时器未清除、事件未解绑 |
| 性能 | 大列表是否优化 | 1000 条数据未用虚拟列表 |
| 错误处理 | 错误是否正确处理 | catch 后静默失败、无错误提示 |
| 错误处理 | 加载状态是否处理 | 无 loading、loading 未消失 |
🟢 P2:建议检查(可后续优化) #
| 类别 | 检查项 | 问题示例 |
|---|---|---|
| 可读性 | 变量/函数命名是否清晰 | a、data1、handleClick1 |
| 可读性 | 是否有必要的注释 | 复杂逻辑无注释、魔法数字无说明 |
| 可读性 | 函数是否过长 | 一个函数 100+ 行 |
| 风格 | 是否符合团队规范 | 用 var、分号风格不一致 |
| 结构 | 是否有重复代码 | 多处相同逻辑可抽取公共函数 |
3.2 按文件类型的专项清单 #
React/Vue 组件审查 #
## React 组件审查清单
- [ ] 组件职责是否单一(一个组件只做一件事)
- [ ] Props/State 是否最小化(不需要的数据不传)
- [ ] 是否有 useEffect/useWatch 的正确清理
- [ ] 事件处理函数命名是否规范(handleXxx)
- [ ] 条件渲染是否正确(&& 与 ? 的使用)
- [ ] 列表渲染是否有 key(且 key 是否正确)
- [ ] 是否有性能优化(memo、useMemo、useCallback)API 请求审查 #
## API 请求审查清单
- [ ] 是否有 loading 状态
- [ ] 是否有错误处理
- [ ] 是否有请求取消(页面卸载时)
- [ ] 是否有重复请求防护(防抖/节流)
- [ ] 响应数据是否校验(null 检查)
- [ ] 是否有请求缓存(必要时)样式审查 #
## CSS 样式审查清单
- [ ] 是否有硬编码颜色/尺寸(应使用变量)
- [ ] 是否有响应式设计(必要时)
- [ ] 是否有性能问题(避免复杂选择器)
- [ ] 是否有命名规范(BEM/其他)
- [ ] 是否有 z-index 冲突风险3.3 常见问题速查表 #
| 看到这个 | 可能的问题 | 建议 |
|---|---|---|
var |
使用过时语法 | 改用 let/const |
innerHTML = userInput |
XSS 风险 | 使用文本渲染或 sanitization |
setTimeout 未 clearTimeout |
内存泄漏 | 组件卸载时清除 |
useEffect(() => { ... }) |
可能缺少清理 | 检查是否需要 return cleanup |
组件内 const obj = {} |
每次渲染创建新对象 | 移到组件外或用 useMemo |
fetch().then() 无 catch |
未处理错误 | 加 catch 或 try-catch |
| 数组渲染无 key | React 警告 | 加唯一 key |
a, b, c 变量名 |
命名不清晰 | 改有意义的名字 |
| 函数 50+ 行 | 职责过多 | 拆分函数 |
注释 // todo |
未完成 | 要求完成或标记清楚 |
四、实战场景 #
场景 1:Review 一个 React 登录组件 #
Author 提交的代码:
// Login.tsx
import React, { useState } from 'react';
function Login() {
const [phone, setPhone] = useState('');
const [code, setCode] = useState('');
const handleSubmit = async () => {
const res = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ phone, code })
});
const data = await res.json();
if (data.success) {
window.location.href = '/home';
}
};
return (
<div>
<input value={phone} onChange={e => setPhone(e.target.value)} />
<input value={code} onChange={e => setCode(e.target.value)} />
<button onClick={handleSubmit}>登录</button>
</div>
);
}Reviewer 的反馈:
## Review 反馈
### 🔴 必须修改(Request Changes)
1. **错误处理缺失**
```tsx
// 问题:fetch 没有 catch,请求失败时用户无感知
const handleSubmit = async () => {
const res = await fetch('/api/login', { ... });
// ❌ 没有 try-catch 或 catch
};
// 建议:
const handleSubmit = async () => {
try {
const res = await fetch('/api/login', { ... });
if (!res.ok) throw new Error('请求失败');
const data = await res.json();
if (data.success) {
window.location.href = '/home';
} else {
// ✅ 显示错误提示
alert(data.message || '登录失败');
}
} catch (err) {
alert('网络错误,请重试');
}
};- Loading 状态缺失
// 问题:提交过程中按钮没有禁用,用户可能重复点击 // 建议: const [loading, setLoading] = useState(false); const handleSubmit = async () => { setLoading(true); try { ... } finally { setLoading(false); } }; <button onClick={handleSubmit} disabled={loading}> {loading ? '登录中...' : '登录'} </button>
🟡 建议优化(Comment) #
-
输入验证
// 建议:添加手机号格式验证 const isValidPhone = /^1\d{10}$/.test(phone); if (!isValidPhone) { alert('请输入正确的手机号'); return; } -
input 缺少 placeholder 和 type
<input type="tel" placeholder="请输入手机号" value={phone} onChange={e => setPhone(e.target.value)} />
### 场景 2:Review 一个列表渲染优化
**Author 提交的代码:**
```tsx
// UserList.tsx
function UserList({ users }) {
return (
<div>
{users.map(user => (
<div key={user.id}>
<span>{user.name}</span>
<span>{user.age}</span>
<button onClick={() => deleteUser(user.id)}>删除</button>
</div>
))}
</div>
);
}Reviewer 的反馈:
## Review 反馈
### ✅ 基本正确
- key 使用正确(user.id)
- 渲染逻辑清晰
### 🟡 建议优化
1. **大列表性能问题**
```tsx
// 问题:如果 users 有 1000+ 条,会有性能问题
// 建议:使用虚拟列表(react-window 或 react-virtualized)
import { FixedSizeList } from 'react-window';
function UserList({ users }) {
const Row = ({ index, style }) => (
<div style={style}>
<span>{users[index].name}</span>
<span>{users[index].age}</span>
<button onClick={() => deleteUser(users[index].id)}>删除</button>
</div>
);
return (
<FixedSizeList
height={400}
itemCount={users.length}
itemSize={50}
>
{Row}
</FixedSizeList>
);
}-
空数据处理
// 问题:users 为空时显示空白 // 建议: if (users.length === 0) { return <div className="empty">暂无数据</div>; } -
事件处理优化
// 问题:每个 item 都创建新的 onClick 函数 // 建议: const handleDelete = useCallback((id) => { deleteUser(id); }, [deleteUser]); <button onClick={() => handleDelete(user.id)}>删除</button>
### 场景 3:Review 一个 API 封装
**Author 提交的代码:**
```ts
// api.ts
export async function getUser(id: string) {
const res = await fetch(`/api/user/${id}`);
return res.json();
}
export async function updateUser(id: string, data: any) {
const res = await fetch(`/api/user/${id}`, {
method: 'PUT',
body: JSON.stringify(data)
});
return res.json();
}Reviewer 的反馈:
## Review 反馈
### 🔴 必须修改
1. **类型定义缺失**
```ts
// 问题:data 是 any,没有类型约束
// 建议:
interface User {
name: string;
age: number;
email?: string;
}
export async function updateUser(id: string, data: Partial<User>) {
...
}-
响应状态检查
// 问题:未检查 res.ok // 建议: export async function getUser(id: string): Promise<User> { const res = await fetch(`/api/user/${id}`); if (!res.ok) { throw new Error(`获取用户失败: ${res.status}`); } return res.json(); } -
请求取消
// 问题:页面切换时请求未取消 // 建议:返回 AbortController export async function getUser(id: string, signal?: AbortSignal) { const res = await fetch(`/api/user/${id}`, { signal }); ... } // 使用: const controller = new AbortController(); getUser('123', controller.signal); // 页面卸载时 controller.abort();
🟢 建议优化 #
- 统一错误处理
// 建议:封装统一的请求函数 async function request<T>(url: string, options?: RequestInit): Promise<T> { const res = await fetch(url, options); if (!res.ok) { const error = await res.json().catch(() => ({ message: '请求失败' })); throw new Error(error.message); } return res.json(); }
---
## 五、团队落地
### 5.1 小团队如何开始 Code Review?
**从零开始,分三阶段:**
#### 阶段 1:自愿尝试(第 1-2 周)
| 做法 | 目的 |
|------|------|
| 只要求重要功能提交 PR | 降低门槛,不强制 |
| Reviewer 自愿认领 | 避免分配压力 |
| 只给 Comment,不给 Request Changes | 鼓励性反馈 |
| 每周复盘一次 | 收集问题,调整规则 |
#### 阶段 2:强制执行(第 3-4 周)
| 做法 | 目的 |
|------|------|
| 所有代码必须走 PR | 养成习惯 |
| 每个 PR 必须有 Reviewer Approve | 确保质量 |
| Request Changes 正常使用 | 问题必须修改 |
| 制定 Review 检查清单 | 标准化流程 |
#### 阶段 3:成熟阶段(1 个月后)
| 做法 | 目的 |
|------|------|
| 自动化检查先行(lint、test) | 减少人工检查 |
| Review 时间纳入工作量计算 | 避免 Review 成为负担 |
| 建立 Review 积分/奖励 | 激励积极性 |
| 定期 Review 复盘会议 | 持续改进 |
### 5.2 PR 大小控制
**小型团队的特殊问题:PR 太大。**
| PR 大小 | Review 效果 | 建议 |
|---------|------------|------|
| < 200 行 | 快速看完,质量高 | ✅ 理想大小 |
| 200-500 行 | 需要时间,但可控 | ⚠️ 可以接受 |
| 500-1000 行 | 很难仔细看完 | ❌ 建议拆分 |
| > 1000 行 | 几乎无法有效 Review | ❌ 必须拆分 |
**拆分 PR 的方法:**
```markdown
## 大 PR 拆分示例
原 PR:新增用户模块(1000+ 行)
- 用户列表页面
- 用户详情页面
- 用户编辑页面
- 用户 API
- 用户 Hook
拆分后:
PR 1:用户 API + Hook(200 行)
PR 2:用户列表页面(300 行)
PR 3:用户详情页面(250 行)
PR 4:用户编辑页面(250 行)5.3 Reviewer 分配策略 #
小团队(3-5 人)的分配策略:
| 团队构成 | 分配策略 | 原因 |
|---|---|---|
| 1 资深 + 2 初级 | 资深审查所有 | 初级审查资深的代码可能能力不足 |
| 2 资深 + 2 初级 | 资深互审 + 资深审初级 | 资深之间互相把关 |
| 3 资深 | 每人审 1/3 | 均分工作量 |
| 全初级 | 外部求助或交叉审 | 互相学习,必要时请教外部 |
分配原则:
- 避免审查自己的代码 — 自我审查无效
- 业务相关者优先 — 改了支付模块,支付负责人审
- 轮换避免疲劳 — 不要总让同一个人审
- 能力匹配 — 复杂代码让资深审,简单代码让初级审(学习机会)
5.4 Review 时间控制 #
Review 不应该是无限制的:
| PR 类型 | 建议 Review 时间 | 超时处理 |
|---|---|---|
| 紧急修复(hotfix) | 30 分钟内 | 过时不审,直接合并(记录原因) |
| 常规 PR | 1 天内 | 超时提醒,必要时催促 |
| 大型重构 | 2-3 天 | 安排专门时间审查 |
避免 Review 堆积:
## Review 积压处理
问题:PR 提交 3 天了还没人审
解决方案:
1. 每日站会提醒:"今天有 3 个 PR 待审,请认领"
2. 自动提醒:PR 超过 24 小时未审,自动发消息提醒
3. Review 积分:快速 Review 有积分奖励
4. 强制要求:每人每天至少审 1 个 PR(或轮值)5.5 反馈礼仪 #
Code Review 的沟通方式很重要:
| 场景 | 好的表达 | 不好的表达 |
|---|---|---|
| 发现 bug | "这里有个潜在的 bug,当 data 为 null 时会报错" | "你这代码有问题" |
| 建议优化 | "建议把这个函数拆分成两个,职责会更清晰" | "这代码写得乱七八糟" |
| 询问原因 | "这里用 setTimeout 的原因是什么?是否有更好的方案?" | "为什么要这样写?" |
| 同意合并 | "代码质量不错,可以合并" | "还行吧" |
黄金法则:
- 对事不对人 — 评论代码,不评论人
- 解释原因 — 说明为什么有问题,不只是指出问题
- 给出方案 — 不只说问题,还要给建议
- 鼓励学习 — Review 是互相学习的机会
六、常见问题 #
Q1:团队只有 3 个人,怎么分配 Reviewer? #
答案:轮流审查 + 资深兜底。
| 人数 | 分配方案 |
|---|---|
| 3 人(1 资深 + 2 初级) | 资深审初级,初级互审(资深复查) |
| 3 人(全资深) | 轮流审,每人审 1/3 |
| 3 人(全初级) | 交叉审 + 必要时请外部资深帮忙 |
Q2:Reviewer 和 Author 资深程度差不多,审查有效吗? #
答案:有效,但重点不同。
| Author 资深度 | Reviewer 资深度 | 审查重点 |
|---|---|---|
| 资深 | 资深 | 业务逻辑、设计决策、边缘场景 |
| 初级 | 初级 | 代码风格、常见错误、互相学习 |
| 初级 | 资深 | 全面审查 + 教学指导 |
Q3:紧急修复(hotfix)还要走 PR 吗? #
答案:必须走,但可以简化流程。
## Hotfix PR 处理流程
1. 直接创建 hotfix 分支,快速修复
2. 提交 PR,标注 [HOTFIX]
3. 资深立即 Review(30 分钟内)
4. Review 通过后立即合并
5. 合并后复盘:为什么需要 hotfix?如何避免?Q4:PR 改动太大,怎么审查? #
答案:要求拆分,或分批次审查。
| 情况 | 处理方式 |
|---|---|
| PR 可以拆分 | 要求 Author 拆成多个小 PR |
| PR 无法拆分(如重构) | 安排专门时间审查,分几天完成 |
| PR 堆积很久 | 检查是否 PR 管理有问题,改进流程 |
Q5:Author 不同意 Reviewer 的意见怎么办? #
答案:讨论解决,必要时请第三方。
## 意见分歧处理
1. Author 解释代码设计的原因
2. Reviewer 解释建议的理由
3. 双方讨论,找到最佳方案
4. 如无法达成一致,请团队资深或 Leader 判定
5. 最终结果记录在 PR 中,作为团队经验Q6:Review 太花时间,影响开发进度怎么办? #
答案:Review 是开发的一部分,纳入工作量。
| 做法 | 效果 |
|---|---|
| Review 时间计入工作量 | Review 不成为额外负担 |
| 控制每次 PR 大小 | 小 PR 审得快 |
| 自动化检查先行 | 减少人工检查的工作量 |
| 建立 Review 积分制度 | 激励快速 Review |
Q7:远程团队怎么做 Code Review? #
答案:工具 + 文档 + 约定。
| 工具 | 用途 |
|---|---|
| GitHub/GitLab PR | 异步 Review |
| 钉钉/飞书 PR 通知 | 及时提醒 |
| 屏幕共享 + 语音 | 复杂 PR 实时讨论 |
| PR 模板 + 检查清单 | 标准化流程 |
七、工具推荐 #
7.1 必备工具 #
| 工具 | 用途 | 优点 |
|---|---|---|
| GitHub PR | 代码托管 + Review | 免费、易用、生态丰富 |
| GitLab MR | 代码托管 + Review | 私有部署、功能全面 |
| ESLint | 自动检查代码风格 | 减少人工检查 |
| Prettier | 自动格式化 | 格式统一,无需争论 |
| Husky | Git Hooks 自动检查 | 提交前自动 lint |
7.2 可选工具 #
| 工具 | 用途 | 适用场景 |
|---|---|---|
| Danger.js | PR 自动检查提醒 | 大团队、自动化需求高 |
| CodeClimate | 代码质量分析 | 有预算的团队 |
| Review Dog | 自动化 Review 辅助 | CI/CD 集成 |
| GitHub Copilot | AI 辅助写代码 | 提高开发效率 |
7.3 团队配置示例 #
# .github/pull_request_template.md(PR 模板)
## 功能说明
[本次改动的内容]
### 改动文件
- [文件列表]
### 自测情况
- [ ] 功能测试通过
- [ ] lint 检查通过
- [ ] 单元测试通过(如有)
### 需要关注
[需要 Reviewer 关注的点]
### 截图
[如有 UI 改动]// .eslintrc.json(Lint 配置)
{
"extends": ["eslint:recommended", "plugin:react/recommended"],
"rules": {
"no-unused-vars": "error",
"react-hooks/exhaustive-deps": "warn"
}
}// .husky/pre-commit(提交前自动检查)
{
"hooks": {
"pre-commit": "npm run lint && npm run test"
}
}八、总结速记 #
核心概念表 #
| 名词 | 解释 |
|---|---|
| PR/MR | 代码合并请求 |
| Reviewer | 审查代码的人 |
| Author | 提交代码的人 |
| Approve | 审查通过 |
| Request Changes | 要求修改 |
| Comment | 评论/建议 |
Review 检查清单速记 #
P0 必查:逻辑正确 + 安全问题
P1 建议:性能 + 错误处理
P2 优化:可读性 + 风格 + 结构PR 大小控制 #
< 200 行:理想
200-500:可控
500-1000:建议拆分
> 1000:必须拆分反馈礼仪 #
对事不对人
解释原因 + 给方案
鼓励学习小团队 Review 策略 #
阶段 1:自愿尝试(低门槛)
阶段 2:强制执行(养成习惯)
阶段 3:成熟阶段(自动化 + 激励)附录:命令速查表 #
Git 常用命令 #
# 创建分支
git checkout -b feature/xxx
# 查看 Diff
git diff # 未提交的改动
git diff main # 当前分支与 main 的差异
git diff --stat # 改动统计
# 提交 PR(GitHub)
git push origin feature/xxx
# 然后在 GitHub 网页创建 PR
# 更新 PR(根据 Review 修改后)
git add .
git commit -m "fix: 根据 Review 修改"
git push origin feature/xxxGitHub PR 操作 #
# 查看 PR 列表
gh pr list
# 查看 PR 详情
gh pr view 123
# Approve PR
gh pr review 123 --approve
# Request Changes
gh pr review 123 --request-changes -b "问题描述"
# Comment
gh pr review 123 --comment -b "建议内容"
# 合并 PR
gh pr merge 123推荐资源 #
| 资源 | 链接 | 说明 |
|---|---|---|
| GitHub PR 文档 | https://docs.github.com/pull-requests | 官方指南 |
| Google Engineering Practices | https://google.github.io/eng-practices/review/ | Google 的 Review 规范 |
| ESLint 配置指南 | https://eslint.org/docs/latest/use/configure/ | Lint 配置 |
| Husky 文档 | https://typicode.github.io/husky/ | Git Hooks |
最后更新:2026-03-29
继续阅读
返回文章列表上一篇
Promise 完全指南下一篇
前端媒体资源完全指南