Skip to content
返回质量保障

构建门控

确保代码在 CI 中编译构建后才能合并、抓本地环境漏的集成错。

为什么

"我机器上工作"是软件工程最著名短语有因——开发者本地环境有特定 Node 版本、特定 OS、不在仓的环境变量和月前装的依赖。CI 有干净环境、.nvmrc 的确切 Node 版本、package-lock.json 的确切依赖、无本地状态。构建门控在这干净环境跑构建抓本地环境漏的集成错: 因旧缓存本地工作的导入、在 devDependencies 但生产用的依赖、本地设但 CI 未设的环境变量。构建门控是代码真编译集成的第一证——无它团队在生产(或发管道太晚)发现构建失败。3 分钟每 PR 跑的构建门控是防"我机器上工作" bug 最便宜保险。

何时使用

每 PR、合前——构建门控是代码编译集成的最低证。

如何做

1. 干净 CI 环境跑构建
   - 用 .nvmrc/.python-version 的确切 Node/Python/Java 版本
   - 从锁文件装依赖(npm ci、pip install -r requirements.txt)
   - 不用开发者机器缓存的 node_modules
   - 这抓"我机器上工作" bug

2. 构建生产产物非仅开发构建
   - npm run build(生产构建非开发服务器)
   - 这抓仅生产问题(摇树优化、环境变量)
   - 开发构建工作但生产构建失败是 bug

3. 多平台构建(若部署到多)
   - 矩阵构建: [ubuntu-latest、windows-latest、macos-latest]
   - 这抓平台特定问题(路径分隔符、原生模块)
   - 若仅部署 Linux 则仅 Linux 构建

4. 缓存构建依赖(但不缓存构建输出)
   - 缓存 node_modules(加速 npm ci)
   - 不缓存 dist/(构建须新鲜跑抓错)
   - 缓存 .next/cache 或 target/(增量构建产物)

5. 构建错快失败
   - 构建门控应首次错立即失败
   - 不在坏构建上继续跑测试
   - 错误消息应清: 哪文件、哪行、什么错

6. 要求构建门控合前过
   - 分支保护: 要求构建作业过
   - 构建失败不允许合
   - 这防坏构建到 main

示例

# .github/workflows/ci.yml — 构建门控
name: CI
on: [pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20]  # 测多 Node 版本
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: npm  # 缓存 node_modules
      - run: npm ci  # 从锁文件装(非 npm install)
      - run: npm run build  # 生产构建
      - run: npm run typecheck  # tsc --noEmit

# .nvmrc — 固定 Node 版本
20

# package.json — 构建脚本
{
  "scripts": {
    "build": "next build",  // 生产构建
    "typecheck": "tsc --noEmit",
    "dev": "next dev"  // 开发服务器(CI 不用)
  }
}

# 门控抓的常见构建错:
# 1. 导入错: 本地工作(旧缓存)但 CI 失败
#    错: 找不到模块 './utils' 或其对应类型声明
#    修: 导入路径错或文件未提交

# 2. 类型错: 本地工作(未跑 tsc)但 CI 失败
#    错: 类型 'User' 上不存在属性 'name'
#    修: 类型错或属性可选

# 3. 环境变量错: 本地工作(.env 设)但 CI 失败
#    错: 缺环境变量: DATABASE_URL
#    修: 加环境变量到 CI 工作流或仓密

# 4. 依赖错: 本地工作(node_modules)但 CI 失败
#    错: 找不到包 'lodash'
#    修: 依赖不在 package.json 或在 devDependencies
#         但生产代码用

# 分支保护: 要求构建门控
# 设置 > 分支 > 分支保护规则:
# - 要求状态检查过: build
# - 合前要求分支最新

常见问题

  • ⚠CI 中用 npm install 非 npm ci——npm install 更新锁文件装与开发者不同版本、CI 构建过但生产失败(或反)因依赖不同。
  • ⚠缓存构建输出(dist/)非仅依赖——构建因输出缓存跳、新鲜构建会抓的构建错漏、坏代码合。
  • ⚠应用部署多平台但仅一平台构建——Linux 构建过但 Windows 因路径分隔符失败、团队生产发现。
  • ⚠CI 仅跑开发构建非生产构建——开发构建跳摇树优化、环境变量验证和压缩、生产构建失败于开发构建未抓的问题。

最佳实践

  • ✓干净 CI 环境用 npm ci(非 npm install)跑生产构建(npm run build)——这抓本地环境漏的"我机器上工作" bug。
  • ✓缓存依赖(node_modules)不缓存构建输出(dist/)——构建须新鲜跑抓错但依赖装可缓存加速。
  • ✓若部署多平台在所有目标平台(Linux、Windows、macOS)构建——这抓路径分隔符和原生模块兼容性等平台特定问题。
  • ✓分支保护要求构建门控合前过不允许绕——main 上坏构建阻整个团队、修比 PR 中抓贵 10 倍。