前端项目工程化之 vue 项目中添加 git hooks (优雅的 git commit 以及 eslint 和 stylelint 自动修复代码样式)
项目基本依赖:”vue-cli”:”3.5.3” “core-js”: “^2.6.5” “vue”: “^2.6.10” “babel-eslint”: “^10.0.1”
“eslint”: “^5.16.0”
“eslint-plugin-vue”: “^5.0.0”
编辑器:vscode
使用效果
使用步骤
注意:使用前确保 vue.config.js 里的 lintOnSave 已设置为 true
1.安装以下依赖
1 | npm i -D @commitlint/cli@8.1.0 @commitlint/config-conventional@8.1.0 commitizen@4.0.3 cz-conventional-changelog@3.0.2 cz-customizable@6.2.0 husky@3.0.2 lint-staged@8.1.5 |
2.package.json 文件中添加以下配置
1 | |
2 | "scripts": { |
3 | "serve": "vue-cli-service serve", |
4 | "build": "vue-cli-service build", |
5 | "lint": "vue-cli-service lint", |
6 | "commit": "git-cz" |
7 | }, |
8 | "husky": { |
9 | "hooks": { |
10 | "pre-commit": "lint-staged", |
11 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" |
12 | } |
13 | }, |
14 | "config": { |
15 | "commitizen": { |
16 | "path": "node_modules/cz-customizable" |
17 | } |
18 | }, |
19 | "lint-staged": { |
20 | "src/**/*.{js,vue}": [ |
21 | "vue-cli-service lint", |
22 | "git add" |
23 | ] |
24 | }, |
上面 package.json 配置说明(不要复制下面 json,json 不支持注释)
1 | |
2 | "scripts": { |
3 | "serve": "vue-cli-service serve", |
4 | "build": "vue-cli-service build", |
5 | "lint": "vue-cli-service lint",// vue-cli 自带的lint检查 |
6 | "commit": "git-cz" // 提交命令 |
7 | }, |
8 | "husky": { |
9 | "hooks": { |
10 | "pre-commit": "lint-staged", //git commit 执行这个命令,这个命令再调起 lint-staged |
11 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" //提交检查 |
12 | } |
13 | }, |
14 | "config": { |
15 | "commitizen": { |
16 | "path": "node_modules/cz-customizable" //定制项目的提交说明 |
17 | } |
18 | }, |
19 | "lint-staged": { |
20 | // 检查文件 |
21 | "src/**/*.{js,vue}": [ |
22 | |
23 | "vue-cli-service lint",// 提交之前检查并修复代码 |
24 | |
25 | "git add" |
26 | ] |
27 | }, |
3.在项目根目录下新建 commitlint.config.js 文件配置如下
1 | module.exports = { |
2 | extends: ["@commitlint/config-conventional"], |
3 | rules: { |
4 | // 提交主题类型 |
5 | "type-enum": [ |
6 | 2, |
7 | "always", |
8 | [ |
9 | "feat", |
10 | "perf", |
11 | "fix", |
12 | "docs", |
13 | "style", |
14 | "refactor", |
15 | "test", |
16 | "chore", |
17 | "revert", |
18 | "build", |
19 | "ci" |
20 | ] // 主题含义见 /.cz-config.js |
21 | ], |
22 | "subject-full-stop": [0, "never"], // 主题句号 |
23 | "subject-case": [0, "never"] // 主题案例 |
24 | } |
25 | }; |
4.在项目根目录下新建 .cz-config.js 文件配置如下(注意:不要省略文件名前的点 “ . “)
1 | module.exports = { |
2 | // 修改主题选择 |
3 | types: [ |
4 | { value: "build", name: "build: 构建打包" }, |
5 | { value: "feat", name: "feat: 添加新功能" }, |
6 | { value: "fix", name: "fix: Bug修复" }, |
7 | { |
8 | value: "docs", |
9 | name: "docs: 变更的只有文档,比如README.md等" |
10 | }, |
11 | { |
12 | value: "style", |
13 | name: "style: 空格, 分号等格式修复(注意不是 css 修改)" |
14 | }, |
15 | { value: "ci", name: "ci ci配置,脚本文件等更新" }, |
16 | { |
17 | value: "refactor", |
18 | name: "refactor: 代码重构(即不是新增功能,也不是修改bug的代码变动)" |
19 | }, |
20 | { value: "test", name: "test: 添加一个测试,包括单元测试、集成测试等" }, |
21 | { value: "perf", name: "perf: 优化相关,比如提升性能、体验" }, |
22 | { value: "chore", name: "chore: 改变构建流程、或者增加依赖库、工具等" }, |
23 | { value: "revert", name: "revert: 代码回退" } |
24 | ], |
25 | |
26 | // 修改文件范围选择 |
27 | // scopes: [ |
28 | // { name: 'components' }, |
29 | // { name: 'assets' }, |
30 | // { name: 'views' }, |
31 | // { name: 'api' }, |
32 | // { name: 'utils' }, |
33 | // { name: 'other' }, |
34 | // ], |
35 | |
36 | // 选择对应的主题后的选择 |
37 | // scopeOverrides: { |
38 | // fix: [ |
39 | // { name: 'merge' }, |
40 | // { name: 'style' }, |
41 | // { name: 'e2eTest' }, |
42 | // { name: 'unitTest' } |
43 | // ] |
44 | // }, |
45 | |
46 | // 构建对话 |
47 | messages: { |
48 | type: "选择一种你的提交类型(必选):", |
49 | scope: "选择一个更改范围(可选):", |
50 | // used if allowCustomScopes is true |
51 | customScope: "自定义更改范围(可选):", |
52 | subject: "短说明(必填):\n", |
53 | body: '长说明,使用"|"换行(可选):\n', |
54 | breaking: "非兼容性说明 (可选):\n", |
55 | footer: "关联关闭的issue,例如:#31, #34(可选):\n", |
56 | confirmCommit: "确定提交说明?" |
57 | }, |
58 | // 是否允许自定义更改范围 |
59 | allowCustomScopes: true, |
60 | // 允许中断的改变 |
61 | allowBreakingChanges: ["feat", "fix"], |
62 | // 修改主题描述字数限制 |
63 | subjectLimit: 100, |
64 | // 选择跳过的步骤(不用填,不用选,直接跳过) |
65 | skipQuestions: ["body", "breaking", "footer"] |
66 | }; |
5.在项目根目录下新建 .eslintrc.js 文件配置如下(自己可以参考官网修改)
eslint 中文网 http://eslint.cn/docs/rules/
eslint-config-vue 配置 https://github.com/vuejs/eslint-config-vue/blob/master/index.js
1 | module.exports = { |
2 | root: true, |
3 | parserOptions: { |
4 | parser: "babel-eslint", |
5 | sourceType: "module" |
6 | }, |
7 | env: { |
8 | browser: true, |
9 | node: true, |
10 | es6: true |
11 | }, |
12 | extends: ["plugin:vue/recommended", "eslint:recommended"], |
13 | |
14 | // add your custom rules here |
15 | //it is base on https://github.com/vuejs/eslint-config-vue |
16 | rules: { |
17 | "vue/max-attributes-per-line": [ |
18 | 2, |
19 | { |
20 | singleline: 10, |
21 | multiline: { |
22 | max: 1, |
23 | allowFirstLine: false |
24 | } |
25 | } |
26 | ], |
27 | "vue/singleline-html-element-content-newline": "off", |
28 | "vue/multiline-html-element-content-newline": "off", |
29 | "vue/name-property-casing": ["error", "PascalCase"], |
30 | "vue/no-v-html": "off", |
31 | "accessor-pairs": 2, |
32 | "vue/html-self-closing": "off", |
33 | "arrow-spacing": [ |
34 | 2, |
35 | { |
36 | before: true, |
37 | after: true |
38 | } |
39 | ], |
40 | "block-spacing": [2, "always"], |
41 | "brace-style": [ |
42 | 2, |
43 | "1tbs", |
44 | { |
45 | allowSingleLine: true |
46 | } |
47 | ], |
48 | camelcase: [ |
49 | 0, |
50 | { |
51 | properties: "always" |
52 | } |
53 | ], |
54 | "no-undef": 2, |
55 | "no-undef-init": 2, |
56 | "no-unreachable": 2, |
57 | "no-unsafe-finally": 2, |
58 | "no-unused-vars": [ |
59 | 2, |
60 | { |
61 | vars: "all", |
62 | args: "none" |
63 | } |
64 | ], |
65 | quotes: [ |
66 | 2, |
67 | "single", |
68 | { |
69 | avoidEscape: true, |
70 | allowTemplateLiterals: true |
71 | } |
72 | ], |
73 | semi: [2, "never"], |
74 | "semi-spacing": [ |
75 | 2, |
76 | { |
77 | before: false, |
78 | after: true |
79 | } |
80 | ], |
81 | "space-before-blocks": [2, "always"], |
82 | |
83 | "spaced-comment": [ |
84 | 2, |
85 | "always", |
86 | { |
87 | markers: [ |
88 | "global", |
89 | "globals", |
90 | "eslint", |
91 | "eslint-disable", |
92 | "*package", |
93 | "!", |
94 | "," |
95 | ] |
96 | } |
97 | ], |
98 | "template-curly-spacing": [2, "never"], |
99 | |
100 | "no-debugger": process.env.NODE_ENV === "production" ? 2 : 0, |
101 | "object-curly-spacing": [ |
102 | 2, |
103 | "always", |
104 | { |
105 | objectsInObjects: false |
106 | } |
107 | ], |
108 | "array-bracket-spacing": [2, "never"] |
109 | } |
110 | }; |
6.在项目根目录下新建 update.sh 文件配置如下
1 |
|
2 | |
3 | success="更新成功" |
4 | fail="更新失败" |
5 | |
6 | # 确保脚本抛出遇到的错误 |
7 | set -e |
8 | |
9 | # 参数检验 |
10 | if [ $# -gt 0 ] ; then |
11 | echo fail: $fail; |
12 | exit 1 |
13 | fi |
14 | |
15 | git add . |
16 | npm run commit |
17 | # 捕获异常 |
18 | if [ $? = 0 ] ; then |
19 | git push # 确保执行过默认分支操作 git push -u origin master 或者 git push -u origin dev 等 |
20 | echo success:$success |
21 | else |
22 | echo fail: $fail; |
23 | exit 1 |
24 | fi |
6.使用
项目根目录下启动 git-bash (vscode 默认 bash 改成 git-bash)
运行以下命令,
对于可选的项目直接按 enter 键跳过
1 | ./update.sh |
7.项目添加配置 Stylelint
公司项目使用的 scss ,下面以 scss 为例
a.安装以下包
stylelint: 必须安装
stylelint-config-standard: 是官方推荐的插件
stylelint-order: 是规范样式的顺序的
stylelint-scss:stylelint 的 SCSS 特定 linting 规则的集合
1 | npm i stylelint stylelint-config-standard stylelint-order stylelint-scss -D |
b. 在项目根目录下新建.stylelintrc 文件(或其他支持的文件格式)
1 | { |
2 | "defaultSeverity": "error", |
3 | "extends": ["stylelint-config-standard"], |
4 | "plugins": ["stylelint-scss", "stylelint-order"], |
5 | "rules": { |
6 | "order/order": [ |
7 | "declarations", |
8 | "custom-properties", |
9 | "dollar-variables", |
10 | "rules", |
11 | "at-rules" |
12 | ], |
13 | "order/properties-order": [ |
14 | "position", |
15 | "top", |
16 | "right", |
17 | "bottom", |
18 | "left", |
19 | "float" |
20 | ], |
21 | "media-feature-name-no-vendor-prefix": true, |
22 | "at-rule-no-vendor-prefix": true, |
23 | "selector-no-vendor-prefix": true, |
24 | "property-no-vendor-prefix": true, |
25 | "value-no-vendor-prefix": true, |
26 | "rule-empty-line-before": null, |
27 | "no-missing-end-of-source-newline": null, |
28 | "selector-pseudo-class-no-unknown": null, |
29 | "font-family-no-missing-generic-family-keyword": null, |
30 | "no-descending-specificity": null, |
31 | "declaration-empty-line-before": null, |
32 | "declaration-block-trailing-semicolon": null, |
33 | "selector-combinator-space-before": null, |
34 | "selector-combinator-space-after": null, |
35 | "block-closing-brace-newline-before": null, |
36 | "at-rule-no-unknown": null, |
37 | "property-case": null, |
38 | "property-no-unknown": null |
39 | } |
40 | } |
c. 在项目根目录下新建.stylelintignore 文件 (默认忽略 node_modules 文件夹)
1 | *.min.css |
2 | |
3 | # 其他类型文件 |
4 | *.js |
5 | *.jpg |
6 | *.woff |
7 | |
8 | # 测试和打包目录 |
9 | /test/ |
10 | /dist/ |
d.配置 package.json
“scripts” 字段下添加 stylelint 命令
1 | { |
2 | "scripts": { |
3 | "serve": "vue-cli-service serve", |
4 | "build": "vue-cli-service build", |
5 | "dev": "vue-cli-service serve", |
6 | "build:prod": "vue-cli-service build --mode production", |
7 | "build:dev": "vue-cli-service build --mode dev", |
8 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0", |
9 | "lint": "vue-cli-service lint", |
10 | "stylelint": "stylelint **/*.{html,vue,css,sass,scss} --fix", |
11 | "commit": "git-cz" |
12 | } |
13 | } |
“lint-staged” 字段改为如下
1 | { |
2 | "lint-staged": { |
3 | "src/**/*.{js,vue}": ["npm run lint", "git add"], |
4 | "**/*.{html,vue,css,sass,scss}": ["npm run stylelint", "git add"] |
5 | } |
6 | } |
e.使用,同上
运行
1 | ./update.sh |
参考链接
1.https://github.com/okonet/lint-staged
2.https://github.com/typicode/husky
3.https://github.com/conventional-changelog/commitlint
4.https://blog.csdn.net/weixin_33890526/article/details/91393527
5.https://juejin.im/post/5afc5242f265da0b7f44bee4#heading-9