跳到主要内容

如何衡量前端代码质量

问题

你怎么衡量一个前端项目的代码质量?有哪些指标?

回答思路

1. 代码质量的维度

2. 可量化的指标

指标工具推荐阈值说明
测试覆盖率Vitest / Jest≥ 70%(核心逻辑 ≥ 90%)衡量测试充分度
类型覆盖率TypeScriptstrict mode 100%衡量类型安全
Lint 通过率ESLint0 error代码规范遵守程度
包体积bundle-analyzer首屏 JS < 200KB性能相关
圈复杂度ESLint rule函数 < 10代码复杂度
重复代码率jscpd< 5%代码复用程度
依赖安全npm audit0 high/critical依赖安全
Core Web VitalsLighthouseLCP < 2.5s, CLS < 0.1用户体验

3. 高质量代码 vs 低质量代码

❌ 低质量代码
// 1. 命名不清晰
const d = new Date();
const fn = (a: any, b: any) => a + b;

// 2. 过长函数(做了太多事情)
function handleSubmit(formData) {
// 50 行校验逻辑...
// 30 行数据转换...
// 20 行 API 调用...
// 10 行错误处理...
// 总共 110 行
}

// 3. 硬编码
if (user.role === 1) { /* admin */ }
if (status === 'XFHJ2K') { /* ??? */ }

// 4. 没有错误处理
const data = JSON.parse(input);
const value = obj.a.b.c.d;
✅ 高质量代码
// 1. 命名清晰,自解释
const createdAt = new Date();
const calculateTotal = (price: number, quantity: number): number => price * quantity;

// 2. 职责单一,函数简短
function handleSubmit(formData: FormData): void {
const validationResult = validateForm(formData);
if (!validationResult.isValid) {
showErrors(validationResult.errors);
return;
}

const payload = transformFormData(formData);
submitToServer(payload);
}

// 3. 使用常量和枚举
const enum UserRole {
Admin = 1,
Editor = 2,
Viewer = 3,
}
if (user.role === UserRole.Admin) { /* ... */ }

// 4. 完善的错误处理
const data = safeJsonParse<UserData>(input, defaultValue);
const value = obj?.a?.b?.c?.d ?? fallbackValue;

4. 建立质量度量体系

集成到 CI 流水线

.github/workflows/quality.yml
name: Code Quality
on: [pull_request]

jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Lint 检查
- run: pnpm lint

# 类型检查
- run: pnpm tsc --noEmit

# 单元测试 + 覆盖率
- run: pnpm test --coverage

# 覆盖率门禁
- uses: codecov/codecov-action@v3
with:
fail_ci_if_error: true

# 包体积检查
- run: pnpm build
- uses: andresz1/size-limit-action@v1

5. 代码质量改进策略

阶段策略工具
编码时ESLint 实时提示 + TypeScript 类型检查IDE 插件
提交前lint-staged + husky 拦截pre-commit hooks
CR 时人工 Review + AI 辅助GitHub PR + CodeRabbit
CI 时自动化测试 + 覆盖率门禁 + 体积检查GitHub Actions
上线后错误监控 + 性能监控Sentry + Web Vitals

常见面试问题

Q1: 代码质量和开发速度如何平衡?

答案

短期看是矛盾的,长期看高质量代码反而更快:

  • 短期:写测试、做 CR 会花更多时间
  • 长期:高质量代码减少 Bug、减少维护成本、新功能开发更快

平衡策略:

  1. 自动化规范检查:让机器处理格式、简单 Bug,减少人工负担
  2. 按重要度分层:核心逻辑严格要求,边缘功能适当放宽
  3. 技术债定期偿还:不追求完美,但持续改进
  4. 团队共识:对"什么是可接受的质量"达成共识

Q2: 圈复杂度是什么?怎么降低?

答案

圈复杂度(Cyclomatic Complexity)衡量代码中独立执行路径的数量。每多一个 ifforcase,复杂度 +1。

降低圈复杂度
// ❌ 复杂度高(多层嵌套 if)
function getDiscount(user: User): number {
if (user.isVip) {
if (user.level >= 3) {
if (user.years > 5) return 0.5;
return 0.7;
}
return 0.85;
}
return 1;
}

// ✅ 使用早返回 + 策略表降低复杂度
const discountRules: Array<{ match: (u: User) => boolean; discount: number }> = [
{ match: (u) => u.isVip && u.level >= 3 && u.years > 5, discount: 0.5 },
{ match: (u) => u.isVip && u.level >= 3, discount: 0.7 },
{ match: (u) => u.isVip, discount: 0.85 },
];

function getDiscount(user: User): number {
return discountRules.find((rule) => rule.match(user))?.discount ?? 1;
}

Q3: 你如何推动团队提升代码质量?

答案

  1. 工具先行:配置 ESLint + Prettier + TypeScript strict,让工具自动保障基础质量
  2. 建立 CR 文化:制定 CR 规范,每个 PR 必须 Review
  3. 写好测试:Leader 带头写测试,核心逻辑必须有测试覆盖
  4. Code Quality Dashboard:可视化展示各项指标,定期 Review
  5. Knowledge Sharing:分享好的代码模式和反面案例

Q4: 测试覆盖率高就代表质量好吗?

答案

不一定。测试覆盖率是必要条件,但不是充分条件:

  • 100% 覆盖率 ≠ 没有 Bug:可能覆盖了行但没覆盖分支
  • 有效的测试更重要:测试应该验证行为而非实现细节
  • 关键路径优先:核心业务逻辑 90%+,工具函数 80%+,UI 组件关注行为
好测试 vs 坏测试
// ❌ 坏测试:测试实现细节
test('should call setState', () => {
const setState = vi.fn();
// 测试内部实现...
});

// ✅ 好测试:测试行为
test('should show error when input is invalid', () => {
render(<LoginForm />);
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
expect(screen.getByText('Email is required')).toBeInTheDocument();
});

相关链接