【前端工程化】eslint与 git hook相关配置

687 阅读8分钟

eslint

1、安装 eslint

  • 这里安装8版本的 eslint,生成.eslintrc.cjs文件

yarn add eslint@8.6.0 --save-dev

  • 使用yarn eslint --init初始化相关配置,生成类似如下文件eslintrc.cjs

    module.exports = {
      root: true, // ESLint 一旦找到带有 "root": true 的配置,就会停止在父文件夹中查找。
      // 如果是SSR项目,则需要配置node:true
      env: {
        browser: true,
        es2021: true,
      },
      extends: [
        //全部规则默认关闭,这个配置打开推荐规则
        "eslint:recommended",
        //ts
        "plugin:@typescript-eslint/recommended",
        //vue3 语法规则
        "plugin:vue/vue3-essential",
        "plugin:prettier/recommended",
      ],
      overrides: [
        {
          env: {
            node: true,
          },
          files: [".eslintrc.{js,cjs}"],
          parserOptions: {
            sourceType: "script",
          },
        },
      ],
      parserOptions: {
        ecmaVersion: "latest",
        parser: "@typescript-eslint/parser",
        sourceType: "module",
      },
      plugins: ["@typescript-eslint", "vue"],
      rules: {
        // 0 = off, 1 = warn, 2 = error
      },
    };
    
  • 自动安装相关规则

    • eslint:eslint 核心模块
    • eslint-plugin-vue:针对 vue 代码的规则检查
    • prettier:
    • eslint-plugin-prettier:将 prettier 的格式化规则集成到 eslint 中
    • @vue/eslint-config-prettier:将禁用与 prettier 格式化规则冲突的 eslint 规则

安装 9 版本遇到问题:

解决[plugin:vite-plugin-eslint] Could not find config file报错

使用@rollup/plugin-eslint替换

2、eslint常用配置项

  • root:定义根配置

    默认情况下,ESLint 会在所有父级目录中寻找配置文件,一直到根目录。这样可以让所有项目都遵循同一套规则。你也可以将 .eslintrc.cjs 配置文件中的 root 设置为 true,ESLint 一旦发现配置文件中有 root: true,它就会停止在父级目录中寻找。

  • env:定义运行环境

    • browser:浏览器全局变量
    • node:node.js全局变量和 node.js作用域
    • Es6:启用初模块之外的所有 es6 功能
  • rules:检查规则

    规则的值有两种格式:数组和字符串/数字

    • off或者 0:关闭规则,eslint 不对该规则进行检查
    • warn 或者 1:将规则作为警告打开,不影响退出代码。在开发环境下,终端会输出警告信息,但是不会影响功能页面的展示
    • error 或者 2:将规则作为错误打开,触发时退出代码为 1。在开发环境下,终端输出错误信息,浏览器也没也会显示错误信息而不是正常的功能展示
  • plugin:扩展 eslint 内置规则

    eslint-plugin-vue:对 vue 文件的 <template><script> 内容进行检查

    plugins 中的规则默认是未启用的,需要在 rules 中启用相应的规则。 plugins 需要与 rules 结合使用。

    module.exports = {
      // ...
      plugins: ["eslint-plugin-vue"],
      rules: {
        // ... eslint-plugin-vue 的 lint 规则
      },
    };
    
  • extends:集成配置方案,一份配置好的 plugins 和 rules

    比如:eslint-plugin-vue 提供了一个名为 plugin:vue/recommended 的规则包。在 extends 中引用这个规则包相当于启用了一系列的规则

    module.exports = {
      // ...
      extends: ["plugin:vue/recommended"],
      rules: {
        // 此处无需手动一项一项配置 lint 规则,因为插件已经根据 recommended 选项自动设置了预设的规则包
      },
    };
    
  • parser:语法解析器配置

    ESLint 默认使用 Espree 作为其解析器,它仅支持 ES5 语法,不支持实验性语法和非标准语法(如 TypeScript 类型)。但是我们可以配置解析器(parser)以使 ESLint 支持其他语法。例如:

    module.exports = {
      // ...
      parserOptions: {
        parser: "babel-eslint",
      },
    };
    ​
    

3、eslint 常用命令

  • npx eslint:检查文件
  • npx eslint --fix:修复文件
# 仅检查 Vue 文件
npx eslint --ext .vue [目录路径]
​
# 同时检查 JavaScript 和 Vue 文件
npx eslint --ext .js --ext .vue [目录路径]
# or
npx eslint --ext .js,.vue [目录路径]

在 package.json文件中配置

"scripts": {
  ...,
  "lint": "eslint --ext .ts,.js,.vue src",
  "slint": "stylelint "src/**/*.(vue|scss|css|less)"", // stylelint
}

4、配置规则中遇到的问题

  • "no-prototype-builtins": 'error', 直接使用proto属性

    obj.hasOwnProperty('key')
    // 报错:Do not access Object.prototype method 'hasOwnProperty' from target object. eslint(no-prototype-builtins)
    ​
    // 解决:不要从目标对象访问 Object 原型方法,想到一种解决方案——直接找到这个方法,用 call 改变指向调用
    Object.prototype.hasOwnProperty.call(obj, 'key')

    在 JS 中,往往通过改变原型链实现继承。一旦原型链发生改变,原先可以访问到的原型属性、方法便可能无法访问。考虑最极端的情况,若 obj 原先原型链的最顶端是 Object,此时可以通过原型链访问 Object.hasOwnProperty 方法;而若改变后,顶端不再是 Object,那么访问 obj.hasOwnProperty 访问就会得到 undefined。因此,直接从对象访问原型方法,很可能会带来隐藏的 BUG。

    解决方法:直接在 Object 对象上调用其方法,利用 call 改变其 this 指向到我们的目标对象上,即可安全使用 hasOwnProperty 方法了。

  • "no-unused-vars"未使用的变量

    'no-unused-vars': 0// 设置 0 不使用:ts 泛型校验不过去
    // 使用 ts no-unused-vars校验,
    "@typescript-eslint/no-unused-vars": ['error', { 'vars': 'all', 'args': 'after-used', 'ignoreRestSiblings': false }]
    // local作用域内(all 全部),args:none 不检查参数(after-used 后使用)
    

prettier

prettier 是一个代码格式化工具,用于检查代码中格式的问题。

在根目录下创建一个名为.prettier.cjs文件并配置

module.exports = {
  useTabs: true, // 是否使用 tab 进行缩进,默认为 false,表示用空格进行缩进
  tabWidth: 4, // 一个 tab 代表几个空格数,默认为 2
  arrowParens: "avoid", // 箭头函数只有一个参数时是否使用括号,有两个可选值"<always|avoid>",默认为 always
  htmlWhitespaceSensitivity: "ignore",
  trailingComma: "es5", // 是否使用尾逗号,有三个可选值"<none|es5|all>",默认为 all
};
​

1、集成 eslint

安装与 prettier 相关依赖:eslint-plugin-prettier@vue/eslint-config-prettier。提供了plugin:prettier/recommended 的规则包

  • eslint-plugin-prettier:ESLint 插件,该插件用于将 Prettier 的格式化规则集成到 ESLint 中
  • @vue/eslint-config-prettier:ESLint 配置,它将禁用与 Prettier 格式化规则冲突的 ESLint 规则

我们还需要在 .eslintrc.cjs 添加相应的配置:

module.exports = {
  // ...
  extends: ["plugin:prettier/recommended"],
};

plugin:prettier/recommended 需要添加到数组的最后一个元素才能覆盖前面的规则,从而禁用与 Prettier 格式化规则冲突的 ESLint 规则

这个配置相当于

module.exports = {
  // ...
  extends: ["prettier"],
  plugins: ["prettier"],
  rules: {
    "prettier/prettier": "error",
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off",
  },
};
​

2、常用命令

  • npx prettier --write xxx:格式化文件
  • npx prettier --check xxx:检查文件格式

stylelint

用于检查和维护 CSS、SCSS 等样式表的工具

1、安装stylelint

yarn add stylelint stylelint-config-standard-scss stylelint-config-prettier --save-dev
  • stylelint:StyleLint 的核心模块
  • stylelint-config-standard:StyleLint 官方推荐的配置规则
  • stylelint-config-prettier:该配置用于解决 StyleLint 和 Prettier 之间的规则冲突问题。将其放在 extends 数组的最后位置,可以确保覆盖 Prettier 的配置
  • stylelint-scss:该插件是 StyleLint 的 SCSS 扩展,增加了对 SCSS 语法的支持,允许检查和验证 SCSS 文件

2、配置文件

在项目根目录下创建名为 .stylelintrc.cjs 的文件来进行 StyleLint 的配置

module.exports = {
  extends: ["stylelint-config-standard", "stylelint-config-prettier"],
  plugins: ["stylelint-scss"],
  // ...
};

解决报错:Unknown word (CssSyntaxError)Stylelint(CssSyntaxError

在stylelint的配置文件中指定语法为postcss-html

module.exports  =  {
    ...
    customSyntax: "postcss-html", // 启用PostCSS解析HTML
    rules:  {}
};

3、常用命令

  • npx stylelint xx:检查文件
  • npx stylelint --fix xx:修复文件
 "slint": "stylelint "src/**/*.(vue|scss|css|less)"",

commitlint

在使用 Git 提交代码时,通常都需要填写提交说明,也就是 Commit Messag

  • 安装 commitlint:yarn add @commitlint/cli @commitlint/config-conventional --save-dev

  • 配置 commitlint:根目录创建 commitlint.config.js 文件进行配置

    module.exports = {
      extends: ['@commitlint/config-conventional'],
      rules: {
        ...
      }
    }
    
  • 配置规则

    // 校验规则
      "rules": {
        "type-enum": [
          2,
          "always",
          [
            "feat", //新特性、新功能
            "fix", //修改bug
            "docs", //文档修改
            "style", //代码格式修改, 注意不是 css 修改
            "refactor", //代码重构
            "perf", //优化相关,比如提升性能、体验
            "test", //测试用例修改
            "chore", //其他修改, 比如改变构建流程、或者增加依赖库、工具等
            "revert", //回滚到上一个版本
            "build", //编译相关的修改,例如发布版本、对项目构建或者依赖的改动
          ],
        ],
        "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],
      },
    

husky

husky 是一个 githook 工具,在 git 操作之前与之后可设置自动执行的脚本:pre-commit

  • pre-commit:该钩子在键入提交信息前运行。 它用于检查即将提交的快照。如果该钩子以非零值退出,Git 将放弃此次提交,你可以利用该钩子,来检查代码风格是否一致。
  • prepare-commit-msg:该钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 - commit-msg:该钩子接收一个参数,此参数存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。
  • post-commit:该钩子一般用于通知之类的事情。 在上面的钩子中,我们需要关注 pre-commit 和 commit-msg 钩子
  • 安装:yarn add husky --dev

  • 初始化 husky 配置:yarn husky install,执行该命令会创建.husky目录

  • 添加 commit-msg hook

    commit-msg文件中可以配置在 git commit 时对 commit 注释的校验指令

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

    会在 husky 下生成commit-msg 文件,表示在 git commit 前执行一个 npx --no -- commitlint --edit $1 指令,对 commit 的注释进行校验。

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    ​
    npx --no -- commitlint --edit "$1"
    
  • 添加 pre-commit hook

    npx husky add .husky/pre-commit "npx eslint --fix packages/**/*.{ts,js,vue}"
    

    会在 husky 下生成pre-commit文件,文件中可以配置在 git commit 前需要执行的操作

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    ​
    npx eslint --fix package/**/*.{ts,js,vue}