Files
novalon-website/docs/plans/2026-03-24-code-quality-tools-integration.md
T
张翔 498bb3a3c8 refactor: reorganize project structure and improve code quality
- Move CI/CD configs to config/ci/ directory
- Reorganize scripts into categorized directories (deployment, monitoring, testing, utils)
- Consolidate documentation into docs/ directory with proper structure
- Update linting and testing configurations
- Remove obsolete test reports and performance summaries
- Add new documentation for code quality tools and contact form security
- Improve project organization and maintainability
- Fix lint-staged config to only lint JS/TS files
- Disable react/react-in-jsx-scope rule for Next.js compatibility
- Ignore scripts and test config directories in ESLint
2026-03-24 13:38:58 +08:00

17 KiB
Raw Blame History

代码质量工具集成实施计划

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: 集成代码质量工具,建立自动化质量门禁,确保代码提交前自动检查

Architecture: 采用Husky管理Git hookslint-staged对暂存文件进行检查,commitlint规范提交信息,Jest生成覆盖率报告

Tech Stack: Husky 8+, lint-staged 15+, commitlint 19+, Jest 29+, @commitlint/config-conventional


前置条件

  • Node.js 18+ 已安装
  • Git 已配置
  • 项目已克隆到本地
  • package.json 已存在

Task 1: 安装依赖包

Files:

  • Modify: package.json

Step 1: 安装Husky、lint-staged和commitlint

npm install --save-dev husky lint-staged @commitlint/cli @commitlint/config-conventional

Step 2: 验证安装

Run: npm list husky lint-staged @commitlint/cli

Expected: 显示已安装的版本号

Step 3: 提交安装

git add package.json package-lock.json
git commit -m "chore: install husky, lint-staged and commitlint"

Task 2: 配置Husky

Files:

  • Create: .husky/pre-commit
  • Create: .husky/commit-msg
  • Modify: package.json

Step 1: 初始化Husky

npx husky install

Step 2: 创建pre-commit钩子

创建文件 .husky/pre-commit:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

Step 3: 创建commit-msg钩子

创建文件 .husky/commit-msg:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit $1

Step 4: 添加prepare脚本到package.json

在package.json的scripts中添加:

"prepare": "husky install"

Step 5: 运行prepare脚本

Run: npm run prepare

Expected: 创建.husky目录并设置Git hooks

Step 6: 提交配置

git add .husky/ package.json
git commit -m "chore: configure husky git hooks"

Task 3: 配置lint-staged

Files:

  • Create: .lintstagedrc.json
  • Modify: package.json

Step 1: 创建lint-staged配置文件

创建文件 .lintstagedrc.json:

{
  "*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "prettier --write"
  ],
  "*.{json,md}": [
    "prettier --write"
  ],
  "*.{css,scss}": [
    "stylelint --fix",
    "prettier --write"
  ]
}

Step 2: 添加lint-staged脚本到package.json

在package.json的scripts中添加:

"lint-staged": "lint-staged"

Step 3: 测试lint-staged

Run: npm run lint-staged

Expected: 对所有暂存文件运行lint和prettier

Step 4: 提交配置

git add .lintstagedrc.json package.json
git commit -m "chore: configure lint-staged"

Task 4: 配置commitlint

Files:

  • Create: commitlint.config.js
  • Create: .commitlintrc.json

Step 1: 创建commitlint配置文件

创建文件 commitlint.config.js:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'chore',
        'revert',
        'build',
        'ci'
      ]
    ],
    'subject-case': [0]
  }
};

Step 2: 创建备用配置文件

创建文件 .commitlintrc.json:

{
  "extends": ["@commitlint/config-conventional"],
  "rules": {
    "type-enum": [
      2,
      "always",
      [
        "feat",
        "fix",
        "docs",
        "style",
        "refactor",
        "perf",
        "test",
        "chore",
        "revert",
        "build",
        "ci"
      ]
    ],
    "subject-case": [0]
  }
}

Step 3: 测试commitlint

Run: echo "feat: add new feature" | npx commitlint

Expected: 通过验证

Run: echo "invalid commit message" | npx commitlint

Expected: 失败并显示错误信息

Step 4: 提交配置

git add commitlint.config.js .commitlintrc.json
git commit -m "chore: configure commitlint"

Task 5: 配置代码覆盖率检查

Files:

  • Modify: jest.config.jsjest.config.ts
  • Modify: package.json

Step 1: 检查现有Jest配置

Run: cat jest.config.jscat jest.config.ts

Expected: 查看现有配置

Step 2: 更新Jest配置添加覆盖率

如果使用jest.config.js:

module.exports = {
  // ... 现有配置
  collectCoverage: true,
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/*.stories.{js,jsx,ts,tsx}',
    '!src/**/__tests__/**',
    '!src/**/*.test.{js,jsx,ts,tsx}',
    '!src/**/*.spec.{js,jsx,ts,tsx}'
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 70,
      lines: 70,
      statements: 70
    }
  },
  coverageReporters: ['json', 'lcov', 'text', 'html']
};

如果使用jest.config.ts:

import type { Config } from 'jest';

const config: Config = {
  // ... 现有配置
  collectCoverage: true,
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/*.stories.{js,jsx,ts,tsx}',
    '!src/**/__tests__/**',
    '!src/**/*.test.{js,jsx,ts,tsx}',
    '!src/**/*.spec.{js,jsx,ts,tsx}'
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 70,
      lines: 70,
      statements: 70
    }
  },
  coverageReporters: ['json', 'lcov', 'text', 'html']
};

export default config;

Step 3: 添加覆盖率脚本到package.json

在package.json的scripts中添加:

"test:coverage": "jest --coverage",
"test:coverage:watch": "jest --coverage --watch",
"coverage:report": "open coverage/lcov-report/index.html"

Step 4: 运行覆盖率测试

Run: npm run test:coverage

Expected: 生成覆盖率报告

Step 5: 提交配置

git add jest.config.js package.json
git commit -m "chore: configure jest coverage"

Task 6: 集成覆盖率检查到pre-commit

Files:

  • Modify: .lintstagedrc.json
  • Create: scripts/check-coverage.sh

Step 1: 创建覆盖率检查脚本

创建文件 scripts/check-coverage.sh:

#!/bin/bash

# 运行测试并生成覆盖率
npm run test:coverage -- --passWithNoTests

# 检查覆盖率是否达到阈值
if [ $? -ne 0 ]; then
  echo "❌ 测试失败,请修复测试后再提交"
  exit 1
fi

echo "✅ 测试通过"

Step 2: 添加执行权限

Run: chmod +x scripts/check-coverage.sh

Step 3: 更新lint-staged配置

修改 .lintstagedrc.json:

{
  "*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "prettier --write"
  ],
  "*.{json,md}": [
    "prettier --write"
  ],
  "*.{css,scss}": [
    "stylelint --fix",
    "prettier --write"
  ],
  "package.json": [
    "bash scripts/check-coverage.sh"
  ]
}

Step 4: 测试覆盖率检查

Run: bash scripts/check-coverage.sh

Expected: 运行测试并检查覆盖率

Step 5: 提交配置

git add .lintstagedrc.json scripts/check-coverage.sh
git commit -m "chore: integrate coverage check to pre-commit"

Task 7: 创建质量门禁文档

Files:

  • Create: docs/development/quality-gates.md

Step 1: 创建质量门禁文档

创建文件 docs/development/quality-gates.md:

# 代码质量门禁

## 概述

项目配置了自动化质量门禁,确保代码提交前通过所有质量检查。

## 质量检查

### 1. 代码风格检查

**工具**: ESLint + Prettier

**检查时机**: pre-commit hook

**检查内容**:
- 代码语法错误
- 代码风格规范
- 代码格式化

**通过标准**: 无错误,无警告

### 2. 提交信息规范

**工具**: commitlint

**检查时机**: commit-msg hook

**检查内容**:
- 提交信息格式
- 提交类型合法性

**通过标准**: 符合Conventional Commits规范

**提交类型**:
- `feat`: 新功能
- `fix`: 修复bug
- `docs`: 文档更新
- `style`: 代码格式调整
- `refactor`: 重构
- `perf`: 性能优化
- `test`: 测试相关
- `chore`: 构建/工具相关
- `revert`: 回滚提交
- `build`: 构建相关
- `ci`: CI/CD相关

**提交信息格式**:

():

```

示例:

feat(auth): add JWT authentication

Implement JWT-based authentication with:
- Token generation
- Token validation
- Refresh token mechanism

Closes #123

3. 代码覆盖率检查

工具: Jest

检查时机: pre-commit hook(修改package.json时)

检查内容:

  • 单元测试覆盖率
  • 分支覆盖率
  • 函数覆盖率
  • 行覆盖率
  • 语句覆盖率

通过标准:

  • 分支覆盖率: ≥ 70%
  • 函数覆盖率: ≥ 70%
  • 行覆盖率: ≥ 70%
  • 语句覆盖率: ≥ 70%

4. 类型检查

工具: TypeScript

检查时机: pre-commit hook

检查内容:

  • 类型错误
  • 类型推断

通过标准: 无类型错误

如何绕过质量门禁

⚠️ 警告: 仅在紧急情况下绕过质量门禁

绕过pre-commit hook

git commit --no-verify -m "message"

绕过commit-msg hook

git commit --no-verify -m "message"

绕过所有hooks

git commit --no-verify -m "message"

故障排查

ESLint错误

问题: pre-commit hook因ESLint错误失败

解决方案:

  1. 查看错误详情
  2. 修复代码或配置
  3. 运行 npm run lint 检查
  4. 重新提交

Prettier错误

问题: pre-commit hook因Prettier格式化失败

解决方案:

  1. 运行 npm run lint 自动修复
  2. 手动修复无法自动修复的问题
  3. 重新提交

commitlint错误

问题: commit-msg hook因提交信息格式错误失败

解决方案:

  1. 检查提交信息格式
  2. 使用正确的提交类型
  3. 重新提交

覆盖率不达标

问题: 覆盖率检查失败

解决方案:

  1. 查看覆盖率报告
  2. 补充测试用例
  3. 重新提交

持续改进

提高覆盖率阈值

随着项目发展,逐步提高覆盖率阈值:

  • Phase 1: 70% (当前)
  • Phase 2: 75%
  • Phase 3: 80%
  • Phase 4: 85%
  • Phase 5: 90%

添加更多质量检查

未来可以添加:

  • 复杂度检查
  • 重复代码检查
  • 安全漏洞扫描
  • 依赖漏洞检查

参考资料


**Step 2: 提交文档**

```bash
git add docs/development/quality-gates.md
git commit -m "docs: add quality gates documentation"

Task 8: 更新项目文档

Files:

  • Modify: README.md
  • Modify: docs/development/getting-started.md

Step 1: 更新README.md添加质量门禁说明

在README.md的"开发指南"部分添加:

### 代码质量门禁

项目配置了自动化质量门禁,确保代码提交前通过所有质量检查:

- **ESLint**: 代码风格检查
- **Prettier**: 代码格式化
- **commitlint**: 提交信息规范
- **Jest**: 代码覆盖率检查

详细信息请查看 [质量门禁文档](docs/development/quality-gates.md)。

Step 2: 更新快速开始指南

docs/development/getting-started.md 添加:

## 代码质量门禁

项目配置了自动化质量门禁,确保代码提交前通过所有质量检查。

### 质量检查

- **代码风格检查**: ESLint + Prettier
- **提交信息规范**: commitlint
- **代码覆盖率检查**: Jest

### 提交规范

使用Conventional Commits规范:

():

```

提交类型:

  • feat: 新功能
  • fix: 修复bug
  • docs: 文档更新
  • style: 代码格式调整
  • refactor: 重构
  • perf: 性能优化
  • test: 测试相关
  • chore: 构建/工具相关

详细信息请查看 质量门禁文档


**Step 3: 提交文档更新**

```bash
git add README.md docs/development/getting-started.md
git commit -m "docs: update documentation for quality gates"

Task 9: 验证质量门禁

Files:

  • Test: 创建测试文件验证所有hooks

Step 1: 测试pre-commit hook

创建测试文件:

echo "console.log('test');" > test-precommit.js
git add test-precommit.js
git commit -m "test: pre-commit hook"

Expected: pre-commit hook运行lint-staged,格式化代码

Step 2: 测试commit-msg hook

git commit --amend -m "invalid commit message"

Expected: commit-msg hook拒绝提交

git commit --amend -m "test: verify commit-msg hook"

Expected: commit-msg hook通过

Step 3: 测试覆盖率检查

修改package.json触发覆盖率检查:

echo "// modified" >> package.json
git add package.json
git commit -m "test: coverage check"

Expected: 运行测试并检查覆盖率

Step 4: 清理测试文件

rm test-precommit.js
git add -A
git commit -m "chore: remove test files"

Step 5: 提交验证结果

git log --oneline -5

Expected: 显示所有提交都通过了质量门禁


Task 10: 创建CI/CD集成文档

Files:

  • Create: docs/deployment/quality-gates-ci.md

Step 1: 创建CI/CD集成文档

创建文件 docs/deployment/quality-gates-ci.md:

# CI/CD中的质量门禁

## 概述

质量门禁不仅在本地的Git hooks中运行,也在CI/CD流水线中执行,确保所有合并到主分支的代码都符合质量标准。

## Woodpecker CI配置

### 质量检查步骤
`.woodpecker.yml` 中添加质量检查步骤:

```yaml
pipeline:
  quality-check:
    image: node:18-alpine
    environment:
      NODE_ENV: test
    commands:
      - npm ci
      - npm run lint
      - npm run type-check
      - npm run test:coverage
    when:
      event:
        - push
        - pull_request

  coverage-report:
    image: node:18-alpine
    environment:
      NODE_ENV: test
    commands:
      - npm ci
      - npm run test:coverage
      # 上传覆盖率报告到Codecov或其他服务
    secrets: [codecov_token]
    when:
      event:
        - pull_request

质量门禁规则

CI/CD中的质量门禁规则:

  1. 代码检查: ESLint必须通过,无错误
  2. 类型检查: TypeScript编译必须成功
  3. 测试通过: 所有测试必须通过
  4. 覆盖率达标: 代码覆盖率必须≥70%

失败处理

如果质量检查失败:

  1. CI/CD流水线失败
  2. 阻止合并到主分支
  3. 发送通知给开发者
  4. 显示详细的错误信息

本地开发 vs CI/CD

本地开发

  • 优点: 快速反馈,立即发现问题
  • 缺点: 可能被绕过(--no-verify

CI/CD

  • 优点: 强制执行,无法绕过
  • 缺点: 反馈延迟,需要等待CI运行

最佳实践

  1. 本地优先: 在本地运行质量检查,确保通过后再推送
  2. CI兜底: CI/CD作为最后一道防线,确保质量
  3. 快速反馈: CI/CD配置为快速失败,尽早发现问题

持续改进

监控质量指标

定期监控以下指标:

  • 代码覆盖率趋势
  • ESLint错误数量
  • TypeScript错误数量
  • 测试失败率
  • CI/CD通过率

优化质量门禁

根据监控数据优化质量门禁:

  1. 调整覆盖率阈值
  2. 添加新的质量检查
  3. 优化检查性能
  4. 改进错误提示

参考资料


**Step 2: 提交文档**

```bash
git add docs/deployment/quality-gates-ci.md
git commit -m "docs: add CI/CD quality gates documentation"

验收标准

功能完整性

  • Husky Git hooks正常工作
  • lint-staged对暂存文件进行检查
  • commitlint验证提交信息
  • Jest生成覆盖率报告
  • 覆盖率检查集成到pre-commit

代码质量

  • 所有质量检查通过
  • 覆盖率达到70%以上
  • 提交信息符合规范
  • 代码风格一致

文档完整性

  • 质量门禁文档完整
  • CI/CD集成文档完整
  • 使用指南清晰
  • 故障排查指南完整

可维护性

  • 配置文件清晰易懂
  • 脚本可维护
  • 文档更新及时
  • 团队培训完成

后续优化

  1. 提高覆盖率阈值: 逐步提高到80%、85%、90%
  2. 添加更多检查: 复杂度检查、重复代码检查、安全扫描
  3. 集成更多工具: SonarQube、CodeClimate等
  4. 自动化更多流程: 自动生成CHANGELOG、自动发布等
  5. 性能优化: 优化质量检查性能,减少等待时间

参考资料