ESLint 处处可见,已是必不可少的一环,只是在将 ESLint 集成到开发环境中时,对 ESLint 需更多的理解。
ESLint
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs —— ESLint official website
ESLint 是一个基于 ECMAScript/JavaScript 代码模式识别和报告的工具,用于确保代码的一致性和正确性。
安装和使用
先决条件:Node.js (^8.10.0, ^10.13.0,或>=11.10.1)使用SSL支持构建的。(如果使用的是一个正式的Node.js发行版,SSL总是内置的。)
本地安装和使用
如果想将 ESLint 作为项目构建框架的一部分,推荐本地安装。
1 | npm install eslint --save-dev |
初始化 ESLint,创建一个 ESLint 配置文件1
./node_modules/.bin/eslint --init
运行 ESLint 检测代码1
./node_modules/.bin/eslint yourfile.js
另外,也可以使用 npx。1
npx eslint yourfile.js
全局安装和使用
如果不想在每个项目都单独安装 ESLint,又希望每个项目都能使用 ESLint。可以将 ESLint 安装在全局环境中。
1 | npm install -g eslint |
初始化 ESLint,并创建一个 ESLint 配置文件。1
eslint --init
运行 ESLint 检测代码1
eslint yourfile.js
注意: ESLint 的任何插件或共享配置文件必须与 ESLint 安装环境保持一致。即如果 ESLint 是本地安装(或全局安装),相关的插件和共享配置文件也要相应地安装在本地(或全局)。如果混合安装可能导致 ESLint 不能正常工作,这与 Node 模块查询机制有关。
ESLint 配置
在运行 eslint --init
后,在当前目录会新创建一个 .eslintrc
配置文件。假如文件内容如下所示1
2
3
4
5
6
7{
"rules": {
"eqeqeq": "off",
"semi": 0,
"quotes": ["error", "double"],
}
}
"semi"
和 "quotes"
是 ESLint 的规则名,取值可以是下面任何一个值:
"off"
或0
:关闭规则。"warn"
或1
:开启规则。如果规则匹配会提示警告,但不会退出当前进程。"error"
或2
:开启规则。如果规则匹配会报错,并退出当前进程。
当规则提供了额外的配置选项,就需要使用数组形式使用。如"quotes": ["error", "double"]
,数组第一个元素永远是规则的取值("error"
),其他元素则是该规则特有的配置选项("double"
)。
除了可以在配置文件中定制规则外,还可以通过如下方式
注释方式定制:
1
/* eslint eqeqeq: "off", curly: "error" */
或
1
/* eslint eqeqeq: 0, curly: 2 */
上述两种方式完全对等。如果需要定制额外配置选项:
1
/* eslint quotes: ["error", "double"], curly: 2 */
package.json
1
2
3
4
5
6
7
8
9
10
11{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"]
}
}
}
ESLint 配置文件支持如下格式:
- JavaScript
- YAML
- JSON
- package.json
如果在同一个目录同时存在多个配置文件,ESLint 会按如下优先级使用优先级高者。
- .eslintrc.js
- .eslintrc.yaml
- .eslintrc.yml
- .eslintrc.json
- .eslintrc(格式为JSON/YAML)
- package.json
配置的叠层关系
假如有个 app,目录结构如下所示:
1 | ├─┬ app |
app/.eslintrc
配置文件会作用 app/
下的所有文件。其中 app/tests/test.js
由 app/tests/.eslintrc
和 app/.eslintrc
共同作用,而 app/tests/.eslintrc
的优先级较高。
ESLint 默认情况下会从当前的目录逐级向上查找配置文件,直到用户根目录为止。这对于想要将所有项目都统一遵循一套代码风格是很有益处的,只需在用户根目录下添加一个配置文件即可(~/.eslintrc
)。但有时可能又不想要这种行为,为了将 ESLint 限制在特定的项目中,可以在配置文件中添加"root": true
即可。这样 ESLint 在寻找配置文件时,如果发现配置文件中存在该配置项,就不会再继续向上查找了。
假如有个 projectA 项目。目录结构如下:1
2
3
4
5
6
7
8home
└── user
├── .eslintrc <- Always skipped if other configs present
└── projectA
├── .eslintrc <- Not used
└── lib
├── .eslintrc <- { "root": true }
└── main.js
这里对 projectA/lib/.eslintrc
设置了 "root": true
配置项。这样在 ESLint 分析 projectA/lib/main.js
时,仅仅 projectA/lib/.eslintrc
配置文件生效,而 projectA/.eslintrc
是没作用的。更多……
plugins
如果需要定制的规则来自第三方插件,首先需要先配置插件。在配置时需要将插件名中的 eslint-plugin-
前缀去掉。
1 | { |
然后再定制插件规则。这里需要以 插件名/规则名
形式作为定制规则名,同样也需要将插件名中的 eslint-plugin-
前缀去掉。因为 ESLint 在定位规则插件时,只会使用无前缀的插件名进行匹配。1
2
3
4
5
6
7
8{
"plugins": [
"plugin1" // 插件 eslint-plugin-plugin1
],
"rules": {
"plugin1/rule1": "error"
}
}
关闭规则
ESLint 提供了多种关闭规则的方式。
- 注释方式
1 | /* eslint-disable */ |
1 | /* eslint-disable no-alert */ |
1 | alert('foo'); // eslint-disable-line |
1 | alert('bar'); // eslint-disable-line no-alert |
.eslintrc
配置文件1
2
3
4
5{
"rules": {
"no-alert": "off",
}
}package.json
1
2
3
4
5
6
7
8
9{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"rules": {
"no-alert": "off",
}
}
}关闭特定文件的规则
1
2
3
4
5
6
7
8
9
10
11{
"rules": {...},
"overrides": [
{
"files": ["*-test.js","*.spec.js"], // 指定需要关闭规则的文件
"rules": {
"no-unused-expressions": "off" // 关闭的规则
}
}
]
}关闭插件
eslint-plugin-example
的rule-name
规则1
2foo(); // eslint-disable-line example/rule-name
foo(); /* eslint-disable-line example/rule-name */
Parser
ESLint 默认只会处理 ECMAScript 5。如果需要支持其他 ECMAScript 版本,可以通过 parserOptions
选项来指定。
1 | { |
env
如果想要使用 ES6 的 Set
、Map
,就需要指定 es6
执行环境。ESLint 提供了很多常见的执行环境:
- browser
- node
- commonjs
- es6
- amd
- 更多……
1 | { |
使用第三方插件提供的执行环境:1
2
3
4
5
6{
"plugins": ["example"], // example 插件
"env": {
"example/custom": true
}
}
global
如果访问没有被定义的全局变量,no-undef 规则就会警告它们的使用。此时可以通过如下方式解决:1
2
3
4
5
6
7{
"globals": {
"var1": "writable", // var1 可以读写
"var2": "readonly" // var2 仅可读
"var3": "off" // var3 不可读写
}
}
或1
/* global var1:writable, var2, var3: off*/
由于历史原因,如下对 var1
、var2
的设置效果完全相同。1
2
3"var1": "writable",
"var1": "writable",
"var1": true,
1 | "var2": "readonly", |
extends
如果不知道怎么定制一套属于自己的代码风格,可以基于一些现有的代码风格进行定制。
扩展主流的代码风格
1 | { |
使用 rules
配置项定制专属代码风格1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"extends": [
"Airbnb",
],
"rules": {
// enable additional rules
"indent": ["error", 4],
"eqeqeq": "warn",
// override default options for rules from base configurations
"quotes": ["error", "single"],
// disable rules from base configurations
"no-console": "off",
}
}
rules
选项可能会继承或重写 extends
规则:
继承规则
extends
规则:"eqeqeq": ["error", "allow-null"]
rules
规则:"eqeqeq": "warn"
- 最终规则:
"eqeqeq": ["warn", "allow-null"]
重写规则
extends
规则:"quotes": ["error", "single", "avoid-escape"]
rules
规则:"quotes": ["error", "single"]
- 最终规则:
"quotes": ["error", "single"]
扩展来自第三方插件的代码风格1
2
3
4
5
6
7
8
9
10
11
12{
"plugins": [
"react"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended" // react 插件的 recommended
],
"rules": {
"no-set-state": "off"
}
}
.eslintignore
可能存在希望 ESLint 在工作时,忽略掉特定文件或目录。此时可以在项目根目录创建一个 .eslintignore
文件,然后在文件添加需要忽略掉的文件或目录即可。ESLint 默认会忽略掉/node_modules/*
和 /bower_components/*
。1
2
3
4
5# /node_modules/* and /bower_components/* in the project root are ignored by default
# Ignore built files except build/index.js
build/*
!build/index.js # negated pattern
在 package.json
中配置
1 | { |
ESLint 在执行后,如果存在错误或警告。可以在 ESLint 执行时增加 --fix
选项来自动修复。但并不是所有错误或警告都能修复。只有规则前有个 🔧 才能被修复,More……
ESLint + IDE
这里以 Visual Studio Code 为例讲解,其他可以参考官方相关介绍。
要将 ESLint 集成到 Visual Studio Code 中,需要依赖 vscode-eslint 插件。集成步骤如下:
- 安装 ESLint(全局或本地)
- 安装 vscode-eslint 插件
- 创建
.eslintrc.*
配置文件
如果不想手动修复 ESLint 报出的错误,可以配合格式化工具自动修复(只能修复规则前有个 🔧 的规则,其他错误还需手动修复)。这里以 prettier 为例。
- 安装 vscode 插件 prettier-vscode