Skip to content
返回质量保障

审查工具

用工具(linter、类型检查器、测试覆盖)自动化机械检查使审查者聚焦逻辑。

为什么

代码审查时间稀缺,花在机械检查(风格、格式、类型错误、缺测试)是浪费——这些正是工具比人强的事。linter 0.1s 抓风格违规;人花 30 秒找和写评论、作者花 5 分钟修和回、循环重复下违规。CI 自动这些检查使 PR 不通过 linter、类型检查器和测试覆盖阈值不能开——审查者永不见风格违规、类型错误或未测代码,时间花仅人能做的事: 逻辑、架构、安全、命名。这使审查更快(15 分钟非一小时)、更有价值(反馈关于设计非格式)、更不挫(无人喜评论缺分号)。

何时使用

项目开始时设工具 CI 强制。团队识别重复检查时增量加工具。

如何做

1. linter(ESLint、Biome、Ruff、golangci-lint)
   - 强风格、抓常见 bug、禁不安全模式
   - CI 每 PR 跑、违规坏
   - 配规则匹配团队约定
   - 自动修可自动修的(格式、导入顺序)

2. 格式化器(Prettier、gofmt、rustfmt、black)
   - 消格式讨论——工具决定
   - 保存时跑(编辑器)和 CI 中(强制)
   - 审查中永无格式评论

3. 类型检查器(TypeScript、mypy、pyright)
   - 运行前抓类型错误
   - 类型错误坏构建
   - 用严格模式(无隐 any、无 null 无显检查)

4. 测试覆盖(jest --coverage、pytest --cov、go test -cover)
   - 新代码要求覆盖(如新行 80%)
   - 覆盖降阈值下坏构建
   - 覆盖是地板非目标——100% 覆盖不意味好测试

5. 预提交钩子(husky、lefthook、pre-commit)
   - 提交时跑 linter、格式化器和类型检查器
   - 检查坏提交坏——开发者推前修
   - 这在到 CI 前更不用说审查前抓问题

示例

// .eslintrc.json——强风格和抓 bug
{
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  "rules": {
    "no-unused-vars": "error",
    "no-implicit-coercion": "error",
    "eqeqeq": "error", // 无 ==、用 ===
    "no-var": "error", // 用 let/const
    "prefer-const": "error"
  }
}

// .prettierrc——消格式讨论
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 80
}

// tsconfig.json——严格类型检查
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}

// package.json——覆盖阈值
{
  "scripts": {
    "test": "jest --coverage --coverageThreshold='{"global":{"lines":80}}'"
  }
}

// .husky/pre-commit——提交前跑检查
#!/bin/sh
npx lint-staged
// lint-staged 配置:
{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write", "tsc --noEmit"]
  }
}

// .github/workflows/ci.yml——CI 强制
name: CI
on: [pull_request]
jobs:
  checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run lint    // eslint
      - run: npm run format:check  // prettier --check
      - run: npm run typecheck  // tsc --noEmit
      - run: npm test  // 带覆盖 jest

// 现审查者可聚焦逻辑非风格:
// 审查者评论: "这函数有竞条件——
//   两请求可更新同记录。考虑用带版本字段的乐观锁。"
// (非: "42 行用了 == 而非 ===。")

常见问题

  • ⚠审查中评论 linter 能抓的风格——"用单引号"是 linter 规则非审查评论,审查者时间浪费于机械检查。
  • ⚠设 linter 但 CI 不强制——linter 本地过但开发者禁(eslint-disable)或不跑,违规发。
  • ⚠要求 100% 测试覆盖——团队写琐碎测试(expect(true).toBe(true))达阈值,覆盖 100% 但测试无价值,指标变游戏。
  • ⚠CI 跑所有检查但本地不跑——开发者推、等 CI 10 分钟、发现 lint 错、修、再推、循环重复 5 次才绿。

最佳实践

  • ✓CI 和预提交钩子自动化所有机械检查(lint、格式、类型检查、覆盖)使审查者永不见——审查时间花逻辑、架构和安全非风格。
  • ✓保存时(编辑器集成)和提交时(预提交钩子)本地跑检查非仅 CI——开发者即时反馈不等 10 分钟 CI 找 lint 错。
  • ✓为新代码设覆盖阈值(新行 80%)而非所有代码 100%——这鼓励测新代码不激旧代码琐碎测试。
  • ✓用严格 TypeScript(strict: true、noImplicitAny、strictNullChecks)——类型检查器抓整类 bug(空解引用、类型困惑)否则审查者须手动查。