项目规范配置
1.git提交规范配置
- commitlint 约束commit messag规范
- lint-stage 提交代码时只针对暂存区文件(git add), 进行代码lint检查并fix
- husky git hooks工具 git操作时可运行指定钩子命令
配置commitlint
规范git commit message, 约束commit提交格式commitlint文档说明
git commit -m <type>(<scope>?): <subject>
type(必须):
- feat:新功能(feature)
- ci:自动化流程配置修改
- fix:修补bug
- docs:文档更新(documentation)
- style:修改了空格、缩进等(不影响代码运行的变动)
- refactor:功能重构(即不是新增功能,也不是修改bug的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动 比如 webpack babel eslint配置
- perf:优化相关,比如提升性能、体验。
- revert:回滚
scope(可选):
scope用于说明 commit 影响的范围,比如 feat(src/element.js): element按需导入
subject(必须): commit的简短描述
# example
git commit -m "some message" # fails
git commit -m "fix: some message" # passes
安装commitlint
# 安装 commitlint
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# 第二种安装commitlint写法
# 如果命令窗口是 mac iterm2 或 windows cmder支持此复合写法安装 (windows cmd powershell不支持此写法会报错)
npm install --save-dev @commitlint/{cli,config-conventional}
项目目录下创建commitlint配置文件:
module.exports = {
extends: ['@commitlint/config-conventional']
}
安装lint-stage husky (配合commitlint使用)
安装lint-stage
lint-stage代码lint工具 只处理暂存区文件,husky git钩子工具
# 装lint-stage
npm i -D lint-staged
安装husky
npm i husky -D
通过husky安装两个hook
yarn husky add,添加一个commit-msg hook 和 pre-commit hook
husky与commitlint文档说明 windows建议用 git bash 执行命令 mac 建议用iterm2 执行命令
# Install Husky v6
npm install husky --save-dev
# or
yarn add husky --dev
# Active hooks
# 激活开启 husky 执行完会看到根目录下生成.husky文件夹 里面会保存husky add增加的hook文件
npx husky install
# or
yarn husky install
# Add hook
# 再添加一个pre-commit hook 代码提交时 用来执行lint-staged命令
# --no-install 参数表示强制npx使用项目本地安装的commitlint 和 lint-staged npm包
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'
# or
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'
刚刚用husky添加的两个hook会在当前根目录下 ./husky文件夹里看到commit-msg
pre-commit
package.json添加如下内容(样式校验会在后面说明)
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "npx --no-install commitlint --edit $1"
}
},
"lint-staged": {
"*.{js,vue}": [
"stylelint --config ./.stylelintrc --fix",
"eslint --fix"
],
"*.{less,css}": [
"stylelint --config ./.stylelintrc --fix"
]
}
验证配置
git commit时 liint-staged会先对暂存区文件进行代码格式化 然后检查commit message规范'
commit 失败
git commit -m "提交代码"
控制台错误信息
qbank git:(cq-dev) ✗ git commit -m"提交代码"
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
⧗ input: 提交代码
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg hook exited with code 1 (error)
commit 成功
# type 类型 feat(项目新功能) fix(修补bug) test(测试) chore(工程配置改动)
# scope 影响范围 比如 src/main
# subject msg简短描述
# type(scope): subject 冒号后面也要有一个空格
git commit -m "chore(config): 添加commitlint和lint-stage配置"
控制台信息
qbank git:(cq-dev) ✗ git commit -m "chore(config): 添加commitlint和lint-stage配置"
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
[cq-dev 8098a3e6] chore(config): 添加commitlint和lint-stage配置
7 files changed, 984 insertions(+), 14 deletions(-)
create mode 100644 .husky/.gitignore
create mode 100755 .husky/commit-msg
create mode 100755 .husky/pre-commit
create mode 100644 commitlint.config.js
2.EsLint + styleLint 配置
安装esLint依赖:
npm install eslint-plugin-vue eslint @vue/cli-plugin-eslint -D
安装styleLint依赖:
npm install stylelint-config-standard stylelint-order stylelint -D
.eslintrc.js文件配置
module.exports = {
root: true, // 检测到最近一级.eslintrc*
env: {
es6: true, // 支持并启用es6语法
node: true, // 支持node语法及变量
browser: true, // 支持浏览器全局变量
},
extends: ['plugin:vue/recommended', 'eslint:recommended'], // 第三方插件
plugins: ['vue'],
parserOptions: {
parser: 'babel-eslint', // 解析器,默认使用Espree
ecmaVersion: 2018,
sourceType: 'module', // 指定文件来源类型,"script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)
},
// 全局变量不做校验
globals: {
moment: 'writable',
Vue: 'writable',
VueRouter: 'writable',
VueI18n: 'writable',
ELEMENT: 'writable',
TWEEN: 'writable',
_: 'writable',
MathJax: 'writable'
},
rules: {
indent: ['error', 2, {SwitchCase: 1}],
'no-debugger': 2,
'no-unused-vars': 1,
eqeqeq: 2,
quotes: ['error', 'single', {'allowTemplateLiterals': true}],
'no-irregular-whitespace': 2, // 禁止不规则的空格
'no-multi-spaces': 'error', // 禁止多个空格
'space-infix-ops': 2, // 运算符前后禁止多个空格
'array-bracket-spacing': ['error', 'never'], // 数组统一空格
'block-spacing': ['error', 'always'],
'comma-spacing': ['error'],
'comma-style': ['error', 'last'],
'computed-property-spacing': ['error', 'never'],
'func-call-spacing': ['error', 'never'],
'key-spacing': ['error', {'beforeColon': false, 'afterColon': true}], // 冒号空格
'keyword-spacing': ['error', {'before': true}], //if () {}空格else
'no-whitespace-before-property': 'error',
'semi-spacing': 'error', //分号空格
'space-before-blocks': ['error', 'never'], //function name()空格{}
'space-before-function-paren': ['error', 'never'], //function name空格(){}
'space-in-parens': ['error', 'never'],
'arrow-spacing': ['error', {'before': false, 'after': false}], //()空格=>空格{}
'rest-spread-spacing': ['error', 'never'], // 空格...空格{}
'no-unreachable': 1,
'no-console': ["error", { allow: ["error","warn"] }],
'no-trailing-spaces': 2,
'object-curly-spacing': ['error', 'never'],
// 'vetur.validation.template': false,
// 'vue/valid-template-root': 'off',
'vue/no-v-html': 0,
'vue/component-tags-order': ['error', {'order': ['style', 'template', 'script']}],
'vue/html-quotes': ['error', 'double'],
'vue/require-v-for-key': 1, // v-for要有key
'vue/html-self-closing': 'off', // 标签闭合
'vue/html-closing-bracket-newline': ['error', {
'singleline': 'never',
'multiline': 'never'
}],
'vue/html-closing-bracket-spacing': 'error', // 标签后是否允许空格
'vue/html-end-tags': 'error', // 标签自我关闭
'vue/mustache-interpolation-spacing': 2, // 标签插值中前后固定一个空格
'vue/no-reserved-component-names': 'error', // 禁止保留名称
'vue/no-unsupported-features': 1, // 未支持的语法
'vue/no-unused-components': 1, // 未注册的组件
'vue/padding-line-between-blocks': 1, //
'vue/no-use-v-if-with-v-for': 1,
'vue/singleline-html-element-content-newline': 0, // {{}}强制换行
// "vue/static-class-names-order": 1, // name属性
'vue/max-attributes-per-line': ['error', { // 单行和多行属性数量
'singleline': 10,
'multiline': {
'max': 1,
'allowFirstLine': false
}
}],
},
};
eslint呼略文件 .eslintignore
dist
node_modules
.stylelintrc.js文件配置
module.exports = {
extends: ['stylelint-config-standard'],
plugins: ["stylelint-order"],
rules:{
'no-descending-specificity':null,
'function-url-quotes': 'always',
'string-quotes': 'double',
'indentation': 2,
'unit-case':null,
'color-hex-case': 'upper',
'color-hex-length': 'long',
'rule-empty-line-before': 'never',
'font-family-no-missing-generic-family-keyword': null,
'block-opening-brace-space-before':'always',
'property-no-unknown':null,
'no-empty-source':null,
"order/properties-order": [
//css内容
'content',
'counter-increment',
'counter-reset',
'quotes',
'crop',
'move-to',
'page-policy',
//css3 过渡
'transition',
'transition-property',
'transition-duration',
'transition-delay',
'transition-timing-function',
//css3 2d 3d
'transform-origin',
'transform-style',
'perspective',
'perspective-origin',
'backface-visibility',
'transform',
//动画
'animation',
'animation-name',
'animation-duration',
'animation-timing-function',
'animation-delay',
'animation-iteration-count',
'animation-direction',
'animation-play-state',
'animation-fill-mode',
//定位
'box-sizing',
'display',
'vertical-align',
'visibility',
//溢出
'overflow',
'overflow-x',
'overflow-y',
'overflow-style',
//表格
'border-collapse',//边框合并
'border-spacing',
'caption-side',
'empty-cells',
'table-layout',
//定位
'position',
'z-index',
'left',
'top',
'right',
'bottom',
'clip',
//浮动
'float',
'clear',
//大小
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
//填充
'padding',
'padding-left',
'padding-top',
'padding-right',
'padding-bottom',
//间距
'margin',
'margin-left',
'margin-top',
'margin-right',
'margin-bottom',
//背景
'background',
'background-color',
'background-image',
'background-size',
'background-position',
'background-repeat',
'background-attachment',
'background-origin',
'background-clip',
//边框
'border',
'border-width',
'border-style',
'border-color',
'border-left',
'border-left-width',
'border-left-style',
'border-left-color',
'border-top',
'border-top-width',
'border-top-style',
'border-top-color',
'border-right',
'border-right-width',
'border-right-style',
'border-right-color',
'border-bottom',
'border-bottom-width',
'border-bottom-style',
'border-bottom-color',
'outline',
'outline-width',
'outline-style',
'outline-color',
'outline-offset',
'border-image',
'border-image-source',
'border-image-slice',
'border-image-width',
'border-image-outset',
'border-image-repeat',
'border-radius',
'border-top-left-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'border-bottom-left-radius',
'box-shadow',
//效果
'list-style',
'list-style-type',
'list-style-position',
'list-style-image',
'opacity',
'cursor',
'resize',
//文字
'font',
'font-family',
'font-size',
'line-height',
'font-weight',
'text-align',
'text-justify',
'text-indent',
'letter-spacing',
'white-space',
'word-spacing',
'text-overflow',
'word-break',
'word-wrap',
'color',
'direction',
'font-style',
'text-decoration',
'text-transform',
'text-shadow',
'font-variant',
'font-size-adjust',
'font-stretch',
'unicode-bidi',
'hanging-punctuation',
'punctuation-trim',
'text-align-last',
'text-emphasis',
'text-outline',
'text-wrap',
//无效
'box-decoration-break',
//旋转
'rotation',
'rotation-point',
'color-profile',
'rendering-intent',
'bookmark-label',
'bookmark-level',
'bookmark-target',
'float-offset',
'hyphenate-after',
'hyphenate-before',
'hyphenate-character',
'hyphenate-lines',
'hyphenate-resource',
'hyphens',
'image-resolution',
'marks',
'string-set',
'box-align',
'box-direction',
'box-flex',
'box-flex-group',
'box-lines',
'box-ordinal-group',
'box-orient',
'box-pack',
'grid-columns',
'grid-rows',
'target',
'target-name',
'target-new',
'target-position',
'marker-offset',
'marquee-direction',
'marquee-play-count',
'marquee-speed',
'marquee-style',
'column-count',
'column-fill',
'column-gap',
'column-rule',
'column-rule-color',
'column-rule-style',
'column-rule-width',
'column-span',
'column-width',
'columns',
'fit',
'fit-position',
'image-orientation',
'page',
'size',
'orphans',
'page-break-after',
'page-break-before',
'page-break-inside',
'widows',
'appearance',
'icon',
'nav-down',
'nav-index',
'nav-left',
'nav-right',
'nav-up'
]
}
}
stylelint 呼略文件 .stylelintignore
dist
node_modules
3. vscode配置
1. vscode需要添加以下配置
```javascript
"eslint.validate": ["javascript", "javascriptreact", "html", "vue"],
"vetur.validation.template": false,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"workbench.activityBar.visible": true,
"editor.quickSuggestions": {
"strings": true
},
"git.enableSmartCommit": true,
"editor.tabSize": 2,
"git.confirmSync": false,
"less.lint.unknownProperties": "ignore",
"less.lint.vendorPrefix": "ignore",
//快速添加文件头部注释和函数注释
"fileheader.configObj": {
"createFileTime": true, //设置为true则为文件新建时候作为date,否则注释生成时间为date
"autoAdd": true, //自动生成注释
//默认注释形式
"annotationStr": {
"head": "/*", //自定义注释头部
"middle": " * @", //自定义注释中间部分(注意空格,这也是最终生成注释的一部分)
"end": " */", //自定义注释尾部
"use": true //设置自定义注释可用
},
},
// 默认函数注释
"fileheader.cursorMode": {
"description": "", //自定义函数描述
"param": "", //参数
"return": "" //返回内容
},
"fileheader.customMade": {
"Description": "", //文件内容描述
"Author": "", //创建人,因为是团队合作,写死不合适,所以空着由创建人自行填写
"Date": "Do not edit", //时间
"LastEditTime": "Do not edit", //最后编辑时间
"LastEditors": "Frank", //最后编辑人,写成自己的名字
"Usage": "" //使用方法
},
```
2. vscode需要添加以下插件
- ESlint
- stylelint
- koroFileHeader
- Git History Diff:建议安装,可以查看每段代码是谁编写的,方便开发
3.注释规范
已经安装好了自动添加注释插件 koroFileHeader
vscode需要添加以下配置
//快速添加文件头部注释和函数注释
"fileheader.configObj": {
"createFileTime": true, //设置为true则为文件新建时候作为date,否则注释生成时间为date
"autoAdd": true, //自动生成注释
//默认注释形式
"annotationStr": {
"head": "/*", //自定义注释头部
"middle": " * @", //自定义注释中间部分(注意空格,这也是最终生成注释的一部分)
"end": " */", //自定义注释尾部
"use": true //设置自定义注释可用
},
},
// 默认函数注释
"fileheader.cursorMode": {
"description": "", //自定义函数描述
"param": "", //参数
"return": "" //返回内容
},
"fileheader.customMade": {
"Description": "", //文件内容描述
"Author": "changqing", //创建人,因为是团队合作,写死不合适,所以空着由创建人自行填写
"Date": "Do not edit", //时间
"LastEditTime": "Do not edit", //最后编辑时间
"LastEditors": "jack", //最后编辑人,写成自己的名字
"Usage": "" //使用方法
}
- 文件头部注释 快捷键:
windows:ctrl+alt+i, mac:ctrl+cmd+i
- 函数注释 快捷键:
windows:ctrl+alt+t , mac:ctrl+cmd+t