Git 規(guī)范
組件庫是一個多人協(xié)作的項目,Git 的提交說明精準,在后期協(xié)作以及 Bug 處理時會變得有據(jù)可查,項目的開發(fā)可以根據(jù)規(guī)范的提交說明快速生成開發(fā)日志,從而方便開發(fā)者或用戶追蹤項目的開發(fā)信息和功能特性。提交規(guī)范使用的是 Angular 團隊規(guī)范
commit message 提交符合 Angular 團隊規(guī)范,需要在 comit 之前做校驗,husky 工具可以定義攔截 git 鉤子,對提交的文件和信息做校驗和自動修復
husky
項目的 husky 版本是 ^7.0.4
husky 安裝到開發(fā)依賴中
yarn add husky -D
安裝完后,我們需要在當前項目中創(chuàng)建一個.husky 目錄,并指定該目錄為 git hooks 所在的目錄。
使用以下命令快速創(chuàng)建 ??
npx --no-install husky install
--no-install 參數(shù)表示強制 npx 使用項目中 node_modules 目錄下的husky依賴包
使用以下命令快速創(chuàng)建 pre-commit ??
npx --no-instal husky add .husky/pre-commit "npm run lint"
pre-commit 在 commit 之前會執(zhí)行 npm run lint 校驗代碼,可以定義你的執(zhí)行腳本,校驗不通過不允許 commit 提交
commitizen
commitizen 是一個撰寫符合 Commit Message 標準的一款工具。通過它可以實現(xiàn)交互式撰寫規(guī)范的 Commit Message。
項目安裝 commitizen
yarn add commitizen -D
安裝完成后,一般我們都采用符合 Angular 的 Commit message 格式的提交規(guī)范,運行以下命令生成符合 Angular 提交規(guī)范格式的 Commit message
npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact
運行了上述命令后,它將為你項目安裝 cz-conventional-changelog 適配器模塊,把 config.commitizen 的密鑰添加到文件的根目錄添加到 package.json 中
可以在 package.json 中看到,自動的新增了以下內(nèi)容 ??
{
...
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
...
}
在 package.json scrips 添加 "commit": "git-cz" 命令
scripts: {
"commit": "git-cz"
}
運行 yarn commit 可以通過以下交互式的撰寫 commit messag 然后提交

限制 commitlint
由于 commitizen 并不是強制使用的,仍然可以通過 git commit 來提交,所以不管是 git-cz 還是 git commit 提交前,都要對 commit messag 進行一次校驗,不符合規(guī)范的情況下是不允許進行 commit
首先我們需要安裝 commitlint, commitlint/config-conventional
yarn add @commitlint/cli @commitlint/config-conventional -D
使用以下命令快速創(chuàng)建 git hooks 的 commit-msg 鉤子 ??
這樣每次 commit 的時候都會由 commitlint 對 commit message 進行一次檢驗
npx --no-instal husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
然后在項目根目錄創(chuàng)建一個 commitlint 配置文件 commitlint.config.js,可以對這個文件進行配置
module.exports = {
ignores: [(commit) => commit.includes('init')],
extends: ['@commitlint/config-conventional', 'cz'],
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'],
'subject-case': [0],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release'
]
]
}
}
上面的提示都是英文的,如果想自定義翻譯成中文,需要安裝 cz-customizable 來實現(xiàn)自定義 commit message 規(guī)則,以及安裝對應的 commitlint-config-cz 來配套校驗
yarn add commitlint-config-cz -D
在項目根目錄,創(chuàng)建一個 .cz-config.js 文件,并復制 cz-config-EXAMPLE.js 中的內(nèi)容到其中。然后改成自己想要的規(guī)則即可。
// .cz-config.js
module.exports = {
types: [
{ value: ':sparkles: feat', name: '? feat: 一項新功能' },
{ value: ':bug: fix', name: '?? fix: 修復一個Bug' },
{ value: ':memo: docs', name: '?? docs: 文檔變更' },
{ value: ':lipstick: style', name: '?? style: 代碼風格,格式修復' },
{ value: ':recycle: refactor', name: '?? refactor: 代碼重構,注意和feat、fix區(qū)分開' },
{ value: ':zap: perf', name: '?? perf: 代碼優(yōu)化,改善性能' },
{ value: ':white_check_mark: test', name: '? test: 測試' },
{ value: ':rocket: chore', name: '?? chore: 變更構建流程或輔助工具' },
{ value: ':rewind: revert', name: ':rewind: revert: 代碼回退' },
{ value: ':tada: init', name: '?? init: 項目初始化' },
{ value: ':construction_worker: ci', name: '?? 對CI配置文件和腳本的更改' },
{ value: ':package: build', name: '??? build: 變更項目構建或外部依賴' },
{ value: ':construction: WIP', name: '?? WIP: 進行中的工作' }
],
scopes: [
{ name: 'component' },
{ name: 'config' },
{ name: 'docs' },
{ name: 'src' },
{ name: 'examples' },
{ name: 'play' }
],
// allowTicketNumber: false,
// isTicketNumberRequired: false,
// ticketNumberPrefix: 'TICKET-',
// ticketNumberRegExp: '\\d{1,5}',
// it needs to match the value for field type. Eg.: 'fix'
// scopeOverrides: {
// feat: [
// { name: 'element' }
// ],
// fix: [
// { name: 'element' },
// { name: 'style' },
// ]
// },
// override the messages, defaults are as follows
messages: {
type: '請選擇提交類型(必填):',
scope: '請選擇一個scope (可選):',
customScope: '請輸入文件修改范圍(可選):',
// used if allowCustomScopes is true
subject: '請簡要描述提交(必填):',
body: '請輸入詳細描述,使用"|"換行(可選):\n',
breaking: '列出任務非兼容性說明 (可選):\n',
footer: '請輸入要關閉的issue,例如:#12, #34(可選):\n',
confirmCommit: '確定提交此說明嗎?'
},
allowCustomScopes: true,
allowBreakingChanges: ['feat', 'fix'],
// 限制 subject 長度
subjectLimit: 72
// 跳過問題 skip any questions you want
// skipQuestions: ['body', 'footer'],
// breaklineChar: '|', // It is supported for fields body and footer.
// footerPrefix : 'ISSUES CLOSED:'
// askForBreakingChangeFirst : true, // default is false
}
創(chuàng)建完 .cz-config.js 文件后,我們需要回到 package.json 文件中,將 config.commitizen.path 更改為 node_modules/cz-customizable
...
{
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}
}
...
關于 commitlint-config-cz 更高級的用法可以查看 ?? commitlint-config-cz
為了提交更好看,在 commit 頭部添加了表情 gitmoji,需要安裝這個插件 commitlint-config-gitmoji
yarn add commitlint-config-gitmoji -D
修改 .commitlintrc.js 內(nèi)容
// .commitlintrc.js
module.exports = {
// extends: ['@commitlint/config-conventional', 'cz'],
extends: ['gitmoji']
}
執(zhí)行 yarn commit 可以看到帶表情的中文 commit message

提交 github 顯示效果

comitmit 規(guī)范介紹
<type
>(<scope
>):
<subject>
<BLANK LINE>
<body>
<BLANK LINE> <footer></footer></BLANK></body></BLANK></subject></scope
></type>
介紹一下內(nèi)容規(guī)范,大致分為三個部分(使用空行分割):
- 標題行: 必填, 描述主要修改類型和內(nèi)容
- 主題內(nèi)容: 描述為什么修改, 做了什么樣的修改, 以及開發(fā)的思路等等
- 頁腳注釋: 可以寫注釋,BUG 號鏈接
- type: commit 的類型
- feat: 新功能、新特性
- fix: 修改 bug
- perf: 更改代碼,以提高性能
- refactor: 代碼重構(重構,在不影響代碼內(nèi)部行為、功能下的代碼修改)
- docs: 文檔修改
- style: 代碼格式修改, 注意不是 css 修改(例如分號修改)
- test: 測試用例新增、修改
- build: 影響項目構建或依賴項修改
- revert: 恢復上一次提交
- ci: 持續(xù)集成相關文件修改
- chore: 其他修改(不在上述類型中的修改)
- release: 發(fā)布新版本
- workflow: 工作流相關文件修改
- scope: commit 影響的范圍, 比如: route, component, utils, build…
- subject: commit 的概述
- body: commit 具體修改內(nèi)容, 可以分為多行.
- footer: 一些備注, 通常是 BREAKING CHANGE 或修復的 bug 的鏈接.
- scope: commit 影響的范圍, 比如: route, component, utils, build…
- subject: commit 的概述
- body: commit 具體修改內(nèi)容, 可以分為多行.
- footer: 一些備注, 通常是 BREAKING CHANGE 或修復的 bug 的鏈接.
例如
- fix(修復 BUG)
如果修復的這個 BUG 只影響當前修改的文件,可不加范圍。如果影響的范圍比較大,要加上范圍描述。
例如這次 BUG 修復影響到全局,可以加個 global。如果影響的是某個目錄或某個功能,可以加上該目錄的路徑,或者對應的功能名稱。
// 示例1
fix(global):修復checkbox不能復選的問題
// 示例2 下面圓括號里的 common 為通用管理的名稱
fix(common): 修復字體過小的BUG,將通用管理下所有頁面的默認字體大小修改為 14px
// 示例3
fix: value.length -> values.length
- feat(添加新功能或新頁面)
feat: 添加button組件
這是一個示例,假設對組件功能進行了一些描述。
這里是備注,可以是放BUG鏈接或者一些重要性的東西。
- chore(其他修改)
chore 的中文翻譯為日常事務、例行工作,顧名思義,即不在其他 commit 類型中的修改,都可以用 chore 表示。
其他類型的 commit 和上面三個示例差不多,就不說了。
lint-staged
lint-staged 相當于一個文件過濾器,每次提交時只檢查本次提交的暫存區(qū)的文件,它不能格式化代碼和校驗文件,需要自己配置一下,如:.eslintrc、.stylelintrc 等,然后在 package.json 中引入。
"lint-staged": {
"*.js": ["eslint --fix", "git add"]
}
當文件變化,執(zhí)行 git commit,pre-commit 鉤子會啟動,執(zhí)行 lint-staged 命令,我們對于 lint-staged 如上文配置,對本次被 commited 中的所有 .js 文件,執(zhí)行 eslint --fix 和 git add 命令,前者的的目的是格式化,后者是對格式化之后的代碼重新提交。
使用步驟
- 安裝使用
yarn add -D lint-staged
- 添加腳本命令
// package.json
"scripts": {
"lint:lint-staged": "lint-staged -c ./.husky/lint-staged.config.js"
}
- 在 pre-commit 的鉤子上添加 lint-staged 命令
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
npm run lint:lint-staged
- 添加
lint-staged配置文件
// .husky/lint-staged.config.js
module.exports = {
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
'package.json': ['prettier --write'],
'*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
'*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
'*.md': ['prettier --write']
}
CHANGELOG 自動生成
CHANGELOG 記錄項目所有的 commit 信息并歸類版本,可以快速跳轉(zhuǎn)到該條 commit 記錄,方便知道項目哪個版本做了哪些功能有哪些 bug 等信息。也方便排查 bug,對于提交記錄一目了然,不用一個一個去翻去查
用 standard-version 來實現(xiàn)自動生成 CHANGELOG,conventional-changelog 也可以生產(chǎn) CHANGELOG,不過它推薦用 standard-version (這都是同一個團隊的東西,基于 conventional-changelog 實現(xiàn)的)
安裝
npm i -D standard-version
package.json
{
"scripts": {
"standard-version": "standard-version"
}
}
當 commit type 是 feat 和 fix 的時候執(zhí)行這個命令,它會自增版本號
standard-version 提供自定義配置不同類型對應顯示文案,在根目錄新建 .versionrc.js 文件
module.exports = {
types: [
{ type: 'feat', section: '? Features | 新功能' },
{ type: 'fix', section: '?? Bug Fixes | Bug 修復' },
{ type: 'init', section: '?? Init | 初始化' },
{ type: 'docs', section: '?? Documentation | 文檔' },
{ type: 'style', section: '?? Styles | 風格' },
{ type: 'refactor', section: '?? Code Refactoring | 代碼重構' },
{ type: 'perf', section: '? Performance Improvements | 性能優(yōu)化' },
{ type: 'test', section: '? Tests | 測試' },
{ type: 'revert', section: '? Revert | 回退' },
{ type: 'build', section: '?? Build System | 打包構建' },
{ type: 'chore', section: '?? Chore | 構建/工程依賴/工具' },
{ type: 'ci', section: '?? Continuous Integration | CI 配置' }
]
}
執(zhí)行以下命令,就會根據(jù)你的 commit 信息自動生成 CHANGELOG.md 文件
npm run standard-version
Lint 規(guī)范校驗
ls-lint 校驗文件命名
ls-lint 可以校驗文件命名規(guī)范,例如 kebab-case、PascalCase
安裝使用
yarn add @ls-lint/ls-lint -D
在根項目創(chuàng)建 .ls-lint.yml 文件
ls:
packages/**:
.js: kebab-case
.ts: kebab-case
.d.ts: kebab-case
ignore:
- .git
- node_modules
配置 package.json 腳本命令 "lint:ls-lint": "ls-lint",然后加入 .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
npm run lint:ls-lint
# Format and submit code according to lintstagedrc.js configuration
npm run lint:lint-staged
ESLint 校驗
Eslint 是針對 EScript 的一款代碼檢測工具,它可以檢測項目中編寫不規(guī)范的代碼,如果寫出不符合規(guī)范的代碼會被警告
安裝依賴
-
eslint- Eslint 本體 -
eslint-plugin-vue- 適用于 Vue 文件的 ESLint 插件 -
vue-eslint-parser- 使用eslint-plugin-vue時必須安裝的 eslint 解析器
yarn add eslint eslint-plugin-vue vue-eslint-parser -D
添加 ESLint 配置文件,根目錄創(chuàng)建配置文件 .eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
es6: true,
node: true
},
extends: ['eslint:recommended', 'plugin:vue/recommended'],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
parser: 'babel-eslint'
},
rules: {}
}
.eslintignore 配置不想被 eslint 校驗的文件
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Dockerfile
.husky/lint-staged.config.js 添加腳本命令 eslint --fix
添加 --fix 可以開啟 eslint 的自動修復功能。
如果您使用的編輯起是 vscode ,請安裝 eslint 的插件進行使用喔
有時候編輯器的問題,配置不會立馬生效,需要關閉編輯器重新開啟項目,讓編輯器重新加載配置。
Prettier
Prettier 對 js 或者 css 等代碼進行格式化,可以保證團隊的代碼風格保持一致。
安裝
yarn add -D prettier
根目錄新建 prettier.config.js 文件
module.exports = {
// 單行代碼的最大寬度
printWidth: 120,
// 指定每個縮進級別的空格數(shù)
tabWidth: 2,
// 使用制表符 (tab) 縮進
useTabs: false,
// 在語句末尾打印分號
semi: true,
// 多行時盡可能打印尾隨逗號
trailingComma: 'none',
// 使用單引號而不是雙引號
singleQuote: true,
// 在對象文字中打印括號之間的空格
bracketSpacing: true,
// 將 > 多行 JSX 元素放在最后一行的末尾,而不是單獨放在下一行(不適用于自閉元素)。
jsxBracketSameLine: false,
// auto | lf | crlf | cr
endOfLine: 'lf'
}
在 .husky/lint-staged.config.js 配置命令格式化 prettier --write
.prettierignore 忽略格式化
# 以下文件夾不會被格式化
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
ESLint 配合 Prettier
安裝依賴
-
eslint-config-prettier- 關閉所有與 eslint 沖突的規(guī)則,請注意,該插件只有關閉沖突的規(guī)則的作用 -
eslint-plugin-prettier- 如果您禁用與代碼格式相關的所有其他 ESLint 規(guī)則,并且僅啟用檢測潛在錯誤的規(guī)則,則此插件效果最佳。換句話說,就是你想單獨配置某一項時,使用這個插件。值得一提的是,這個插件附帶了一個 plugin:prettier/recommended 配置,可以和 eslint-config-prettier 一次性設置插件。該配置最主要的就是解決回調(diào)函數(shù)的格式化問題
yarn add eslint-config-prettier eslint-plugin-prettier -D
- 修改
.eslintrc.js
{
extends: [
'eslint:recommended',
'plugin:vue/recommended',
'plugin:prettier/recommended',
],
}
Stylelint
Stylelint 是一款強大的現(xiàn)代 linter,可幫助您避免錯誤并強制執(zhí)行樣式中的約定,幫助統(tǒng)一團隊中書寫樣式代碼的規(guī)則。
Stylelint 是一個強大、先進的 CSS 代碼檢查器(linter),可以幫助你規(guī)避 CSS 代碼中的錯誤并保持一致的編碼風格。
安裝依賴
-
stylelint- Stylelint 本體 -
stylelint-config-prettier- 關閉 Stylelint 中與 Prettier 中會發(fā)生沖突的規(guī)則。 -
stylelint-config-rational-order- 對 CSS 聲明進行排序 -
stylelint-config-standard- Stylelint 官方推薦規(guī)則 -
stylelint-order使用 stylelint-config-rational-order 時依賴的模塊
安裝
yarn add stylelint stylelint-config-prettier stylelint-config-standard
stylelint-config-rational-order stylelint-order -D
stylelint.config.js 配置文件
module.exports = {
root: true,
plugins: ['stylelint-order'],
extends: ['stylelint-config-standard'],
rules: {
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global']
}
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep']
}
],
'at-rule-no-unknown': [
true,
{
ignoreAtRules: ['function', 'if', 'each', 'include', 'mixin']
}
],
'no-empty-source': null,
'named-grid-areas-no-invalid': null,
'unicode-bom': 'never',
'no-descending-specificity': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
'declaration-block-trailing-semicolon': 'always',
'rule-empty-line-before': [
'always',
{
ignore: ['after-comment', 'first-nested']
}
],
'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }],
'order/order': [
[
'dollar-variables',
'custom-properties',
'at-rules',
'declarations',
{
type: 'at-rule',
name: 'supports'
},
{
type: 'at-rule',
name: 'media'
},
'rules'
],
{ severity: 'warning' }
],
// Specify the alphabetical order of the attributes in the declaration block
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'float',
'width',
'height',
'max-width',
'max-height',
'min-width',
'min-height',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'margin-collapse',
'margin-top-collapse',
'margin-right-collapse',
'margin-bottom-collapse',
'margin-left-collapse',
'overflow',
'overflow-x',
'overflow-y',
'clip',
'clear',
'font',
'font-family',
'font-size',
'font-smoothing',
'osx-font-smoothing',
'font-style',
'font-weight',
'hyphens',
'src',
'line-height',
'letter-spacing',
'word-spacing',
'color',
'text-align',
'text-decoration',
'text-indent',
'text-overflow',
'text-rendering',
'text-size-adjust',
'text-shadow',
'text-transform',
'word-break',
'word-wrap',
'white-space',
'vertical-align',
'list-style',
'list-style-type',
'list-style-position',
'list-style-image',
'pointer-events',
'cursor',
'background',
'background-attachment',
'background-color',
'background-image',
'background-position',
'background-repeat',
'background-size',
'border',
'border-collapse',
'border-top',
'border-right',
'border-bottom',
'border-left',
'border-color',
'border-image',
'border-top-color',
'border-right-color',
'border-bottom-color',
'border-left-color',
'border-spacing',
'border-style',
'border-top-style',
'border-right-style',
'border-bottom-style',
'border-left-style',
'border-width',
'border-top-width',
'border-right-width',
'border-bottom-width',
'border-left-width',
'border-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'border-bottom-left-radius',
'border-top-left-radius',
'border-radius-topright',
'border-radius-bottomright',
'border-radius-bottomleft',
'border-radius-topleft',
'content',
'quotes',
'outline',
'outline-offset',
'opacity',
'filter',
'visibility',
'size',
'zoom',
'transform',
'box-align',
'box-flex',
'box-orient',
'box-pack',
'box-shadow',
'box-sizing',
'table-layout',
'animation',
'animation-delay',
'animation-duration',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',
'animation-fill-mode',
'transition',
'transition-delay',
'transition-duration',
'transition-property',
'transition-timing-function',
'background-clip',
'backface-visibility',
'resize',
'appearance',
'user-select',
'interpolation-mode',
'direction',
'marks',
'page',
'set-link-source',
'unicode-bidi',
'speak'
]
},
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts']
}
.stylelintignore 忽略校驗目錄文件
/dist/*
/public/*
public/*
在 .husky/lint-staged.config.js 增加命令 stylelint --fix
與 Prettier 配合
stylelint 會與 prettier 產(chǎn)生沖突,要做兼容
安裝
yarn add stylelint-config-prettier
stylelint-scss stylelint-config-standard-scss postcss postcss-html postcss-scss -D
- stylelint-config-prettier ---- 基于 prettier 代碼風格的 stylelint 規(guī)則
- stylelint-config-standard-scss ---- 針對 scss 的標準可共享配置。
- postcss ---- 用于 postcss-html 和 postcss-scss 的支持
- postcss-html ---- 解析
<style>類vue、html文件標簽中的樣式 - postcss-scss ---- 解析
<style lang=“scss”>下的scss樣式
修改 stylelint.config.js
module.exports = {
plugins: ['stylelint-order'],
customSyntax: 'postcss-html',
extends: ['stylelint-config-standard', 'stylelint-config-standard-scss']
}
Lint 配置上可能不完善,在遇到問題后會繼續(xù)完善和補充