本文档介绍我们团队采用的代码质量管理工具(Husky、ESLint、Prettier、commitlint、lint-staged)和版本自动化工具(semantic-release)的原理、配置和使用方法。通过这些工具,我们旨在提升代码一致性、规范提交信息,并自动化版本管理。
工具概览与原理
1. 代码质量管理工具
ESLint
- 作用: 检查 JavaScript/TypeScript 代码中的潜在错误和风格问题。
- 原理: 根据配置文件中的规则,扫描代码并报告问题,支持自动修复。
- 用途: 确保代码质量,避免常见错误。
Prettier
- 作用: 自动格式化代码,保持风格一致。
- 原理: 根据配置文件格式化代码,覆盖 ESLint 的风格规则,避免冲突。
- 用途: 统一团队代码风格,减少手动调整。
Husky
- 作用: 在 Git 钩子(如提交前、提交时)执行自定义脚本。
- 原理 : 在特定 Git 操作(如
git commit
)时触发预定义任务。 - 用途: 集成其他工具,在提交流程中自动检查代码和提交信息。
lint-staged
- 作用: 只对 Git 暂存区文件运行 lint 和格式化。
- 原理: 结合 ESLint 和 Prettier,仅处理即将提交的文件。
- 用途: 提高检查效率,避免扫描整个项目。
commitlint
- 作用: 校验 Git 提交信息是否符合规范。
- 原理: 根据 Conventional Commits 规范,检查提交消息格式。
- 用途: 确保提交信息清晰,为版本管理提供依据。
2. 版本管理工具
semantic-release
- 作用: 根据提交信息自动生成版本号并发布。
- 原理: 分析 Git 提交历史,按 Conventional Commits 规范递增版本(MAJOR.MINOR.PATCH),并更新版本号、生成 CHANGELOG、推送标签。
- 用途: 减少手动版本管理,自动化发布流程。
配置步骤
以下是完整的配置流程(假设使用 npm 和 Node.js 项目)。
1. 初始化项目
csharp
npm init -y
2. 安装依赖
arduino
npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-prettier husky lint-staged @commitlint/cli @commitlint/config-conventional semantic-release @semantic-release/git @semantic-release/npm
3. 配置 ESLint
创建 .eslintrc.json
:
json
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:prettier/recommended"
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "warn",
"prettier/prettier": "error"
}
}
4. 配置 Prettier
创建 .prettierrc
:
json
{
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"printWidth": 80
}
创建 .prettierignore
:
arduino
node_modules
dist
*.min.js
5. 配置 Husky
初始化 Husky:
csharp
npx husky init
配置 pre-commit
钩子(.husky/pre-commit
):
bash
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
配置 commit-msg
钩子:
sql
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
6. 配置 lint-staged
在 package.json
中添加:
json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
}
7. 配置 commitlint
创建 commitlint.config.js
:
java
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert']],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never']
}
};
8. 配置 semantic-release
创建 .releaserc.json
:
perl
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/git"
]
}
更新 package.json
的 scripts
:
json
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"prepare": "husky",
"release": "semantic-release"
}
}
9. 配置 CI/CD(以 GitHub Actions 为例)
创建 .github/workflows/release.yml
:
yaml
name: Release
on:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
注意 : 需要在 GitHub 项目设置中添加 NPM_TOKEN
(用于发布到 npm)和 GITHUB_TOKEN
(自动生成)。
10. 初始化 Husky
arduino
npm run prepare
使用流程
1. 开发流程
- 编写代码: 在本地修改代码。
- 暂存代码 : 使用
git add .
将更改加入暂存区。 - 提交代码:
-
- 运行
git commit -m "feat: 添加新功能"
。 - pre-commit: Husky 触发 lint-staged,自动运行 ESLint 和 Prettier 修复暂存文件。
- commit-msg: Husky 触发 commitlint,检查提交信息是否符合规范。
- 如果校验失败,提交被阻止,需修正后重新提交。
- 运行
2. 版本管理流程
- 推送代码 : 将代码推送到
main
分支(git push origin main
)。 - 自动发布:
-
- CI/CD 触发
semantic-release
。 - 根据提交信息更新版本号(如
feat
→ MINOR)。 - 生成 CHANGELOG,创建 Git 标签,推送更新。
- 可选:发布到 npm。
- CI/CD 触发
3. 提交信息规范
使用 Conventional Commits 格式:
Conventional Commits 的 type 类型
type 是提交信息的核心部分,用于描述提交的性质。以下是常见的 type 类型(基于 commitlint/config-conventional 的默认配置):
- feat: 新增功能(feature)。
-
- 示例:feat: 添加用户登录功能
- 影响版本:递增 MINOR(如 1.0.0 → 1.1.0)。
- fix: 修复 bug。
-
- 示例:fix: 修复表单验证错误
- 影响版本:递增 PATCH(如 1.0.0 → 1.0.1)。
- docs: 文档变更。
-
- 示例:docs: 更新 README 文件
- 影响版本:通常不影响版本号。
- style: 代码风格调整(不影响功能,例如格式化、空格)。
-
- 示例:style: 调整 CSS 缩进
- 影响版本:通常不影响版本号。
- refactor: 代码重构(不新增功能、不修复 bug)。
-
- 示例:refactor: 重构用户认证逻辑
- 影响版本:通常不影响版本号。
- test: 添加或修改测试代码。
-
- 示例:test: 添加登录功能单元测试
- 影响版本:通常不影响版本号。
- chore: 杂项工作(如更新依赖、配置调整)。
-
- 示例:chore: 更新 npm 依赖版本
- 影响版本:通常不影响版本号。
- revert: 回滚之前的提交。
-
- 示例:revert: 回滚 feat: 添加用户登录功能
- 影响版本:根据回滚内容决定。
- 示例:
makefile
feat(user): 添加登录功能
fix: 修复表单验证错误
提交规范结构 Conventional Commits 的提交信息遵循以下格式:
1. 基本组成部分
- : 提交类型(如 feat、fix)。
- (可选): 变更范围(如模块名、文件路径),用括号包裹。
- : 简短描述(通常 50 个字符以内),首字母不大写,无句号。
- 分隔符:冒号后加一个空格(: )。
2. 可选部分
- body(可选): 详细说明,使用空行与 description 分隔。
- footer(可选): 元信息,如关联问题(Fixes #123)或破坏性变更(BREAKING CHANGE:)。
3.破坏性变更新
用 ! 或 BREAKING CHANGE: 表示破坏性变更,会递增 MAJOR 版本。
常见问题与解决方案
- 提交被阻止怎么办?
-
- 检查错误提示,可能是代码问题(运行
npm run lint
和npm run format
修复)或提交信息不符合规范(参考 Conventional Commits)。
- 检查错误提示,可能是代码问题(运行
- 版本没有更新?
-
- 确保提交信息符合规范,且推送到
main
分支。 - 检查 CI/CD 日志,确认
semantic-release
是否正常运行。
- 确保提交信息符合规范,且推送到
- 如何跳过检查?
-
- 临时跳过:
git commit --no-verify
(不推荐)。 - 添加
[skip release]
到提交信息,跳过版本发布。
- 临时跳过:
总结
- 代码质量: ESLint 和 Prettier 确保代码规范,Husky 和 lint-staged 在提交前自动检查。
- 提交信息: commitlint 强制使用 Conventional Commits。
- 版本管理 : semantic-release 自动化版本递增和发布。
通过以上配置,团队可以高效协作,保持代码和版本的一致性。