现阶段咱们团队的项目没有严格统一的方案,为了提升效率、规范项目,急需对开发以及提交制定好规范,特有此文。css
社区中的commit message规范众多,咱们团队选择 Angular 规范 ,由于该规范配套工具齐全,且使用最为普遍。html
其规范大体以下:vue
每次提交,message都应该包含三个部分:Header、Body、Footer。格式以下:java
Item | Value |
---|---|
type(scope): subject | # Header 必填,其中 type 和 subject 必填。 |
空一行 | |
72-character wrapped. | # Body 选填。对本次commit的详情描述,能够多行 |
空一行 | |
BREAKING CHANGE: msg. | # Footer 选填。主要用于版本回滚或绑定issue |
这样写的commit相似于文档或者注释,固然若是在查看log不想所有行展现时,执行git log --oneline便可只展现一行node
在Angular
规范的基础上,咱们项目须要在message
前添加JIRA编号,如“AA-0000 #comment (something)
”, 因此咱们最终的规范是基于Augular
的规范而实现的自定义react
有了规范总不能次次手敲,能借助工具仍是要借助工具git
commitizen
是一个格式化commit message的工具github
cz-customizable
vue-cli
@undefined0_0/cz-customizable
shell
cz-customizable
的以即可以在咱们项目组中使用的工具安装
# commitizen工具建议全局安装
npm i -g commitizen
# 项目级安装
npm i -D @undefined0_0/cz-customizable
复制代码
// package.json
"config": {
"commitizen": {
"path": "./node_modules/@undefined0_0/cz-customizable"
}
},
复制代码
而后在项目根目录下新建.cz-config.js
文件,按照官方给的实例文件 cz-config-EXAMPLE.js 以下所示:
进行定制化修改,如去掉不使用的value,定制scope,或者汉化等等
// .cz-config.js
module.exports = {
jiraMode: true, // 是否开启 JIRA 校验,默认为false
jiraPrefix: '', // JIRA 项目编号,会添加在需求号前,`${jiraPrefix}-0000 #comment (something)`
types: [
{ value: 'feat', name: 'feat: A new feature' },
{ value: 'fix', name: 'fix: A bug fix' },
{ value: 'docs', name: 'docs: Documentation only changes' },
{
value: 'style',
name:
'style: Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)',
},
{
value: 'refactor',
name: 'refactor: A code change that neither fixes a bug nor adds a feature',
},
{
value: 'perf',
name: 'perf: A code change that improves performance',
},
{ value: 'test', name: 'test: Adding missing tests' },
{
value: 'chore',
name:
'chore: Changes to the build process or auxiliary tools\n and libraries such as documentation generation',
},
{ value: 'revert', name: 'revert: Revert to a commit' },
{ value: 'WIP', name: 'WIP: Work in progress' },
],
scopes: [{ name: 'accounts' }, { name: 'admin' }, { name: 'exampleScope' }, { name: 'changeMe' }],
allowTicketNumber: false,
isTicketNumberRequired: false,
ticketNumberPrefix: 'TICKET-',
ticketNumberRegExp: '\\d{1,5}',
// it needs to match the value for field type. Eg.: 'fix'
/* scopeOverrides: { fix: [ {name: 'merge'}, {name: 'style'}, {name: 'e2eTest'}, {name: 'unitTest'} ] }, */
// override the messages, defaults are as follows
messages: {
type: "Select the type of change that you're committing:",
scope: '\nDenote the SCOPE of this change (optional):',
// used if allowCustomScopes is true
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):\n',
footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
confirmCommit: 'Are you sure you want to proceed with the commit above?',
},
allowCustomScopes: true,
allowBreakingChanges: ['feat', 'fix'],
// skip any questions you want
skipQuestions: ['body'],
// limit subject length
subjectLimit: 100,
// breaklineChar: '|', // It is supported for fields body and footer.
// footerPrefix : 'ISSUES CLOSED:'
// askForBreakingChangeFirst : true, // default is false
};
复制代码
通常来讲,到这一步其实已经够用了,若是愿意规范本身的代码和commit,但若是没有规则仍是会有错误的提交,接下来就继续对commit作校验
@commitlint/config-conventional
commitlint-config-cz
commitlint-with-demand
commitlint
插件commitlint-plugin-with-jira-issue
commitlint
rulenpm i -D @commitlint/config-conventional @commitlint/cli commitlint-config-cz commitlint-with-demand commitlint-plugin-with-jira-issue
复制代码
而后在项目根目录新建lint配置文件.commitlintrc.js
,其实别的格式也能够。
// .commitlintrc.js
module.exports = {
extends: [
// 使用预设的配置
'@commitlint/config-conventional',
'cz'
],
plugins: [
'with-jira-issue'
],
parserPreset: 'commitlint-with-demand',
// 改变预设中的提交类型
// rule由配置项和配置数组组成,数组中第一位为 level 表示规则状态,0为禁用规则,1为警告,2为错误,第二位为应用与否,可选 always|never ,第三位该rule的值
rules: {
'type-enum': [2, 'always', [
// 只有包含以下type的message才被经过
'feat',
'update',
'fix',
// ...
]],
// ...
'with-jira-issue': [2, 'always'],
// ...
// 其他配置再也不赘述,移步官方文档查看
}
};
复制代码
// .demand.js
// Your JIRA number
const JIRA_PROJECT = '';
module.exports = {
JIRA_PROJECT
};
复制代码
commitlint
相关文档
vue3用脚手架搭建项目时会自带lint工具
或者自行安装eslint
# eslint
npm i -D eslint babel-eslint eslint-plugin-vue
复制代码
eslint
babel-eslint
eslint-plugin-vue
// package.json
"scripts": {
"lint": "vue-cli-service lint src/**/*.js" // 不肯自动修复 带上(--no-fix)
// "lint": "eslint src"
}
复制代码
.eslint.js
文件
是eslint校验的规则,使用项目标准便可。extends 是基础配置,rules是自定义的设置
例如
// .eslintrc.js
module.exports = {
// 此项是用来配置标准的js风格
"extends": "standard",
// add your custom rules here
// 下面这些rules是用来设置从插件来的规范代码的规则,使用必须去掉前缀eslint-plugin-
// 主要有以下的设置规则,能够设置字符串也能够设置数字,二者效果一致
// "off" -> 0 关闭规则
// "warn" -> 1 开启警告规则
//"error" -> 2 开启错误规则
"rules": {
"semi": [2, "never"],
"no-console": 0,
"comma-dangle": [2, "always-multiline"],
"max-len": 0,
"react/jsx-first-prop-new-line": 0,
"react/jsx-filename-extension": 0,
"space-before-function-paren": [2, "always"],
"no-unused-expressions": [0, {
"allowShortCircuit": true,
"allowTernary": true
}],
"arrow-body-style": [0, "never"],
"func-names": 0,
"prefer-const": 0,
"no-extend-native": 0,
"no-param-reassign": 0,
"no-restricted-syntax": 0,
"no-eval": 0,
"no-continue": 0,
"react/jsx-no-bind": 0,
"no-unused-vars": [2, { "ignoreRestSiblings": true }],
"no-underscore-dangle": 0,
"global-require": 0,
"import/no-unresolved": 0,
"import/extensions": 0,
"jsx-a11y/href-no-hash": 0,
"react/no-array-index-key": 0,
"react/require-default-props": 0,
"react/forbid-prop-types": 0,
"react/no-string-refs": 0,
"react/no-find-dom-node": 0,
"import/no-extraneous-dependencies": 0,
"import/prefer-default-export": 0,
"react/no-danger": 0,
"jsx-a11y/no-static-element-interactions": 0,
},
//此项是用来指定eslint解析器的,解析器必须符合规则,babel-eslint解析器是对babel解析器的包装使其与ESLint解析
"parser": "babel-eslint",
//此项是用来指定javaScript语言类型和风格,sourceType用来指定js导入的方式,默认是script,此处设置为module,指某块导入方式
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 8,
"ecmaFeatures": {
"jsx": true,
"experimentalObjectRestSpread": true
}
},
"settings": {
"import/resolver": "node"
}
};
复制代码
具体的rules见文档
优势
less
、sass
预处理器;项目中安装stylelint
npm i -D stylelint stylelint-config-standard stylelint-scss stylelint-order stylelint-config-recess-order
复制代码
stylelint-scss
scss
拓展,使stylelint
支持scss
语法stylelint-config-standard
stylelint
代码规则stylelint-order
stylelint-config-recess-order
stylelint-order
的第三方配置配置文件.stylelintrc.js
// .stylelintrc.js
module.exports = {
"extends": [
"stylelint-config-standard" // 标准配置规则
],
'plugins': [
'stylelint-order', // 指定排序,好比声明的块内(插件包)属性的顺序。
'stylelint-scss' // 执行各类各样的 SCSS语法特性检测规则(插件包)
],
"rules": {
// css书写顺序
// ...
// 其余规则
'no-empty-source': null
}
}
复制代码
配置文件.stylelintignore
,指定忽略的文件
*.js
*.jpg
*.woff
测试和打包目录
/test/
/dist/
复制代码
校验
在package.json
中的scripts
添加指令,而后npm run lintcss
便可
// package.json
{
"scripts": {
"lintcss": "stylelint src/**/*.css", // (--fix) 自动修复,不建议使用
}
}
复制代码
yorkie
:在cli安装以后,@vue/cli-service 也会安装 yorkie,它会让你在 package.json 的 gitHooks 字段中方便地指定 Git hook:
npm i -D lint-staged yorkie
复制代码
// package.json
"gitHooks": {
"pre-commit": "lint-staged", // 代码lint检测
"commit-msg": "commitlint -E GIT_PARAMS" // commitlint检测
},
复制代码
commit-msg
lint-staged
对已修改的文件进行校验pre-commit
lint-staged
对修改的文件进行校验新建.lintstagedrc.js
文件
// .lintstagedrc.js
module.exports = {
"*.{js,vue}": [
"eslint"
],
"*.{html,vue,css,wxss,sass,scss}": [
"stylelint"
]
}
复制代码
standard-version
是一款遵循语义化版本(semver)和 commit message 标准规范 的版本和 changelog 自动化工具。
一般咱们在main分支进行发布操做时,须要更新版本号,更新changelog,打tag,而 standard-version
工具会自动完成上述操做
npm i -D standard-version
复制代码
// package.json
"scripts": {
"release": "standard-version"
}
复制代码
主版本号(major):通常改动很大,不兼容低版本 次版本号(minor):兼容同一个大版本的API和用法 修订号(patch):通常用来修复bug 有的时候在修订号后面可能还会有先行版本号,例如1.0.0-alpha.1,1.0.0-beta.4,2.0.0-rc.1等。经常使用的先行版本通常为alpha,beta,rc,stable,csp等。
经常使用的命令以下
-f
第一次Realease
-r
指定版本号
自定义能够经过:
-r minor
执行后版本号则是:v1.1.0
-r 2.0.0
执行后版本号则是:v2.0.0
-p
用来生成预发版本,若是当期的版本号是 1.0.0
-p
执行后版本号则是:1.0.1-0-p alpha
执行后版本号则是:v1.0.1-alpha.0-t
版本 tag 前缀,默认有一个前缀v,若是不想有任何前缀,直接用-t 便可指定前缀。若是当期的版本号是 1.0.0
-t 'V-'
执行后版本号则是:V-2.0.0命令能够结合使用,如-t 'V-' -r 2.1.0
,执行后版本号则是:V-2.1.0
--dry-run
预览功能。不会修改package.json、changelog以及tag
更多命令经过 standard-version --help
查看
建立.versionrc.js
文件
// .versionrc.js
module.exports = {
"header": "# HEAD \n\n", // changelog顶部标题
"types": [ // 影响生成changelog内容的配置
{"type": "feat", "section": "Features"},
{"type": "fix", "section": "Bug Fixes"},
{"type": "chore", "hidden": true},
{"type": "docs", "hidden": true},
{"type": "style", "hidden": true},
{"type": "refactor", "hidden": true},
{"type": "perf", "hidden": true},
{"type": "test", "hidden": true}
],
// ...
}
复制代码
更多配置见Conventional Changelog Configuration Spec (v2.1.0)
standard-version
支持生命周期脚本。咱们能够经过下面这些钩子在发布期间去执行本身的补充命令。钩子按照下面的顺序执行:
prerelease
:首先进入该生命周期。当prerelease
返回一个非零的退出代码,versioning将被停止,但它对进程没有影响。
prebump/postbump
:在版本号变动以前和以后执行。若是prebump
脚本返回版本#,则将使用该版本,而不是standard-version
提供的版本。
prechangelog/postchangelog
:在生成CHANGELOG以前和以后执行。
precommit/postcommit
:在提交步骤以前和以后调用。
pretag/posttag
:在标记tag步骤以前和以后调用。
假如项目中使用JIRA时,issue地址须要使用jira的地址,但standard-version
并不支持自定义issue地址,因此能够这样操做(若是安装了replace
)
// .versionrc.js
"scripts": {
"postchangelog": "replace 'https://github.com/myproject/issues/' 'https://myjira/browse/' CHANGELOG.md"
}
复制代码
或者
// .versionrc.js
"scripts": {
"prebump": "echo 9.9.9"
}
复制代码
执行standard-version会生成v9.9.9的版本。
standard-version
若想跳过某些操做,如生成changelog、打tag等能够在 .versionrc.js
文件中增长配置来实现:
// .versionrc.js
"skip": {
"changelog": true, // 自动生成changelog
"commit": true, // 自动commit
"tag": true // 打tag标识
}
复制代码