ESLint
ESLint 是一种静态代码分析工具,用于识别 JavaScript 代码中存在的有问题的模式,可以帮助我们写出语法正确,风格统一的代码。
安装以及使用 ESLint
- 我们可以使用 npm 来安装 ESLint,运行
npm install eslint --save-dev
命令安装 ESlint。 - 在项目根目录运行
./node_modules/.bin/eslint --init
命令进行初始化操作,初始化的时候根据命令的提示输入一些基本的设置,确认后会在项目的根目录下面生成一个名字为.eslintrc.*
(这个在初始化的时候可以选择不同的文件格式,json 或者 yaml 都是可以的)的配置文件。如下图所示 - 安装配置完成之后就可以直接使用了,可以在任何的文件目录或者文件上运行
./node_modules/.bin/eslint yourfile.js
上述的使用只是在本地安装了 eslint,当然我们完全可以把这货安装成全局的,使用
npm install -g eslint
,但是呢,全局安装的 eslit 在执行的时候,使用的插件和配置文件还是优先读取本地的,如果在~/
目录中存在配置文件,只有在 eslint 没有读取到任何的配置文件的时候才会去读取这里的文件。
ESLint 基本配置
ESLint 被设计为完全可配置的。主要有两种方法来配置 ESLint:
- 把配置信息直接放在源代码文件中。
javascript /* eslint-env node, mocha */ class Hello{ greet(name){ console.log("Hello "+name); } } module.exports=Hello;
- 把配置文件放置在配置文件中,可以为整个目录和它的子目录指定配置信息。可以配置一个独立的
.eslintrc.*
,例如.eslintrc.json
,也可以在package.json
文件中的eslintConfig
指定。
指定支持的解析器选项
解析器选项可以在.eslintrc.*
文件中使用parserOptions
来配置。可用的选项有如下几个:
ecmaVersion
:默认是5
可以使用 6,7,8,9,10 来指定更高的版本。sourceType
:默认是script
。如果代码是 ECMAScript 模块的话可以设置为module
。ecmaFeatures
:这个是一个 Object,可以用来指定额外的语言特性。globalReturn
:允许在全局作用域下使用return
语句。impliedStrict
:启用全局的strict mode
。jsx
:启用JSX支持experimentalObjectRestSpread
:启用实验性的特性支持,这个是实验性的功能,在实际的项目中最好不要使用。
一个简单的文件示例:
{
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {}
}
指定解析器
ESLint 默认使用Espree作为解析器,可以在配置文件中指定其他的解析器,这些解析器必须符合下列的要求:
- 必须是一个 node 模块
- 必须符合parser interface
通过设置.eslintrc
文件中的parser
选项来指定其他的解析器,例如:
{
"parser": "esprima",
"rules": {
"semi": "error"
}
}
下面是一些和 ESLint 兼容的解析器:
指定处理器
处理器可以从其他的文件中提取 JavaScript 代码,然后让 ESLint 检测 JavaScript 代码,或者在预处理中转件 JavaScript 代码。
指定环境
一个环境定义了一组预定义的全局变量。可用的环境包括:
browser
- 浏览器环境中的全局变量。node
- Node.js 全局变量和 Node.js 作用域。commonjs
- CommonJS 全局变量和 CommonJS 作用域 (用于 Browserify/WebPack 打包的只在浏览器中运行的代码)。shared-node-browser
- Node.js 和 Browser 通用全局变量。es6
- 启用除了 modules 以外的所有 ECMAScript 6 特性(该选项会自动设置 ecmaVersion 解析器选项为 6)。worker
- Web Workers 全局变量。amd
- 将 require() 和 define() 定义为像 amd 一样的全局变量。mocha
- 添加所有的 Mocha 测试全局变量。jasmine
- 添加所有的 Jasmine 版本 1.3 和 2.0 的测试全局变量。jest
- Jest 全局变量。phantomjs
- PhantomJS 全局变量。protractor
- Protractor 全局变量。qunit
- QUnit 全局变量。jquery
- jQuery 全局变量。prototypejs
- Prototype.js 全局变量。shelljs
- ShellJS 全局变量。meteor
- Meteor 全局变量。mongo
- MongoDB 全局变量。applescript
- AppleScript 全局变量。nashorn
- Java 8 Nashorn 全局变量。serviceworker
- Service Worker 全局变量。atomtest
- Atom 测试全局变量。embertest
- Ember 测试全局变量。webextensions
- WebExtensions 全局变量。greasemonkey
- GreaseMonkey 全局变量。 这些环境并不是互斥的,所以你可以同时定义多个。
可以在源文件、配置文件或者命令行中的--env
指定运行的环境
-
在源文件中指定运行环境
/* eslint-env node, browser */ console.log("hello");
-
在
.eslintrc.*
配置文件中指定{ "env": { "browser": true, "node": true } }
-
在
package.json
中指定json { "name": "eslintdemo", "version": "1.0.0", "devDependencies": { "eslint": "^6.2.2", "eslint-plugin-react": "^7.14.3", }, "eslintConfig": { "env": { "browser": true, "node": true } } }
可以为指定的插件单独设置运行环境,例如下面的配置文件就表示为my-plugin
插件设置node
的运行环境。
{
"plugins":["my-plugin"],
"env":[
"my-plugin:node":true
]
}
设置全局变量
当访问当前源文件内未定义的变量时,no-undef 规则将发出警告。如果你想在一个源文件里使用全局变量,推荐你在 ESLint 中定义这些全局变量,这样 ESLint 就不会发出警告了。你可以使用注释或在配置文件中定义全局变量。 如果想在 JavaScript 文件中使用注释指定全局变量,格式如下:
/* global v1, v2 */
这里定义了两个全局变量 v1, v2,还可以为这两个变量设置读写的属性,例如:
/* global v1:writable, v2:writable */
如果需要在配置文件中指定全局变量,需要用到globals
属性,例如:
{
"globals": {
"v1": "writable",
"v2": "readonly"
}
}
其中的writable
属性表示允许重写变量,readonly
属性表示不允许重写变量(给变量重新赋值)。
我们还可以使用off
属性来禁用一些全局变量,例如:
{
"env": {
"es6": true
},
"globals": {
"Promise": "off"
}
}
上述的配置就表示了禁用了Promise
全局变量。
配置插件
ESLint 支持第三方的插件。
在配置文件中配置插件的时候,使用plugins
关键字来存放插件名字的列表。插件名可以省略eslint-plugin-
前缀。
{
"plugins": ["my-plugin1", "eslint-plugin-my-plugin2"]
}
配置规则
ESLint 中附加了不少规则,可以在配置文件或者注释中配置使用这些规则。 规则配置项的值必须为下列几个值之一:
"off"
或者0
,这个表示关闭规则。"warn"
或者1
,开启规则,仅警告不会导致程序退出。"error"
或者2
,开启规则,触发错误,程序会退出。
在注释中配置
/* eslint eqeqeq: "off", curly: "error" */
在配置文件中配置
{
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"],
"my-plugin/my-rule": "error"
}
}
可以在注释中使用eslint-disable
来禁用一些规则,例如:
/* eslint-disable indent*/
//这个注释可以放置在代码的不同的地方,可以放置文件的行首,表示对整个文件生效,可以放置在文件的某一行,表示对某一行生效。
如果需要禁用某一组文件的规则,需要使用overrides
和files
,
{
"rules":{...}
"overrides":{
"files":["*-test.js","*.spec.js"],
"rules":{
"no-unused-expressions": "off",
"indent": "off"
}
}
}
配置共享的设置 ESLint 支持在配置文件添加共享设置。你可以添加 settings 对象到配置文件,它将提供给每一个将被执行的规则。如果你想添加的自定义规则而且使它们可以访问到相同的信息,这将会很有用,并且很容易配置。
{
"settings": {
"sharedData": "Hello"
}
}
配置文件使用
ESLint 支持如下几种格式的配置文件:
- JavaScript - 使用
.eslintrc.js
然后输出一个配置对象。 - YAML - 使用
.eslintrc.yaml
或.eslintrc.yml
去定义配置的结构。 - JSON - 使用
.eslintrc.json
去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释。 - (弃用) - 使用 .eslintrc,可以使 JSON 也可以是 YAML。
- package.json - 在
package.json
里创建一个eslintConfig
属性,在那里定义你的配置。 如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下:
- .eslintrc.js
- .eslintrc.yaml
- .eslintrc.yml
- .eslintrc.json
- .eslintc
- packag.json
配置文件层级和级联关系
当使用.eslintrc.*
和package.json
文件的配置时,可以使用层叠配置。层叠配置使用与被检测文件最近的.eslintrc
文件为最高的优先级,然后才是父级的目录。
默认的情况下,eslint 会在所有的父级目录里面寻找配置文件,一直到根目录,但是如果在某个配置文件中设置了"root":true
,eslint 就会停止在父级目录中寻找。
完整的配置层次结构,从最高优先级最低的优先级,如下:
- 行内配置
/*eslint-disable*/
和/*eslint-enable*/
/*global*/
/*eslint*/
/*eslint-env*/
- 命令行选项(或 CLIEngine 等价物):
--global
--rule
--env
--config
- 项目级配置:
- 与要检测的文件在同一目录下的
.eslintrc.*
或package.json
文件,注意.eslintrc
文件的优先级要高于package.json
。 - 继续在父级目录寻找
.eslintrc
或package.json
文件,直到根目录(包括根目录)或直到发现一个有"root": true
的配置。 - 如果不是(1)到(3)中的任何一种情况,退回到 ~/.eslintrc 中自定义的默认配置。
配置文件的继承关系
可以使用extends
来继承一些已经启用的配置。
extends 属性值可以是:
- 指定配置的字符串(配置文件的路径、可共享配置的名称、eslint:recommended 或 eslint:all)
- 字符串数组:每个配置继承它前面的配置
ESLint 递归地扩展配置,基本的配置文件也可以使用extends
属性。
我们可以通过继承eslint:recommended
启用一系列核心的规则,通过继承eslint:all
启用 eslint 的所有的规则。
{
"plugins": ["react"],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"./node_modules/coding-standard/.eslintrc-jsx"
]
}
忽略一些文件和目录
有的时候,我们有一些文件不想使用 ESLint 进行检查,我们可以在配置文件中忽略这些个文件。
忽略文件和目录的应该配置在.eslintignore
文件中,使用的时候glob
模式,这个和 git 的.gitignore
文件的规则是类似的。
- 以 # 开头的行被当作注释,不影响忽略模式。
- 路径是相对于 .eslintignore 的位置或当前工作目录。通过 –ignore-pattern command 传递的路径也是如此。
- 忽略模式同 .gitignore 规范
- 以 ! 开头的行是否定模式,它将会重新包含一个之前被忽略的模式。
- 忽略模式依照 .gitignore 规范.
其他
出现不能正确地解析async/await
的问题
这个是ecmaVersion
设置有问题,设置为 2017 或者更高就可以了。
{
"extends": "eslint-config-airbnb",
"env": {
"browser": true,
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module",
"ecmaFeatures": {
"globalReturn": true,
"impliedStrict": true,
"jsx": true,
"modules": true
}
}
}
参考文献
[1] Confituring ESLint [2] 深入浅出 eslint