Eslint 使用

ESLint

ESLint 是一种静态代码分析工具,用于识别 JavaScript 代码中存在的有问题的模式,可以帮助我们写出语法正确,风格统一的代码。

安装以及使用 ESLint

  1. 我们可以使用 npm 来安装 ESLint,运行npm install eslint --save-dev命令安装 ESlint。
  2. 在项目根目录运行./node_modules/.bin/eslint --init命令进行初始化操作,初始化的时候根据命令的提示输入一些基本的设置,确认后会在项目的根目录下面生成一个名字为.eslintrc.*(这个在初始化的时候可以选择不同的文件格式,json 或者 yaml 都是可以的)的配置文件。如下图所示 /img/1566699279433.png
  3. 安装配置完成之后就可以直接使用了,可以在任何的文件目录或者文件上运行 ./node_modules/.bin/eslint yourfile.js

上述的使用只是在本地安装了 eslint,当然我们完全可以把这货安装成全局的,使用npm install -g eslint,但是呢,全局安装的 eslit 在执行的时候,使用的插件和配置文件还是优先读取本地的,如果在~/目录中存在配置文件,只有在 eslint 没有读取到任何的配置文件的时候才会去读取这里的文件。

ESLint 基本配置

ESLint 被设计为完全可配置的。主要有两种方法来配置 ESLint:

  1. 把配置信息直接放在源代码文件中。 javascript /* eslint-env node, mocha */ class Hello{ greet(name){ console.log("Hello "+name); } } module.exports=Hello;
  2. 把配置文件放置在配置文件中,可以为整个目录和它的子目录指定配置信息。可以配置一个独立的.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作为解析器,可以在配置文件中指定其他的解析器,这些解析器必须符合下列的要求:

  1. 必须是一个 node 模块
  2. 必须符合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*/
//这个注释可以放置在代码的不同的地方,可以放置文件的行首,表示对整个文件生效,可以放置在文件的某一行,表示对某一行生效。

如果需要禁用某一组文件的规则,需要使用overridesfiles,

{
    "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 只会使用一个。优先级顺序如下:
  1. .eslintrc.js
  2. .eslintrc.yaml
  3. .eslintrc.yml
  4. .eslintrc.json
  5. .eslintc
  6. packag.json

配置文件层级和级联关系

当使用.eslintrc.*package.json文件的配置时,可以使用层叠配置。层叠配置使用与被检测文件最近的.eslintrc文件为最高的优先级,然后才是父级的目录。

默认的情况下,eslint 会在所有的父级目录里面寻找配置文件,一直到根目录,但是如果在某个配置文件中设置了"root":true,eslint 就会停止在父级目录中寻找。

完整的配置层次结构,从最高优先级最低的优先级,如下:

  1. 行内配置
  2. /*eslint-disable*//*eslint-enable*/
  3. /*global*/
  4. /*eslint*/
  5. /*eslint-env*/
  6. 命令行选项(或 CLIEngine 等价物):
  7. --global
  8. --rule
  9. --env
  10. --config
  11. 项目级配置:
  12. 与要检测的文件在同一目录下的 .eslintrc.*package.json 文件,注意.eslintrc文件的优先级要高于package.json
  13. 继续在父级目录寻找 .eslintrcpackage.json文件,直到根目录(包括根目录)或直到发现一个有"root": true的配置。
  14. 如果不是(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