代码提交规范(基于Conventional Commits)
功能目标:
1.统一提交格式(如feat,fix 等)
2.提交前自动lint 格式化(eslint + prettier)
3.防止提交不规范代码(lint-staged)
4.检验提交信息格式(commitlint)
5.自动钩子执行(husky)
最终效果:
git commit -m 'feat(user): 新增用户信息页面'
格式不规范拒绝提交:
git commit -m 'update stuff' // 会失败
一.安装依赖:
# 安装提交校验相关工具(开发依赖)
pnpm add -D husky lint-staged @commitlint/cli @commitlint/config-conventional
包的功能和作用:
1.husky git hook工具,让你在git的生命周期事件中运行脚本
类别: 工具类
Husky 允许你轻松管理 Git Hooks(如 pre-commit, pre-push, commit-msg 等),并在这些节点执行脚本或工具。
1.安装husky
npm install --save-dev husky
2.初始化husky(创建.husky/目录)
npx husky install
3.添加hook
npx husky add .husky/pre-commit "npx lint-staged"
/**
在husky 文件下添加 pre-commit文件 并且配置上 lint-staged 执行的命令
这个命令可以来源于package 中配置好的pnpm 命令
比如: pre-commit文件 可以存在的命令: pnpm run lint-staged
* /
npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"
也可以npx --no-install commitlint --quiet --edit $1
--no-install 不自动安装依赖包
如果 commitlint 没有安装在 node_modules 中,则命令会立即失败,避免不必要的远程拉包行为。
--quiet
静默模式,只输出错误信息。
--edit $1
指定 Git 传入的提交信息文件(如 .git/COMMIT_EDITMSG),commitlint 会读取该文件并进行格式校验。
$1 是 Git 钩子自动传入的参数,表示提交信息文件的路径。
/**
在husky 文件下添加commit-msg文件 并且配置上 lint-staged 执行的命令
这个命令可以来源于package 中配置好的pnpm 命令
比如: pre-commit文件 可以存在的命令: pnpm run lint-staged
* /
2.lint-staged 代码检查优化工具,只对git暂存区(staged)文件执行 lint/format
类别:代码质量工具
lint-staged 会只对已 git add 的文件执行指定的检查或格式化操作,提高效率(不影响整个代码库),避免不必要的更改。
搭配husky使用,在pre-commit时自动执行检查
在package.json 中配置:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix", // 对于eslint 执行校验
"prettier --write" // 对于prettier 执行的校验
],
"*.json": ["prettier --write"]
}
}
1.git 暂存文件(即你git add 文件)
2.lint-staged 提取文件列表,逐个执行你配置的命令(如eslint --fix)
3.修改后自动git add,不会破坏提交流程
3.@commitlint/cli git提交信息校验工具,校验commit message 格式是否符合约定
类别: 校验工具
@commitlint/cli 是一个用于校验git提交信息是否符合指定格式的命令工具。它配置git的
commit-msg hook 使用,防止不规范的commit message 被提交
列如: 阻止如下格式:
Update stuff
推荐格式(convertional commits):
feat: 添加登录功能
fix: 修复首页闪退功能bug
常见命令:
npx commitlint --edit HEAD
npx commitlint --from=HEAD~1 --to=HEAD
4.@commitlint/config-conventional commitlint 配置,提供符合conventional commits的校验规则
类别: 配置插件
这是commitlint 提供的一个规则预设,包含了符合conventional commits 规范校验规则(类似于ESLint 的
eslint-config-standard)。
conventional commits 是一套提交信息的标准,定义了提交类型(如feat, fix, docs, chore, refator)与格式
提交规范示列:
feat: 增加注册接口
fix: 修复 token 失效问题
docs: 更新接口文档
chore: 升级依赖
结合cli配置:
创建 commitlint.config.js:
module.exports = {
extends: ['@commitlint/config-conventional'],
};
它们是如何协同工作的:
1.你执行 git commit
2.husky 出发pre-commit
3.lint-staged 检查格式化已暂存的文件
4.husky 触发commit-msg
5.commitlint 校验提交信息格式
6.不符合规则拒绝提交
二: 初始化husky
npx husky init
此命令会:
在项目根目录创建 .husky/ 目录
自动添加 prepare 脚本到 package.json
三:配置commitlint
创建commitlint.config.js 文件
module.exports = {
extends: ['@commitlint/config-conventional'],
};
// 或者
// 自定义插件
const customPlugin = require('./commitlint-custom-plugin.js')
const typeList = {
feat: '新功能',
fix: '修复',
docs: '文档变更',
style: '代码格式(不影响代码运行的变动)',
refactor: '重构(既不是增加feature),也不是修复bug',
pref: '性能优化',
test: '增加测试',
chore: '构建过程或辅助工具的变动',
revert: '回退',
build: '打包',
}
module.exports = {
extends: ['@commitlint/config-conventional'],
/**
* rules 字段用于定义校验规则,其格式为:
* 规则的格式为 [level, condition, value]
* 其中 level 可以是 0(关闭)、1(警告)或 2(错误);
* condition 可以是 always 或 never;
* value 是具体的规则值。
*/
rules: {
//确保 type 总是小写。
'type-case': [2, 'always', 'lower-case'],
// type 类型定义,表示 git 提交的 type 必须在以下类型范围内
'type-enum': [2, 'always', [...Object.keys(typeList)]],
// 指定使用插件中的自定义规则
'custom-rule': [2, 'always', { allowedTypes: typeList }],
// subject 大小写不做校验
'subject-case': [0],
},
plugins: [customPlugin],
}
// 自定义插件文件:
新建 commitlint-custom-plugin.js 文件
// 具体配置见下图
四:配置husky钩子
执行以下命令添加 git 提交校验:
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
五: 配置lint-staged(可选但推荐)
在 package.json 中添加:
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
然后添加 pre-commit 钩子:
npx husky add .husky/pre-commit "npx lint-staged"
package 示列(重点)
{
"scripts": {
"lint": "eslint .",
"prepare": "husky install"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"devDependencies": {
"husky": "^9.0.0",
"lint-staged": "^15.0.0",
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0"
}
}
测试一把:
git add .
git commit -m "fix(login): 修复登录接口错误"
# ✅ 提交成功
git commit -m "update bug"
# ❌ 报错:不符合格式
自定义插件配置 新建 commitlint-custom-plugin.js 文件
// commitlint-custom-plugin.js
const colors = require('colors');
/**
* @description 校验类型是否符合定义
* @param {*} parsed 提交信息集合
* @param {*} allowedTypes 定义类型集合
* @returns 返回类型及是否类型正确
*/
const validType = (value, allowedTypes, isType) => {
return Object.keys(allowedTypes)?.find(item => item === value);
};
// 类型校验失败后,校验头信息
const validHeader = (parsed, allowedTypes, type = '') => {
// 判断type是否符合规则
const typeRegex = Object.keys(allowedTypes).join('|');
const regexString = `^(${typeRegex})(:|:).+`;
const regex = new RegExp(regexString);
const match = parsed.header.match(regex);
if (match) {
errorSubject(parsed, match[1]);
} else {
errorType(parsed, allowedTypes);
}
};
// 类型错误时,提示
const errorType = (parsed, allowedTypes) => {
console.error(
`
` +
'ERROR: 请规范填写type=>'.bgRed +
`
` +
Object.entries(allowedTypes)
.map(item => `${item[0]}:${item[1]}\n`.white)
.join('') +
`
input: ${parsed.raw}
`.green,
);
};
// 主体信息错误,提示
const errorSubject = (parsed, type) => {
console.error(
`
` +
'ERROR: 请确认'.bgRed +
`${type.bgYellow}` +
'类型后有'.bgRed +
':+空格'.bgYellow +
'并添加内容主体信息'.bgRed +
`
input: ${parsed.raw}
`.green,
);
};
module.exports = {
rules: {
'custom-rule': (parsed, when, value) => {
const {allowedTypes} = value;
const type = validType(parsed.type, allowedTypes, 'type');
// 类型存在
if (type) {
if (!parsed.subject) {
errorSubject(parsed, type);
}
} else {
validHeader(parsed, allowedTypes, type);
}
return [2, 'always'];
},
},
};