husky + lint-staged 提交前执行代码检查

512 阅读3分钟

前言

年前为公司升级了新的monorepo项目架构,近来不用加班,在家得闲。便想再搭个monorepo项目,随便记录一下。
用到以下pnpm + vite3 + vue3 + ESLint + Stylelint + TypeScriptmonorepe实战记录,此篇为其中一个的简单介绍。

介绍

团队开发时,制定一定的规范,既能提高协作效率,还能保证格式统一。哪怕有了规范,但难免粗心大意而忽略规范的时候。通过husky和lint-staged在一定程度上可约束团队人员规范化开发。

  • husky:为 git 添加 hook 的工具,能够让git执行某些操作(比如commit、push等)前执行一些其他操作。
  • lint-staged:过滤暂存区文件,可以让提交前执行的钩子函数只作用于暂存区的文件。

提交前规则校验

通过工具(eslint,prettier,stylelint)可以对代码校验,保证了代码风格统一,提高了代码质量,可避免很多低级错误。
开发过程中总难免会有忽略代码校验的时候,但仍可正常提交。当代码不符合规范时,就该阻止代码提交。
通过huskylint-staged,可在提交前执行相关工具的校验工作,校验成功后才允许提交。

1,安装 husky 和 lint-staged

pnpm add husky lint-staged -D

husky: 8.0.3
lint-stged: 13.2.1

2,执行pnpx husky install,执行完会创建一个.husky文件夹,添加的git钩子就会在这个文件夹下。

3,添加git钩子

pnpx husky add ./husky/pre-commit "pnpx lint-staged"

添加了pre-commit钩子,在commit前会执行lint-staged的任务。而lint-staged会过滤暂存区文件,正好提交只需要对暂存区文件校验,接下来只需要编写对应的任务。

4,在package.json配置lint-staged任务

// package.json
{
    // ...
  "scripts": {
    "lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
    "lint:css": "stylelint **/*.{vue,css,sass,scss}",
    "prettier": "prettier --write \"src/**/*.{vue,js,jsx,ts,tsx}\"",
  },
  // 新增lint-staged
  "lint-staged": {
    "src/**/*.{vue,js,jsx,ts,tsx}": [
      "npm run lint",
      "npm run prettier"
    ],
    "*.{vue,css,sass,scss}": [
      "npm run lint:css"
    ]
  }
}

在代码提交前,暂存区内的*.{vue,js,jsx,ts,tsx}文件会执行npm run lintnpm run prettier命令,而*.{vue,scss,sass,css}文件则执行npm run lint:css命令,以实现代码的校验,当校验通过才会提交。

到此,通过 husky 和 line-staged 在提交前执行相关命令,便能自动对代码进行校验。

规范提交信息

1,安装相关库

pnpm add @commitlint/config-conventional @commitlint/cli -D

@commitlint/cli 17.5.1
@commitlint/config-conventional 17.4.4

2,添加相应的git钩子

pnpx husky add .husky/commit-msg "pnpx --no-install commitlint --edit $1"

3,项目根目录新建commitlint.config.cjs配置文件。参考配置如下

// commitlint.config.cjs
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    /**
     配置含义
      name: [ 
        等级( 0: disable,1: warning, 2: error ), 
        生效与否( always, never ),
        值
      ]
     */
    'type-enum': [
      2,
      'always',
      [
        'upd', // 更新某功能
        'feat', // 新增功能(feature)
        'fix', // 修复补丁(bug)
        'refactor', // 代码重构,未新增任何功能和修复任何 bug
        'docs', // 修订文档
        'style', // 仅调整空格、格式缩进等(不改变代码逻辑的变动)
        'test', // 测试用例的增加/修改
        'perf', // 优化相关,改善性能和体验的修改
        'chore', // 非 src 和 test 的修改
        'merge', // 合并分支或冲突等
        'revert', // 回滚到上一个版本
        'build',  //改变构建流程,新增依赖库、工具等(例如 webpack、maven 修改)
        'ci' //自动化流程配置修改
      ],
    ],
    'type-case': [0],
    'type-empty': [0],
    'scope-empty': [0],
    'scope-case': [0],
    'subject-full-stop': [0, 'never'],
    'subject-case': [0, 'never'],
    'header-max-length': [0, 'always', 72],
  },
}

git提交时就必须按规范才能提交,比如git commit -m 'feat: 新增xxx'