目录

什么是 lint-staged?

为什么使用 lint-staged?

核心功能

1. 只对暂存区文件运行检查

2. 与 husky 集成

安装和配置

1. 安装依赖

2. 初始化 husky 配置

3. 配置 lint-staged

4. 配置 husky 钩子

进阶配置

1. 多个文件类型

2. 运行自定义命令

3. 对多个文件同时运行多个命令

4. 缓存机制

常见问题与解决方案

1. 检查命令未生效

2. 命令执行失败

3. 如何禁用某些文件检查

优势

小贴士


什么是 lint-staged

lint-staged 是一个用于在 Git 暂存区的文件上运行代码检查(linting)工具的工具。它通过只对已经暂存(即通过 git add)的文件进行操作,减少了不必要的工作量,提升了开发效率和代码质量。

通常与 husky 配合使用,husky 用来在特定的 Git 钩子(如 pre-commit)中执行 lint-staged,确保在提交代码之前自动进行代码检查。

为什么使用 lint-staged

  1. 高效的代码检查:与其他工具不同,lint-staged 只会在提交时对暂存区(即你已通过 git add 的文件)进行操作,避免了无谓的全量检查。
  2. 提高代码质量:通过在每次提交前检查代码,可以减少低质量代码被提交的概率。
  3. 集成流畅:与 husky 等工具结合,能够自动化工作流,减少开发者的手动操作。

核心功能

1. 只对暂存区文件运行检查

lint-staged 仅在已被 git add 暂存的文件上执行检查,而不会浪费时间检查整个项目。这意味着可以高效地在每次提交前检查和修复代码。

2. husky 集成

husky 是一个用于 Git 钩子的工具。与 lint-staged 配合使用时,husky 会在 Git 提交之前(通过 pre-commit 钩子)触发 lint-staged,确保在提交之前进行代码质量检查。


安装和配置

1. 安装依赖

首先,你需要在项目中安装 lint-stagedhusky

npm install lint-staged husky --save-dev
2. 初始化 husky 配置
npx husky install

这会在项目根目录创建一个 .husky 文件夹,并安装必要的 Git 钩子。

3. 配置 lint-staged

package.json 文件中添加 lint-staged 配置,指定哪些文件类型在提交之前需要检查,使用哪些工具进行检查。比如:

 "lint-staged": {
    "src/**/*.{js,vue}": [
      "eslint --fix"
    ]
4. 配置 husky 钩子

你需要在 .husky 文件夹下设置 Git 钩子,告诉 husky 在提交之前运行 lint-staged。添加 pre-commit 钩子:

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

这样,lint-staged 就会在每次 git commit 前被自动执行。


进阶配置

1. 多个文件类型

你可以对不同类型的文件使用不同的 lint 工具和规则。比如:

"lint-staged": {
  "*.js": "eslint --fix",
  "*.css": "stylelint --fix",
  "*.ts": "tsc --noEmit",
  "*.md": "markdownlint"
}

这样,lint-staged 会根据文件扩展名,分别执行不同的工具和命令。

2. 运行自定义命令

lint-staged 允许你运行任何自定义的命令,而不仅仅是 linters。比如,如果你有一个构建工具,可以在提交之前运行它:

"lint-staged": {
  "*.js": "webpack --config webpack.config.js"
}
3. 对多个文件同时运行多个命令

如果你想在一个文件上运行多个命令,可以使用 && 来链接多个命令。例如,先运行 eslint --fix,再运行 jest --bail

"lint-staged": {
  "*.js": "eslint --fix && jest --bail"
}
4. 缓存机制

lint-staged 支持缓存机制,以加速执行。通过使用 --cache 标志,可以避免每次都对文件进行重复的检查。

"lint-staged": {
  "*.js": "eslint --fix --cache"
}

常见问题与解决方案

1. 检查命令未生效

如果 lint-staged 配置的命令没有生效,可以尝试以下几步:

  • 确认 husky 配置正确。你可以检查 .husky/pre-commit 是否包含正确的命令。
  • 确保 lint-staged 配置在 package.json 文件中正确,且没有拼写错误。
2. 命令执行失败

如果某个命令执行失败,lint-staged 会阻止提交。要检查错误,可以在命令行中运行失败的命令,并查看详细的错误信息。

3. 如何禁用某些文件检查

你可以使用 lint-staged--no-staged 参数来跳过暂存区的文件,或通过 .lintstagedrc 文件来排除特定文件或文件夹。


优势

  1. 提升代码质量lint-staged 帮助开发者自动化地在提交前检查和修复代码,确保提交的代码符合质量标准。
  2. 节省时间:与传统的全量检查不同,lint-staged 仅检查暂存的文件,大大提升了速度。
  3. 提高一致性:自动化的代码检查有助于保持团队代码风格的一致性,减少人为差异。

小贴士

  • 多人协作的项目:在团队中使用 lint-staged 能有效避免出现代码风格不一致的问题,确保每个开发者的代码都符合规范。
  • 运行测试:在提交前运行测试可以确保新提交的代码不会破坏现有的功能。
  • prettier 配合:在项目中集成 prettier,可以确保代码格式统一,减少代码审查时的格式问题。

可能需要点第三方库

  • @vue/cli-plugin-eslint:集成 ESLint 到 Vue 项目中。
  • @vue/eslint-config-prettier:禁用与 Prettier 冲突的 ESLint 规则。
  • babel-eslint:支持最新 JavaScript 语法。
  • eslint:核心的 JavaScript 代码检查工具。
  • eslint-config-airbnb-base:Airbnb 风格指南的 ESLint 配置。
  • eslint-plugin-import:确保模块导入语句的正确性。
  • eslint-plugin-prettier:将 Prettier 格式化规则集成到 ESLint 中。
  • eslint-plugin-vue:为 Vue 项目提供 ESLint 检查规则。
   "eslint": "7.15.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-vue": "9.0.0",
   "@vue/eslint-config-prettier": "^5.0.0",
    "babel-eslint": "10.1.0",
    "@vue/cli-plugin-eslint": "^4.5.19",

 

vue2 .eslintrc.js参考规则

// ESLint 检查配置
module.exports = {
  root: true,
  parserOptions: {
    parser: "babel-eslint", // 使用 babel-eslint 解析器
    sourceType: "module", // 使用模块类型
  },
  env: {
    browser: true, // 浏览器环境
    node: true, // Node.js 环境
    es6: true, // ES6 环境
  },
  extends: [
    "plugin:vue/recommended", // Vue.js 推荐规则
    "eslint:recommended", // ESLint 推荐规则
  ],
  // 自定义规则
  // 基于 https://github.com/vuejs/eslint-config-vue
  rules: {
    "vue/singleline-html-element-content-newline": "off", // 禁止单行 HTML 元素强制换行
    "vue/multiline-html-element-content-newline": "off", // 禁止多行 HTML 元素强制换行
    // "vue/name-property-casing": ["error", "PascalCase"], // 强制 Vue 组件名称使用 PascalCase
    "vue/no-v-html": "off", // 允许使用 v-html 指令
    "vue/multi-word-component-names": "off", // 允许组件名称使用多个单词

    // JavaScript 代码规范
    "accessor-pairs": 2, // 强制 getter 和 setter 配对
    "arrow-spacing": [2, { before: true, after: true }], // 强制箭头函数前后空格
    "block-spacing": [2, "always"], // 强制块内空格
    "brace-style": [2, "1tbs", { allowSingleLine: true }], // 强制大括号风格为1tbs
    camelcase: [0, { properties: "always" }], // 禁止 camelCase 规则
    "comma-dangle": [2, "never"], // 禁止尾随逗号
    "comma-spacing": [2, { before: false, after: true }], // 强制逗号后空格
    "comma-style": [2, "last"], // 强制逗号的位置在最后
    "constructor-super": 2, // 强制类构造函数必须调用 super()
    curly: [2, "multi-line"], // 强制多行控制语句使用大括号
    "dot-location": [2, "property"], // 强制点操作符在属性上
    "eol-last": 2, // 强制文件末尾有换行符
    // eqeqeq: ["error", "always", { null: "ignore" }], // 强制使用全等(===)
    "generator-star-spacing": [2, { before: true, after: true }], // 强制生成器函数的星号前后有空格
    "handle-callback-err": [2, "^(err|error)$"], // 回调函数错误参数名检查
    indent: [2, 2, { SwitchCase: 1 }], // 强制缩进为 2 个空格
    "jsx-quotes": [2, "prefer-single"], // 强制使用单引号
    "key-spacing": [2, { beforeColon: false, afterColon: true }], // 强制对象属性的冒号后面有空格
    "keyword-spacing": [2, { before: true, after: true }], // 强制关键字前后有空格
    "new-cap": [2, { newIsCap: true, capIsNew: false }], // 强制构造函数大写
    "new-parens": 2, // 强制 new 时使用括号
    "no-array-constructor": 2, // 禁止使用 Array 构造函数
    "no-caller": 2, // 禁止使用 arguments.callee
    "no-console": "off", // 允许使用 console
    "no-class-assign": 2, // 禁止给类赋值
    "no-cond-assign": 2, // 禁止在条件语句中使用赋值
    "no-const-assign": 2, // 禁止修改 const 声明的变量
    "no-control-regex": 0, // 允许正则表达式中的控制字符
    "no-delete-var": 2, // 禁止删除变量
    "no-dupe-args": 2, // 禁止函数参数重复
    "no-dupe-class-members": 2, // 禁止类成员重复
    "no-dupe-keys": 2, // 禁止对象中出现重复键
    "no-duplicate-case": 2, // 禁止出现重复的 case 标签
    "no-empty-character-class": 2, // 禁止空字符类
    "no-empty-pattern": 2, // 禁止空解构模式
    "no-eval": 2, // 禁止使用 eval
    "no-ex-assign": 2, // 禁止在异常语句中重新赋值
    "no-extend-native": 2, // 禁止扩展原生对象
    "no-extra-bind": 2, // 禁止多余的函数绑定
    "no-extra-boolean-cast": 2, // 禁止多余的布尔值转换
    "no-extra-parens": [2, "functions"], // 禁止多余的括号
    "no-fallthrough": 2, // 禁止 switch 语句的 case 穿透
    "no-floating-decimal": 2, // 禁止浮动的十进制点
    "no-func-assign": 2, // 禁止函数重新赋值
    "no-implied-eval": 2, // 禁止隐式 eval
    "no-inner-declarations": [2, "functions"], // 禁止在内部声明函数
    "no-invalid-regexp": 2, // 禁止无效的正则表达式
    "no-irregular-whitespace": 2, // 禁止不规则的空格
    "no-iterator": 2, // 禁止使用迭代器
    "no-label-var": 2, // 禁止使用标签变量
    "no-labels": [2, { allowLoop: false, allowSwitch: false }], // 禁止使用标签
    "no-lone-blocks": 2, // 禁止不必要的块级作用域
    "no-mixed-spaces-and-tabs": 2, // 禁止混用空格和 Tab
    "no-multi-spaces": 2, // 禁止多余的空格
    "no-multi-str": 2, // 禁止多行字符串
    "no-multiple-empty-lines": [2, { max: 1 }], // 限制空行最多为 1 行
    "no-native-reassign": 2, // 禁止重新赋值原生对象
    "no-negated-in-lhs": 2, // 禁止在左侧使用否定操作符
    "no-new-object": 2, // 禁止使用 Object 构造函数
    "no-new-require": 2, // 禁止使用 new require()
    "no-new-symbol": 2, // 禁止使用 new Symbol()
    "no-new-wrappers": 2, // 禁止使用 new 包装对象
    "no-obj-calls": 2, // 禁止对对象包装器调用
    "no-octal": 2, // 禁止使用八进制字面量
    "no-octal-escape": 2, // 禁止使用八进制转义字符
    "no-path-concat": 2, // 禁止使用路径连接
    "no-proto": 2, // 禁止使用 __proto__
    "no-redeclare": 2, // 禁止变量重新声明
    "no-regex-spaces": 2, // 禁止正则表达式中的空格
    "no-return-assign": [2, "except-parens"], // 禁止返回语句中包含赋值
    "no-self-assign": 2, // 禁止自我赋值
    "no-self-compare": 2, // 禁止自我比较
    "no-sequences": 2, // 禁止使用逗号操作符
    "no-shadow-restricted-names": 2, // 禁止变量名与限定词重名
    "no-spaced-func": 2, // 禁止函数调用前后有空格
    "no-sparse-arrays": 2, // 禁止稀疏数组
    "no-this-before-super": 2, // 禁止在调用 super() 之前使用 this
    "no-throw-literal": 2, // 禁止抛出字面量
    "no-trailing-spaces": 2, // 禁止行尾空格
    "no-undef": 2, // 禁止使用未定义的变量
    "no-undef-init": 2, // 禁止将变量初始化为 undefined
    "no-unexpected-multiline": 2, // 禁止多行代码中出现意外的换行
    "no-unmodified-loop-condition": 2, // 禁止循环条件表达式不变
    "no-unmodified-loop-condition": 2, // 禁止循环条件表达式不变
    "no-unneeded-ternary": [2, { defaultAssignment: false }], // 禁止不必要的三元运算符
    "no-unreachable": 2, // 禁止不可到达的代码
    "no-unsafe-finally": 2, // 禁止在 finally 块中出现不安全的操作
    "no-unused-vars": [2, { vars: "all", args: "none" }], // 禁止未使用的变量
    "no-useless-call": 2, // 禁止无意义的函数调用
    "no-useless-computed-key": 2, // 禁止无用的计算属性键
    "no-useless-constructor": 2, // 禁止无用的构造函数
    "no-useless-escape": 0, // 允许无用的转义字符
    "no-whitespace-before-property": 2, // 禁止属性前有空格
    "no-with": 2, // 禁止使用 with 语句
    "one-var": [2, { initialized: "never" }], // 强制变量声明时不初始化
    "operator-linebreak": [
      2,
      "after",
      { overrides: { "?": "before", ":": "before" } },
    ], // 强制运算符换行
    "padded-blocks": [2, "never"], // 禁止块级语句有内边距
    quotes: [2, "single", { avoidEscape: true, allowTemplateLiterals: true }], // 强制使用单引号
    semi: [2, "never"], // 禁止分号
    "semi-spacing": [2, { before: false, after: true }], // 强制分号后空格
    "space-before-blocks": [2, "always"], // 强制块级代码前有空格
    "space-before-function-paren": [2, "never"], // 强制函数声明时括号前没有空格
    "space-in-parens": [2, "never"], // 强制括号内没有空格
    "space-infix-ops": 2, // 强制运算符两边有空格
    "space-unary-ops": [2, { words: true, nonwords: false }], // 强制一元操作符前有空格
    "spaced-comment": [
      2,
      "always",
      {
        markers: [
          "global",
          "globals",
          "eslint",
          "eslint-disable",
          "*package",
          "!",
          ",",
        ],
      },
    ], // 强制注释后有空格
    "template-curly-spacing": [2, "never"], // 强制模板字符串大括号内没有空格
    "use-isnan": 2, // 强制使用 isNaN 检查 NaN
    "valid-typeof": 2, // 强制使用 typeof 操作符时的合法检查
    "wrap-iife": [2, "any"], // 强制立即调用函数表达式 (IIFE) 使用括号
    "yield-star-spacing": [2, "both"], // 强制在 yield* 表达式两侧加空格
    yoda: [2, "never"], // 强制禁止 "yoda" 条件(即 x === y)
    "prefer-const": 2, // 强制使用 const 声明不变的变量
    "no-debugger": process.env.NODE_ENV === "production" ? 2 : 0, // 在生产环境中禁止使用 debugger
    "object-curly-spacing": [2, "always", { objectsInObjects: false }], // 强制对象内有空格
    "array-bracket-spacing": [2, "never"], // 强制数组括号内没有空格
  },
};
Logo

一站式 AI 云服务平台

更多推荐