ESLint 学习笔记 - 配置

配置文件

有四种方式来添加配置信息:

  • 在源代码中添加配置信息的注释
  • 在命令行中通过参数来添加配置信息
  • 在 package.json 文件中的 eslintConfig 字段添加配置信息
  • 创建单独的配置文件(推荐)

配置文件的格式:

  • JavaScript - 使用 .eslintrc.js 然后输出一个配置对象
  • YAML - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构
  • JSON - 使用 .eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释
  • (弃用) - 使用 .eslintrc,可以使 JSON 也可以是 YAML
  • package.json - 在 package.json 里创建一个 eslintConfig 属性,在那里定义你的配置

配置文件的查找顺序:

当使用配置文件或 package.json 配置 ESLint 的时候,会一层层地叠加使用配置文件。ESLint 将自动在待检测的代码所在的目录里寻找它们,紧接着是父级目录,一直到文件系统的根目录(除非指定 root: true)。ESLint 会将找到的所有配置文件的配置信息合并使用。推荐在项目根目录中的配置文件中设置 "root": true,表明找到该配置文件之后,就不要再继续向上级目录查找配置文件了。通过这种方式,你可以有项目级 ESLint 设置,也有覆盖特定目录的 ESLint 设置。

层叠使用配置文件的例子

忽略文件

当 ESLint 作用于一个目录时,支持使用 .eslintignore 文件来列出一些不需要被 ESLint 检测的文件。.eslintignore 文件是个纯文本文件,可以放在待检测目录的任何父级目录,它将影响到 .eslintignore 文件所在的目录和所有子目录。

与配置文件不同,.eslintignore 文件不会被叠加查找,ESLint 在找到一个 .eslintignore 文件时候就会停止查找上级目录,因此推荐在项目根目录中创建 .eslintignore 文件。

ESLint 会自动忽略 .eslintignore 文件所在目录中的 node_modules 目录和 bower_components 里面的所有代码的检测。把下面 .eslintignore 文件放到项目根目录里,将忽略项目根目录下的 node_modules,bower_components 以及 build/ 目录下除了 build/index.js 的所有文件。

其实不管是否创建 .eslintignore 文件,都会忽略执行 eslint 命令所在目录的 node_modules 目录和 bower_components 里面的所有代码的检测。

# 忽略 build 目录下的除了 index.js 之外的所有文件的代码检测
build/*
!build/index.js

parser

指定 js 语法解析器,默认使用 espree 解析器。下面的配置指定了 esprima 作为解析器:

{
    "parser": "esprima"
}

parserOptions

指定 js 语法解析选项

{
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        }
    }
}

ecmaVersion

指定待检测的代码中语法所使用的 ECMAScript 版本。

  • "ecmaVersion": 5 默认值,使用 ECMAScript 5
  • "ecmaVersion": 6 使用 ECMAScript 6
  • "ecmaVersion": 2017 使用 ECMAScript 2017
  • "ecmaVersion": "latest" 使用 ECMAScript 最新版本

通过设置 "ecmaVersion": 6 只是告诉 ESLint 待检测的代码中使用了 ES6 的语法,并没有告诉 ESLint 待检测的代码中使用了 ES6 的 API(例如 Set Map Promise 等 ES6 新添加的全局对象以及全局对象的属性、实例对象的原型属性)。通过 "env": { "es6": true } 选项可以告诉 ESLint 代码中使用了 ES6 的 API。

设置 "env": { "es6": true },会自动开启 "ecmaVersion": 6,但是设置 "ecmaVersion": 6 不会自动开启 "env": { "es6": true }

sourceType

指定待检测的代码是如何使用的,是作为 <script> 脚本加载的,还是作为 ES6 模块使用的。

  • "sourceType": "script" 默认值,作为 <script> 脚本
  • "sourceType": "module" 作为 ES6 模块

ecmaFeatures

指定你想使用的额外的语言特性,并不常用。

env

指定待检测的代码的应用环境,每个环境定义了一组预定义的全局变量,常用的环境包括:

  • browser 浏览器环境中的全局变量
  • node Node.js 全局变量和 Node.js 作用域
  • commonjs CommonJS 全局变量和 CommonJS 作用域
  • es6 启用除了 modules 以外的所有 ECMAScript 6 API
  • jquery jQuery 全局变量

这些环境并不是互斥的,所以你可以同时定义多个。通过以下配置指定了待检测的代码将要运行的环境是浏览器环境和 Node.js 环境,因此当代码中使用了浏览器或 Node.js 的全局变量的时候,不会报错。

{
    "env": {
        "browser": true,
        "node": true
    }
}

设置 "env": { "es6": true },会自动开启 "parserOptions": { "ecmaVersion": 6 },也就是说如果待检测的代码中使用了 ES6 的语法和 API,则只需要设置 "env": { "es6": true } 就可以了。

module.exports = {
    "parserOptions": {
        "sourceType": "module",
        // 以下这行可以不设置
        // "ecmaVersion": 6
    },
    "env": {
        // 告诉 ESLint 待检测的代码同时使用了 ES6 的语法和 API
        "es6": true
    }
}

经过测试发现,即使不设置 env: { es6: true },代码里面使用 ES6 的 API,也不会提示错误。

globals

指定待检测的代码中可以使用的全局变量。当代码中使用未定义的变量时会报错,如果你想在待检测的代码里使用全局变量,需要通过 globals 设置。

{
    "globals": {
        "var1": "writable",
        "var2": "readonly",
        "Promise": "off"
    }
}

在待检测的代码中可以使用 var1 以及 var2 变量,不会被警告。var1 可读写,var2 只读。
在待检测的代码中禁用 Promise 全局变量,如果使用 Promise 会报错。

plugins

ESLint 支持使用第三方插件。在使用插件之前,你必须使用 npm 安装它。

通过 plugins 指定使用的插件列表,插件名称可以省略 eslint-plugin- 前缀

{
    "plugins": [
        "plugin1",
        "eslint-plugin-plugin2"
    ]
}

processor (不常用)

插件可以提供处理器。处理器可以从另一种文件中提取 JavaScript 代码,然后让 ESLint 检测 JavaScript 代码。或者处理器可以在预处理中转换 JavaScript 代码。

通过 processor 指定处理器,格式为 插件名/处理器名

{
    "plugins": ["a-plugin"],
    "processor": "a-plugin/a-processor"
}

rules

通过设置一条条的规则,指定了代码应该遵守的书写风格,即代码规范。

ESLint 检测包括两个方面:

  • 语法检测:检测代码中的语法是否符合 parserOptions 选项设置的语法。
  • 规则检测:检测代码中的书写风格是否遵循 rules 设置的规范。如果没有指定 rules 选项,则 ESLint 只对代码进行语法检测。

一个规则可以设置为下列值之一:

  • "off" 或 0 - 关闭规则
  • "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

如果一个规则有额外的选项,你可以使用数组字面量指定它们:

{
    "rules": {
        "eqeqeq": "off",
        "curly": "error",
        "quotes": ["error", "double"]
    }
}

通过注释禁止规则检测

在代码中可以通过注释来禁止/开启对配置文件中设置的规则进行检测。不管禁不禁止规则检测,语法检测都会进行。

禁止一行代码的规则检测

/* eslint-disable-next-line */
alert('foo')

禁止一块代码的规则检测

/* eslint-disable */

alert('foo');

/* eslint-enable */

禁止整个文件范围的规则检测

/* eslint-disable */

alert('foo');

禁止具体某个规则的检测

/* eslint-disable no-alert */

alert('foo');

禁止具体多个规则的检测

/* eslint-disable-next-line no-alert, quotes, semi */
alert('foo');

通过 overrides 禁止一组文件的某个规则检测

通过 overrides.files 指定一组文件,关闭这组文件的 no-unused-expressions 规则检测。

{
  "rules": {},
  "overrides": [
    {
      "files": ["*-test.js", "*.spec.js"],
      "rules": {
        "no-unused-expressions": "off"
      }
    }
  ]
}

extends

我们的配置文件可以从其他地方继承一些配置信息,然后在本配置文件里修改继承的配置信息。

extends 继承的配置信息的来源可以是以下几个方面:

  • eslint:all
  • eslint:recommended
  • 从配置文件继承配置信息
  • 从共享的配置包继承配置信息
  • 从插件继承配置信息

extends 的值可以是字符串,表明从单个来源继承配置信息,以下配置文件只能选择其中一条 extends

const path = require('path')

module.exports = {
    // 启用所有的配置规则选项
    "extends": "eslint:all",
    // 启用推荐的配置规则选项
    "extends": "eslint:recommended",
    // 通过相对路径继承某个配置文件
    "extends": "./config/eslintrc.base.js",
    // 通过绝对路径继承某个配置文件
    "extends": path.resolve(__dirname, 'config/eslintrc.base.js'),
    // 通过模块路径继承某个共享的配置包导出的配置
    "extends": "eslint-config-airbnb",
    // 通过 plugins: 开头的模块路径继承某个插件导出的某个配置
    "extends": "plugin:react/recommended"
}

extends 的值可以是数组,表明从多个来源继承配置信息,后面的配置继承它前面的配置

const path = require('path')

module.exports = {
    extends: [
        "extends": "eslint:recommended",
        "extends": "plugin:react/recommended"
    ]
}

extends 配合 rules 来修改继承的配置。

module.exports = {
    "extends": "eslint:recommended",
    "rules": {
        // 增加四条 eslint:recommended 里面没有的规则
        "indent": ["error", 4],
        "linebreak-style": ["error", "unix"],
        "quotes": ["error", "double"],
        "semi": ["error", "always"],

        // 覆盖从 eslint:recommended 继承的 comma-dangle 和 no-cond-assign 规则的默认选项
        "comma-dangle": ["error", "always"],
        "no-cond-assign": ["error", "always"],

        // 删除从 eslint:recommended 继承的 no-console 规则
        "no-console": "off",
    }
}

以上配置文件在继承的 eslint:recommended 配置规则的基础上,通过 rules 来对继承的规则进行调整:例如增加规则、修改规则、删除规则。

eslint:all

启用当前安装的 ESLint 中所有的核心规则,不推荐。每个 ESLint 小版本更新的时候,都有可能导致某个规则发生了变化。如果我们的代码是按照 ESLint 版本更新之前的规则书写的,那么即使以前不会报错的代码,现在用新的规则检测的时候有可能会报错。

{
    "extends": "eslint:all"
}

eslint:recommended

启动 ESLint 推荐的的 rule 配置,位于 规则页面 中被标记为✔️ 的 rule 将会启动。只有在 ESLint 主要版本进行更新的时候,这个规则子集才会更新。因此只要我们不更新 ESLint 的主版本,那么以前能够通过验证的代码,现在也能通过验证。

{
    "extends": "eslint:recommended"
}

从配置文件继承配置信息

extends 指向一个配置文件,从该配置文件继承配置信息。配置文件的路径可以使绝对路径,也可以是相对路径。

{
  "extends": "./config/eslintrc.base.js"
}

从配置包继承配置信息

配置包是一个 npm 包,它输出一个配置对象。例如 eslint-config-airbnb 包就是一个配置包,它是 airbnb 公司的代码规范。extends 后面跟着模块路径就可以继承该配置包的配置信息。

npm i -D eslint-config-airbnb
{
  "extends": "eslint-config-airbnb"
}

推荐的配置包

eslint-config-standard
eslint-config-airbnb

2022 年 4 月份,使用 eslint-config-standard 则推荐 eslint@7 不要安装 eslint@8,而且还需要安装几个 npm 包:

2022 年 6 月份,使用最新版本的 eslint-config-standard 安装 eslint@8 即可,而且还需要安装几个 npm 包:

  "devDependencies": {
    "eslint": "^7.32.0",
    "eslint-config-standard": "^16.0.3",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^5.2.0"
  }

从插件继承配置信息

插件是一个 npm 包,通常输出规则。一些插件也可以输出一个或多个命名的配置。

extends 属性值可以由以下组成:plugin:插件名(没有前缀)/配置名

npm i -D eslint-plugin-react
{
    "plugins": [
        "eslint-plugin-react"
    ],
    "extends": "plugin:react/recommended"
}

overrides

对指定的文件应用定制的配置信息。大部分可以在配置文件中的配置项都可以在 overrides 里面进行配置,除了 root: true 配置项。

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

以上配置文件对普通的待测文件指定了 "quotes": ["error", "double"] 这条规则,也就是字符串必须使用双引号,而不能使用单引号,否则报错。而对于 bin 目录和 lib 目录中的不以 .test.js 结尾的其他文件,应用 "quotes": ["error", "single"] 这条规则,也就是字符串必须使用单引号而不是双引号,否则报错。

说白了,overrides 通过指定一些待测文件,然后为这些文件定制一些配置信息来覆盖普遍的配置信息。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容