如何配置eslint stylelint pretter husky hooks 规范代码提交

399 阅读5分钟

描述

涉及工具:
    husky
    eslint
    stylelint
    prettier
    commitlint
    cz
    lintstaged

git hooks 顺序

pre-commit   钩子在键入提交信息前运行,检查是否有所遗漏,确保测试运行,以及核查代码
prepare-commit-msg  钩子在启动提交信息编辑器之前,主要在提交commit msg 信息之前做一个编辑操作
commit-msg   钩子接收一个参数,一般用于commit信息编辑完成后的一个验证操作
post-commit  钩子在整个提交过程完成后运行,该钩子一般用于通知之类的事情。
eslint
npm install eslint -g
eslint --init
// init命令选项之后生成下面的配置
module.exports = {
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:vue/essential",
        "plugin:@typescript-eslint/recommended"
    ],
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    "plugins": [
        "vue",
        "@typescript-eslint"
    ],
    "rules": {
    }
}
stylelint
// stylelint-config-standard 官方的css通用配置
// stylelint-order stylelint-config-idiomatic-order css排序规则以及插件
// stylelint-config-prettier stylelint-prettier prettier兼容规则以及插件
pnpm install stylelint-config-standard stylelint-config-prettier stylelint stylelint-order stylelint-prettier stylelint-config-idiomatic-order -D 
// 如果需要支持scss需额外添加
pnpm install stylelint-config-standard-scss --save-dev 
.stylelintrc.js
  • 根目录创建.stylelintrc.js文件
// 文件内容
module.exports = {
  extends: ['stylelint-config-standard', 'stylelint-config-idiomatic-order', 'stylelint-prettier/recommended'],
  plugins: ['stylelint-order'],
  rules: {},
};
settings.json
  • stylelint 需额外配置vscode 全局参数
// settings.json
{
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "prettier.configPath": ".prettierrc",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": false,
    // 主要是这一行是关键,默认保存使用stylelint做格式化
    "source.fixAll.stylelint": true
  },
  "stylelint.validate": [
    "css",
    // 如果需要格式化scss 就需要在这里添加scss
    "scss",
    "less",
    "postcss"
  ],
  "editor.cursorBlinking": "expand",
  "editor.cursorSmoothCaretAnimation": true,
  "workbench.editor.wrapTabs": true,
  "workbench.editor.highlightModifiedTabs": true,
  "editor.rename.enablePreview": false,
  "workbench.editor.enablePreviewFromQuickOpen": true,
  "workbench.editor.showTabs": true,
  "editor.renderWhitespace": "all",
  "diffEditor.ignoreTrimWhitespace": false,
  "settingsSync.ignoredExtensions": [],
  "workbench.editor.enablePreview": false,
  "editor.formatOnSave": true
}
stylelint 格式化Vue文件
// 需要指定对应的代码解析工具
stylelint **/*.vue --custom-syntax postcss-html --fix

// stylelint 也支持webpack打包时进行代码格式化
// stylelint-webpack-plugin

new StyleLintPlugin({
  // 这里也是需要指定对应的代码解析工具的,不然会出现不认识文件中的格式错误
  customSyntax: 'postcss-html',
  files: ['**/*.{vue,html,css,scss,sass,less}'],
  failOnError: false,
  cache: true,
  fix: true,
}),
prettier
pnpm install prettier eslint-config-prettier eslint-plugin-prettier -D
  • 在.eslintrc 中,extend中添加 "prettier" 解决 eslint 和 prettier 的冲突

  • 因为eslint-config-prettier新版本更新之后,只需要写一个 "prettierr" 即可,无需多言指令

  • 截屏2022-06-20 上午10.16.39.png

  • 创建 .prettierrc

{
  "printWidth": 400,
  "tabWidth": 2,
  "singleQuote": true,
  "semi": true
}

hooks工具

husky
  • 初始化husky 会生成husky目录
  • husky hooks 脚本特性,识别到exit 1 就会停止往下运行
npm i lint-staged husky -D 

npm set-script prepare "husky install" 

# 在package.json中添加脚本 

npm run prepare 

# 初始化husky,将 git hooks 钩子交由,husky执行
  • 截屏2022-06-20 上午10.41.27.png
lint-staged
  • 添加对应钩子的执行命令
// 命令会在husky下生成pre-commit脚本文件
npx husky add .husky/pre-commit "npx lint-staged"
  • 添加lint-staged配置文件
    • 方法一
    • 根目录创建  .lintstagedrc.json 文件控制检查和操作方式
    • 方法二
    • 在package.json 文件中添加对应配置
.lintstagedrc.json
{
    "*.{js,jsx,ts,tsx}": ["prettier --write .", "eslint  --fix"],
    "*.md": ["prettier --write"]
}
package.json
// 添加下面这一段才行
  "lint-staged": {
    "**/*.js": [
      "npm run test"
    ],
    "**/*.{js,jsx,tsx,ts,less,md,json}": [
      "prettier --write"
    ]
  },
commitlint
// 一个是校验工具,一个是校验工具的配置参数
pnpm install commitlint @commitlint/config-conventional -D 
commitlint.config.js
  • 添加配置文件
    • 根目录创建   commitlint.config.js 文件

    • 将执行命令添加到husky中

    • npx husky add .husky/commit-msg 'npx --no-install commitlint --edit ""'

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

@commitlint/config-conventional 配置文件中一些常用的验证类型

类型描述
build编译相关的修改,例如发布版本、对项目构建或者依赖的改动
chore其他修改, 比如改变构建流程、或者增加依赖库、工具等
ci持续集成修改
docs文档修改
feat新特性、新功能
fix修改bug
perf优化相关,比如提升性能、体验
refactor代码重构
revert回滚到上一个版本
style代码格式修改, 注意不是 css 修改
test测试用例修改
cz-customizable
  • cz-customizable这个包最开始是作为commitizen 插件,但是现在也可以独立运行
  • 还有一种方法 配置commitizencz-customizable用作插件
  • 这种方法有点麻烦,可参考官网 github.com/leoforfree/…
  • 独立运行只需要一条命令
"scripts" : {
  ...
  "commit": "./node_modules/cz-customizable/standalone.js"
}
  • 将这个工具加入到git hooks事件中
npx husky add .husky/prepare-commit-msg 'exec < /dev/tty && npm run commit'
  • 但是这里有个问题,因为他是在commitlint之前执行的
  • 所以没法先验证用户输入是否正确,再进行提示,就会每次不管对错都会提示,这明显不合理
  • 所以我们需要对prepare-commit-msg hooks进行改造一下
npx commitlint --edit $1 > /dev/null && exit 0
if [ $? -ne 0 ]; then
exec < /dev/tty && pnpm run commit || true
else
echo ""
fi
.cz.config.js
  • cz-customizable工具 根目录必须有个.cz.config.js的配置文件
  • 下面是书写格式
  types: [
    { value: 'init', name: 'init: 初始提交' },
    { value: 'feat', name: 'feat: 增加新功能' },
    { value: 'fix', name: 'fix: 修复bug' },
    { value: 'ui', name: 'ui: 更新UI' },
    { value: 'refactor', name: 'refactor: 代码重构' },
    { value: 'release', name: 'release: 发布' },
    { value: 'deploy', name: 'deploy: 部署' },
    { value: 'docs', name: 'docs: 修改文档' },
    { value: 'test', name: 'test: 增删测试' },
    { value: 'chore', name: 'chore: 更改配置文件' },
    { value: 'style', name: 'style: 样式修改不影响逻辑' },
    { value: 'revert', name: 'revert: 版本回退' },
    { value: 'add', name: 'add: 添加依赖' },
    { value: 'minus', name: 'minus: 版本回退' },
    { value: 'del', name: 'del: 删除代码/文件' },
  ],
  scopes: [],
  // 此处是排除不需要的步骤
  skipQuestions: ['scope', 'body', 'breaking', 'footer'],
  messages: {
    type: '选择更改类型:\n',
    // scope: '更改的范围:\n',
    // 如果allowcustomscopes为true,则使用
    // customScope: 'Denote the SCOPE of this change:',
    subject: '简短描述:\n',
    // body: '详细描述. 使用"|"换行:\n',
    // breaking: 'Breaking Changes列表:\n',
    // footer: '关闭的issues列表. E.g.: #31, #34:\n',
    confirmCommit: '确认提交?',
  },
  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix'],
};
参考仓库
https://gitee.com/tang_peng1/ts-lint-demo.git
init 分支