前言
上一篇引入了CSS框架,接下来配置一下代码提交规范。
8、初始化git
这个很简单,git init即可,会生成一个.git文件
9、husky 配置
安装husky插件
// package.json
"husky": "^8.0.3",
然后添加 husky 脚本
// package.json
"prepare": "husky install"
执行 pnpm run prepare。
执行之后会发现项目根目录多了个.husky的目录及文件。
在该目录下添加 pre-commit、commit-msg和common.sh文件。
注意不要加到_文件夹里。
// .husky/commit-msg
#!/bin/sh
# shellcheck source=./_/husky.sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
// .husky/common.sh
#!/bin/sh
command_exists () {
command -v "$1" >/dev/null 2>&1
}
# Workaround for Windows 10, Git Bash and Pnpm
if command_exists winpty && test -t 1; then
exec < /dev/tty
fi
// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
# Format and submit code according to lintstagedrc.js configuration
npm run lint
npm run lint:lint-staged
安装lint-staged插件。
// package.json
"lint-staged": "^13.2.2",
在.husky文件夹里新建lintstagedrc.cjs文件,用来限定lint范围。
// lintstagedrc.cjs
module.exports = {
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
'!(package)*.json': ['prettier --write--parser json'],
'package.json': ['prettier --write'],
'*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
'*.{vue,css,scss,postcss,less}': ['stylelint --fix', 'prettier --write'],
'*.md': ['prettier --write'],
};
结合之前的文章,添加对应的脚本命令,如果没看过前几篇,一定要去配置一下。
// package.json
"lint:eslint": "eslint --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --fix \"**/*.{vue,css,scss,postcss,less}\" node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint",
这样在使用 git commit 之前,会先执行 .husky/pre-commit 下的脚本,实现提交前的拦截修复。
10、czg交互式commit
安装czg相关插件
// package.json
"@commitlint/cli": "^17.6.1",
"@commitlint/config-conventional": "^17.6.1",
"cz-git": "^1.6.1",
"czg": "^1.6.1",
同时在package.json里添加如下配置,和devDependencies同级。
顺便规范一下node版本。
// package.json
"engines": {
"node": ">=16.9.0",
"npm": ">=7.21.1",
"pnpm": ">=7.0.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-git"
}
}
在 package.json 文件添加脚本。
// package.json
"commit": "git add . && czg",
在根目录加上 commitlint.config.cjs
// commitlint.config.cjs
// @see: https://cz-git.qbenben.com/zh/guide
const fs = require('fs');
const path = require('path');
const scopes = fs
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name.replace(/s$/, ''));
module.exports = {
ignores: [(commit) => commit.includes('init')],
extends: ['@commitlint/config-conventional'],
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
],
],
},
prompt: {
messages: {
// type: "Select the type of change that you're committing:",
// scope: 'Denote the SCOPE of this change (optional):',
// customScope: 'Denote the SCOPE of this change:',
// subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
// body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
// breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
// footerPrefixsSelect: 'Select the ISSUES type of changeList by this change (optional):',
// customFooterPrefixs: 'Input ISSUES prefix:',
// footer: 'List any ISSUES by this change. E.g.: #31, #34:\n',
// confirmCommit: 'Are you sure you want to proceed with the commit above?',
// 中文版
type: '选择你要提交的类型 :',
scope: '选择一个提交范围(可选):',
customScope: '请输入自定义的提交范围 :',
subject: '填写简短精炼的变更描述 :\n',
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixsSelect: '选择关联issue前缀(可选):',
customFooterPrefixs: '输入自定义issue前缀 :',
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
confirmCommit: '是否提交或修改commit ?',
},
types: [
// {
// value: 'feat',
// name: 'feat: 🚀 A new feature',
// emoji: '🚀',
// },
// {
// value: 'fix',
// name: 'fix: 🧩 A bug fix',
// emoji: '🧩',
// },
// {
// value: 'docs',
// name: 'docs: 📚 Documentation only changes',
// emoji: '📚',
// },
// {
// value: 'style',
// name: 'style: 🎨 Changes that do not affect the meaning of the code',
// emoji: '🎨',
// },
// {
// value: 'refactor',
// name: 'refactor: ♻️ A code change that neither fixes a bug nor adds a feature',
// emoji: '♻️',
// },
// {
// value: 'perf',
// name: 'perf: ⚡️ A code change that improves performance',
// emoji: '⚡️',
// },
// {
// value: 'test',
// name: 'test: ✅ Adding missing tests or correcting existing tests',
// emoji: '✅',
// },
// {
// value: 'build',
// name: 'build: 📦️ Changes that affect the build system or external dependencies',
// emoji: '📦️',
// },
// {
// value: 'ci',
// name: 'ci: 🎡 Changes to our CI configuration files and scripts',
// emoji: '🎡',
// },
// {
// value: 'chore',
// name: "chore: 🔨 Other changes that don't modify src or test files",
// emoji: '🔨',
// },
// {
// value: 'revert',
// name: 'revert: ⏪️ Reverts a previous commit',
// emoji: '⏪️',
// },
// {
// value: 'wip',
// name: 'wip: 🕔 work in process',
// emoji: '🕔',
// },
// {
// value: 'workflow',
// name: 'workflow: 📋 workflow improvements',
// emoji: '📋',
// },
// {
// value: 'type',
// name: 'type: 🔰 type definition file changes',
// emoji: '🔰',
// },
// 中文版
{ value: 'feat', name: 'feat: 🚀 新增功能', emoji: '🚀' },
{ value: 'fix', name: 'fix: 🧩 修复缺陷', emoji: '🧩' },
{ value: 'docs', name: 'docs: 📚 文档变更', emoji: '📚' },
{
value: 'style',
name: 'style: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)',
emoji: '🎨',
},
{
value: 'refactor',
name: 'refactor: ♻️ 代码重构(不包括 bug 修复、功能新增)',
emoji: '♻️',
},
{ value: 'perf', name: 'perf: ⚡️ 性能优化', emoji: '⚡️' },
{ value: 'test', name: 'test: ✅ 添加疏漏测试或已有测试改动', emoji: '✅' },
{
value: 'build',
name: 'build: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)',
emoji: '📦️',
},
{ value: 'ci', name: 'ci: 🎡 修改 CI 配置、脚本', emoji: '🎡' },
{ value: 'chore', name: 'chore: ⏪️ 回滚 commit', emoji: '⏪️' },
{
value: 'revert',
name: 'revert: 🔨 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)',
emoji: '🔨',
},
{ value: 'wip', name: 'wip: 🕔 正在开发中', emoji: '🕔' },
{ value: 'workflow', name: 'workflow: 📋 工作流程改进', emoji: '📋' },
{ value: 'types', name: 'types: 🔰 类型定义文件修改', emoji: '🔰' },
],
useEmoji: true,
scopes: [...scopes],
customScopesAlign: 'bottom',
emptyScopesAlias: 'empty',
customScopesAlias: 'custom',
allowBreakingChanges: ['feat', 'fix'],
},
};
执行 pnpm commit 就能看到效果了。
如果出现下面这种情况,执行git config --global core.autocrlf false即可。
正常情况下执行是如下效果。
如果有语法错误就会被拦截。
警告可改可不改,看个人需要。
解决完所有的报错以后,出现这样的提示就表示配置成功,以后都可以按照该规范进行commit,规则后面可以自行修改。
结语
git提交的部分就结束了,接下来会配置自动生成CHANGELOG、release-it、环境变量这些。未完待续…
如果想查看完整代码,可以去我的github仓库:hp-vue-ui,有兴趣可以点个star支持一下。