实现提交代码至 Git 远程仓库前,自动验证规范性

目录

1. 验证目的

2. 实现原理

3. 配置过程

3.1 添加 husky 和 lint-staged,调用 git 钩子 / 分析暂存内容

3.2 添加 stylelint,分析 css

3.3 添加 commit-lint,验证提交信息

3.4 添加 markdownlint 配置文件

3.5 添加 conventional-changelog,方便标记提交 tag

3.6 添加钩子

4. package.json 完整配置示例


1. 验证目的

如果出现下面的内容,客户端应该无法提交:

  • 有问题的代码,比如不符合规范的 css 样式
  • 有问题的提交消息,比如不使用 feat 等描述前缀

2. 实现原理

客户端在使用 git commit 提交代码时,会使用 Git 钩子(pre-commit)

这个钩子会自动执行 某些脚本(eslint),实现代码检测

若检测出错,则阻止 commit 代码

3. 配置过程

3.1 添加 husky 和 lint-staged,调用 git 钩子 / 分析暂存内容

husky 是一个 Git 的 Hook(译为钩子) 工具

lint-staged 是一个对 Git 暂存阶段的内容,执行各种分析的工具

安装下方依赖:

// husky 是一个 Git 的 Hook(译为钩子) 工具
yarn add husky -D

// lint-staged 是一个对 Git 暂存阶段的内容,执行各种分析的工具
yarn add lint-staged -D

在项目根目录下的 pakage.json 的 scripts 标签 中,添加以下内容:

    "prepare": "husky install",
    "postinstall": "husky install",
    "pre-commit": "lint-staged",

3.2 添加 stylelint,分析 css

stylelint 是一个对 CSS 进行分析的工具

在 VSCode 中安装 stylelint 插件:

在项目根目录下,执行下方命令,安装 stylelint 依赖:

// stylelint 是对 CSS 进行分析的工具
yarn add -D stylelint stylelint-config-standard stylelint-config-sass-guidelines
yarn add -D stylelint-order

在项目根目录下创建 .stylelintrc.js 文件:

module.exports = {
  // 按照规则对CSS属性进行排序
  extends: ['stylelint-config-standard', 'stylelint-config-sass-guidelines'],
  plugins: ['stylelint-scss',"stylelint-order"],
  rules: {
    'selector-no-qualifying-type': null,
    // 允许的最大嵌套深度为 3
    'max-nesting-depth': 3,
    // 屏蔽属性按字母顺序检查
    'order/properties-alphabetical-order': null,
    // 屏蔽类选择器的检查,以确保使用字符
    'selector-class-pattern': null,
    // 允许的最大复合选择器为 5
    'selector-max-compound-selectors': 5,
    // 屏蔽没有申明通用字体
    'font-family-no-missing-generic-family-keyword': null,
    'order/properties-order': [
			[
				'content',
				'position',
				'top',
				'right',
				'bottom',
				'left',
				'z-index',
				'display',
				'vertical-align',
				'flex',
				'flex-grow',
				'flex-shrink',
				'flex-basis',
				'flex-direction',
				'flex-flow',
				'flex-wrap',
				'grid',
				'grid-area',
				'grid-template',
				'grid-template-areas',
				'grid-template-rows',
				'grid-template-columns',
				'grid-row',
				'grid-row-start',
				'grid-row-end',
				'grid-column',
				'grid-column-start',
				'grid-column-end',
				'grid-auto-rows',
				'grid-auto-columns',
				'grid-auto-flow',
				'grid-gap',
				'grid-row-gap',
				'grid-column-gap',
				'gap',
				'row-gap',
				'column-gap',
				'align-content',
				'align-items',
				'align-self',
				'justify-content',
				'justify-items',
				'justify-self',
				'order',
				'float',
				'clear',
				'object-fit',
				'overflow',
				'overflow-x',
				'overflow-y',
				'overflow-scrolling',
				'clip',

				//
				'box-sizing',
				'width',
				'min-width',
				'max-width',
				'height',
				'min-height',
				'max-height',
				'margin',
				'margin-top',
				'margin-right',
				'margin-bottom',
				'margin-left',
				'padding',
				'padding-top',
				'padding-right',
				'padding-bottom',
				'padding-left',
				'border',
				'border-spacing',
				'border-collapse',
				'border-width',
				'border-style',
				'border-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',
				'border-left',
				'border-left-width',
				'border-left-style',
				'border-left-color',
				'border-radius',
				'border-top-left-radius',
				'border-top-right-radius',
				'border-bottom-right-radius',
				'border-bottom-left-radius',
				'border-image',
				'border-image-source',
				'border-image-slice',
				'border-image-width',
				'border-image-outset',
				'border-image-repeat',
				'border-top-image',
				'border-right-image',
				'border-bottom-image',
				'border-left-image',
				'border-corner-image',
				'border-top-left-image',
				'border-top-right-image',
				'border-bottom-right-image',
				'border-bottom-left-image',

				//
				'background',
				'background-color',
				'background-image',
				'background-attachment',
				'background-position',
				'background-position-x',
				'background-position-y',
				'background-clip',
				'background-origin',
				'background-size',
				'background-repeat',
				'color',
				'box-decoration-break',
				'box-shadow',
				'outline',
				'outline-width',
				'outline-style',
				'outline-color',
				'outline-offset',
				'table-layout',
				'caption-side',
				'empty-cells',
				'list-style',
				'list-style-position',
				'list-style-type',
				'list-style-image',

				//
				'font',
				'font-weight',
				'font-style',
				'font-variant',
				'font-size-adjust',
				'font-stretch',
				'font-size',
				'font-family',
				'src',
				'line-height',
				'letter-spacing',
				'quotes',
				'counter-increment',
				'counter-reset',
				'-ms-writing-mode',
				'text-align',
				'text-align-last',
				'text-decoration',
				'text-emphasis',
				'text-emphasis-position',
				'text-emphasis-style',
				'text-emphasis-color',
				'text-indent',
				'text-justify',
				'text-outline',
				'text-transform',
				'text-wrap',
				'text-overflow',
				'text-overflow-ellipsis',
				'text-overflow-mode',
				'text-shadow',
				'white-space',
				'word-spacing',
				'word-wrap',
				'word-break',
				'overflow-wrap',
				'tab-size',
				'hyphens',
				'interpolation-mode',

				//
				'opacity',
				'visibility',
				'filter',
				'resize',
				'cursor',
				'pointer-events',
				'user-select',

				//
				'unicode-bidi',
				'direction',
				'columns',
				'column-span',
				'column-width',
				'column-count',
				'column-fill',
				'column-gap',
				'column-rule',
				'column-rule-width',
				'column-rule-style',
				'column-rule-color',
				'break-before',
				'break-inside',
				'break-after',
				'page-break-before',
				'page-break-inside',
				'page-break-after',
				'orphans',
				'widows',
				'zoom',
				'max-zoom',
				'min-zoom',
				'user-zoom',
				'orientation',
				'fill',
				'stroke',

				//
				'transition',
				'transition-delay',
				'transition-timing-function',
				'transition-duration',
				'transition-property',
				'transform',
				'transform-origin',
				'animation',
				'animation-name',
				'animation-duration',
				'animation-play-state',
				'animation-timing-function',
				'animation-delay',
				'animation-iteration-count',
				'animation-direction',
				'animation-fill-mode',
			],
      {
				unspecified: 'bottom',
				severity: 'warning',
			},
		],
  },
};

3.3 添加 commit-lint,验证提交信息

commitlint 是一个对 提交信息 进行分析的工具

执行下方代码,安装依赖:

// commitlint 是对提交信息进行 分析的工具
yarn add -D @commitlint/cli @commitlint/config-conventional

在项目根目录下,创建 commitlint.config.js 文件:

module.exports = {
  extends: ['@commitlint/config-conventional'],
};

3.4 添加 markdownlint 配置文件

在项目根目录下,创建 .markdownlint.json 文件:

{
    "MD010": false,
    "MD013": false,
    "MD024": false,
    "MD025": false,
    "MD033": false,
    "MD046": false
}

3.5 添加 conventional-changelog,方便标记提交 tag

conventional-changelog 是一款可以根据项目的 commit 和 metadata 信息,自动生成 changelogs 和 release notes 的系列工具;

在辅助 standard-version 工具的情况下,它可以自动帮你完成以下工作:

  • 生成 version
  • 打 tag(标记为重要提交)
  • 生成 CHANGELOG
  • 其他

默认推荐的 commit 标准,来自 Angular 项目;除了 Angular 标准外,目前还集成了以下标准:

  • atom
  • codemirror
  • ember
  • eslint
  • express
  • jquery

安装依赖:

npm install conventional-changelog-cli -D

基本使用:

  • 参数 -i CHANGELOG.md 表示 —— 从 CHANGELOG.md 读取 changelog
  • -s 表示 —— 读写 changelog 为同一文件
conventional-changelog -p angular -i CHANGELOG.md -s

注意:上方命令产生的 changelog,是基于上次 tag 版本之后的变更(Feature、Fix、Breaking Changes 等等)所产生的

如果你想生成之前所有 commit 信息产生的 changelog,则需要使用这条命令:

  • -r 表示生成 changelog 时,所有已经发布的版本是否全部生成
  • 0 代表文件整个被覆盖重写,默认为 1
conventional-changelog -p angular -i CHANGELOG.md -s -r 0

最后,在 package.json 中添加脚本:

{
  "scripts": {
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
  }
}

3.6 添加钩子

在 提交前做检查,主要配合 ESLint 和 stylelint:

npx husky add .husky/pre-commit "npm run pre-commit"

 

利用 commitlint 对提交信息进行检查:

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'

 

在 pakage.json 中,添加 husky、lint-staged 配置:

"lint-staged": {
    "*.{js,vue,ts}": [ // 这里要改成要进行检测的文件的格式和位置
      "npx eslint --fix" //提交代码时,会调用 eslint 自动修复不符合规则代码
    ],
    "*.{css,scss}": [
      "npx stylelint --fix"
    ]
  }

 

 

4. package.json 完整配置示例

{
  "name": "vue3-starter",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "prepare": "husky install",
    "postinstall": "husky install",
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "core-js": "^3.12.1",
    "element-plus": "^1.0.2-beta.44",
    "normalize.css": "^8.0.1",
    "vue": "^3.0.4",
    "vue-router": "^4.0.1",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@commitlint/cli": "^12.1.4",
    "@commitlint/config-conventional": "^12.1.4",
    "@typescript-eslint/eslint-plugin": "^4.24.0",
    "@typescript-eslint/parser": "^4.24.0",
    "@vue/cli-plugin-babel": "~5.0.0-beta.1",
    "@vue/cli-plugin-eslint": "~5.0.0-beta.1",
    "@vue/cli-plugin-router": "~5.0.0-beta.1",
    "@vue/cli-plugin-typescript": "~5.0.0-beta.1",
    "@vue/cli-plugin-vuex": "~5.0.0-beta.1",
    "@vue/cli-service": "~5.0.0-beta.1",
    "@vue/compiler-sfc": "^3.0.11",
    "@vue/eslint-config-airbnb": "^5.3.0",
    "@vue/eslint-config-typescript": "^7.0.0",
    "babel-plugin-component": "^1.1.1",
    "eslint": "^7.26.0",
    "eslint-plugin-import": "^2.23.2",
    "eslint-plugin-vue": "^7.9.0",
    "husky": "^6.0.0",
    "lint-staged": "^11.0.0",
    "sass": "^1.32.13",
    "sass-loader": "^11.1.1",
    "stylelint": "^13.13.1",
    "stylelint-config-sass-guidelines": "^8.0.0",
    "stylelint-config-standard": "^22.0.0",
    "stylelint-order": "^4.1.0",
    "stylelint-scss": "^3.19.0",
    "typescript": "~4.2.4",
    "webpack-bundle-analyzer": "^4.4.2"
  },
  "lint-staged": {
    "*.{js,vue,ts}": [
      "npx eslint --fix"
    ],
    "*.{css,scss}": [
      "npx stylelint --fix"
    ]
  }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值