配置文件格式

在 ESLint 中,支持如下格式的配置文件:

如果在项目的同一目录下存在多种格式的配置文件,那么这些配置文件之间是有一个优先级顺序的。顺序如下:

  1. .eslintrc.js
  2. .eslintrc.cjs
  3. .eslintrc.yaml
  4. .eslintrc.yml
  5. .eslintrc.json
  6. package.json

在早期的时候(v7.0.0 之前),ESLint 支持使用 .eslintrc 文件来作为 ESLint 的配置文件,但是从 v7.0.0 开始,官方就已经明确废弃掉这种用法,从 v7.0.0 之后,就建议使用上述的格式来作为 ESLint 的配置文件。但是为了兼容性,之前的 .eslintrc 格式的配置文件依然能够使用,但是还是建议最好使用官方推荐的格式来进行配置。

[[#配置文件的书写|v9.0.0 推荐 eslint.config.js]]

使用配置文件

想让配置文件生效,有两种方式:

对 ESLint 进行配置有多种方式,优先级顺序从高到低如下:

配置文件的层叠

在 ESLint 中支持配置文件的层叠,这是一种管理项目中多个配置文件的方式,这种特性允许在项目中根据不同的部分应用不同的规则。

例如在 src/.eslintrc.js 中,有如下的配置:

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  rules: {
    semi: ['error', 'always']
  }
};

那么现在,就存在两份 ESLint 的配置,此时 ESLint 会在当前目录下查找配置文件,然后会一层一层往上寻找,将找到的所有的配置文件进行一个规则合并。

如果子目录下配置文件的规则和父目录下的配置文件规则发生重合,那么子目录下的配置文件规则会覆盖父目录下配置文件的同名规则。

如果需要就应用当前目录的配置文件,不要再往上找了,那么可以在当前的配置文件中添加一个 root:true,添加了此配置项后,表示就应用当前目录下找到的配置文件,停止继续往上搜索。

扩展配置文件

这里所谓的扩展,实际上更准确的来讲,叫做继承。

{
  "extends": "eslint:recommended",
  "rules" : {
    "no-console": "warn"
  }
}

在上面的配置中,extends 对应的值为 eslint:recommended,表示采用 ESLint 团队推荐的规则规范。在继承了 eslint:recommended 规则规范的基础上进行了额外的配置。

在进行原有配置规则上扩张,有一个细节的问题:

{
  "extends": "eslint:recommended", // "eqeqeq": ["error", "allow-null"]
  "rules" : {
    "eqeqeq": "warn"
  }
}

在上面的扩展中,修改了 eqeqeq 这条规则的重要性(从 error 修改为了 warn),当修改规则重要性的时候,原本的配置选项会保留,也就是说,上面关于 eqeqeq 这条规则,最终会变为:

"eqeqeq": ["warn", "allow-null"]

但是如果更改的是配置选项,那么则是完全覆盖:

{
  "extends": "eslint:recommended", // "quotes": ["error", "single", "avoid-escape"]
  "rules" : {
    "quotes": ["error", "double"]
  }
}

另外关于 extends 对应的值还可以是一个数组,相同规则后面覆盖前面:

{
    "extends": [
        "./node_modules/coding-standard/eslintDefaults.js",
        "./node_modules/coding-standard/.eslintrc-es6",
        "./node_modules/coding-standard/.eslintrc-jsx"
    ],
    "rules": {
        "quotes": "warn"
    }
}

局部重写

有些时候需要对配置进行更加精确的控制,例如都是在同一个目录下,不同的文件使用不同的配置,这种情况下就可以使用局部重写(overrides):

{
  "rules": {
    "quotes": ["error", "double"]
  },
  "overrides": [
    {
      "files": ["bin/*.js", "lib/*.js"],
      "excludedFiles": "*.test.js",
      "rules": {
        "quotes": ["error", "single"]
      }
    }
  ]
}

overrides 对应的值是一个数组,意味着可以有多个配置项,当多个配置项之间匹配上了相同的文件,那么以后面的配置项为准。

overrides 是支持嵌套,例如:

{
  "rules": {
    "quotes": ["error", "double"]
  },
  "overrides": [
    {
      "files": ["lib/*.js"],
      "rules": {
        "quotes": ["error", "single"]
      },
      "overrides": [
        {
          "files": ["util.js"],
          "rules": {
            "quotes": ["error", "double"]
          },
        }
      ]
    }
  ]
}

配置文件的书写

从 v9.0.0 开始,官方推荐的配置文件格式为 eslint.config.js,并且支持 ESM 模块化风格:

export default [
    {
        rules: {
            semi: "error",
            "prefer-const": "error"
        }
    }
];

之所以导出的是一个数组,是为了支持项目中不同的文件或者文件类型定义不同的规则。

例如,项目里面既有 JS 代码,也有 TS 代码,可能想要针对不同的代码类型配置不同的 ESLint 检查规则,就可以这样写:

export default [
  {
    files: ["*.js"],
    rules: {
      "no-var": "error"
    }
  },
  {
    files: ["*.ts"],
    rules: {
      "@typescript-eslint/no-var": "error"
    }
  }
];

如果在 package.json 里面没有指定 type: module,那么就代表使用 CommonJS 规范,那么 ESLint 配置文件在做模块导出的时候,也需要使用 CommonJS 模块规范:

module.exports = [
    {
        rules: {
            semi: "error",
            "prefer-const": "error"
        }
    }
];

配置对象的选项

globals

指定在 Linting 过程中添加到全局作用域的额外对象,例如指定全局下有 var1 可写变量和 var2 只读变量:

export default [
    {
        files: ["**/*.js"],
        languageOptions: {
            globals: {
                var1: "writable",
                var2: "readonly"
            }
        }
    }
];

parser

解析器,作用是负责将源码解析为抽象语法树。ESLint 默认使用的解析器为 Espree,但是可以指定其他的 parser,parser 需要是一个对象,该对象里面包含了 parse 或者 parseForESLint 方法:

import babelParser from "@babel/eslint-parser";

export default [
    {
        files: ["**/*.js", "**/*.mjs"],
        languageOptions: {
            parser: babelParser
        }
    }
];

processor

处理器,主要用于处理 ESLint 默认不能够处理的文件类型。举个例子,假设有一个 markdown 类型的文件,里面有一些 JS 代码,默认这些 JS 代码是不能够被 ESLint 处理的,通过添加额外的处理器,让 ESLint 能够对这些格式的文件进行 Lint 检查:

import markdown from "eslint-plugin-markdown";

export default [
    {
        files: ["**/*.md"],
        plugins: {
            markdown
        },
        processor: "markdown/markdown",
        settings: {
            sharedData: "Hello"
        }
    }
];