Eslint通关指南

928 阅读14分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

简介

作为前端开发Eslint想必大家肯定不会陌生,一般项目中都会配置。但是因为它不会影响到平时我们业务功能的实现,可能很多小伙伴都知道它是用来检测js代码语法和统一代码风格的,但是并没有深入去研究。所以有时候碰到编辑器莫名飘红、某些代码不想让Eslint检测,对于这些问题明明很清楚是需要配置Eslint但是因为不熟悉而无从下手,今天笔者就带大家彻底弄懂Eslint,让你能随心所欲的配置自己的项目。

安装

初始化项目

// 创建项目目录
mkdir eslint-test

// 进入项目
cd eslint-test

// 初始化package.json文件
npm init -y

我们本地安装eslint

npm i eslint -D

初始化配置文件

安装好后,我们需要生成eslint的配置文件

npx eslint --init

执行该命令后,会有一系列选项让我们选择。

这里我们说说eslint的功能,由浅入深eslint支持语法、问题、强制代码风格三个功能。

image.png

这里我们先选择语法和问题的检测。后面还有一系列选择,这里笔者就不再演示了,最终选择如下。

image.png

执行完该命令后,最后生成的配置文件如下,这里我们选择生成的是js文件。

// .eslintrc.js

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: "eslint:recommended",
  overrides: [],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  rules: {},
};

eslint支持多种格式的配置文件,关于配置文件的种类我们后面会细说。

简单测试

配置好了,我们就来简单测试一下,我们新建src目录,并创建index.js文件

语法检测

我们先写个错误的switch

// src/index.js

switch ('randy') {
  case: "name"
}

我们执行下eslint,来检查下我们的index.js文件

npx eslint ./src/index.js

可以看到,eslint提示错误了,问题是冒号问题

image.png

我们来修正下

// src/index.js

switch ('randy') {
  case "name":
}

我们再次执行eslint,来检查下我们的index.js文件

npx eslint ./src/index.js

可以看到,修改后的switch是没语法问题的,所以没有任何错误提示了。

image.png

问题检测

上面使用Eslint检测的是语法问题,接下来我们再来试试Eslint的问题检测。

我们使用一个未定义的变量

// src/index.js

consolelog(randy)

我们再次执行eslint,来检查下我们的index.js文件

npx eslint ./src/index.js

可以看到,Eslint直接报错并提示了错误原因

image.png

格式检测

语法和问题的检测是非常重要的,因为如果不提前检测出来,问题代码打包上线后就会产生生产事故。

接下来我们来说说代码格式,代码格式相对来说没那么重要,因为它不属于代码错误,而是代码风格。好的代码风格能让人看起来特别清爽,也更容易排查错误,在大团队统一代码风格也是非常重要的一件事。

我们先来加个风格风格,这条规则的意思是强制在 function的左括号之前使用一致的空格

rules: {
  "space-before-function-paren": 2,
},

接下来我们写个方法,然后在括号左边不留空格

function say2() {
  console.log(1);
}

我们再次执行eslint,来检查下我们的index.js文件

npx eslint ./src/index.js

可以看到,Eslint直接报错并提示了错误原因

image.png

看到这,很多小伙伴可能要问了,每次要运行eslint命令才能检测到代码问题,能不能直接在编辑器里面显示呢?

vscode支持

诶,还真有,如果要想在vscode支持eslint,直接安装ESLint插件就可以了。

image.png

安装完插件,我们再打开该文件看一下,可以发现在有错误的地方编辑器直接飘红了,并且鼠标悬浮上去错误直接显示出来了。

image.png

image.png

image.png

看到这知道eslint的强大了吧。在开发期间能大大减少错误的出现。

好了说完了eslint的安装、简单使用以及在vscode的支持,接下来我们再来详细说说eslint的配置。

配置项分析

eslint的配置项有很多,下面我们来说说平时使用得最多的几个常用的配置项。

root

root: true 指定该文件为根目录文件,eslint就不会再继续向上查找配置文件了。

如果不配置root: trueeslint会一层一层查找配置文件直到系统根目录,并进行配置合并。对于相同配置规则是里面的会覆盖外面的。所以如果想只使用当前目录的配置文件,配置root: true就可以了。

env 环境

环境,一个环境定义了一组预定义的全局变量。

常见的环境有如下三个

  • browser - 浏览器环境中的全局变量。
  • node - Node.js 全局变量和 Node.js 作用域。
  • es6 - 启用除了 modules 以外的所有 ECMAScript 6 特性(该选项会自动设置 ecmaVersion 解析器选项为 6)。

更多环境可以查看eslint官方文档env模块

下面笔者举个例子

笔者的定义的环境是

env: {
  browser: true,
  es2021: true,
},

如果我们在源码中使用node的全局变量global,就会报错

image.png

但是使用this、window是没问题的,因为我们定义了browser环境。

现在懂了环境的意思吧,就会定义了某环境,就能使用某环境提供的全局变量,就能在源码中直接使用而不会被eslint当做错误处理。

这些环境并不是互斥的,所以你可以同时定义多个。

globals 全局变量

上面说了,定义了环境就能直接使用相应环境的全局变量,但是如果有些全局变量是环境中没有的呢?这就需要用到全局变量配置了。

要在配置文件中配置全局变量,请将 globals 配置属性设置为一个对象,该对象包含以你希望使用的每个全局变量。对于每个全局变量键,将对应的值设置为 "writable" 以允许重写变量,或 "readonly" 不允许重写变量。

由于历史原因,布尔值 false 和字符串值 "readable" 等价于 "readonly"。类似地,布尔值 true 和字符串值 "writeable" 等价于 "writable"。但是,不建议使用旧值。

下面笔者举个例子

假如我们项目中有个全局变量TEST,这个全局变量是通过cdn包引入的,所以eslint并不知道这个全局变量是可以直接使用的,所以会提示错误。

image.png

这样我们在.eslintrc.js文件中配置一个全局变量就可以了

globals: {
  TEST: true,
},

配置完后,就不会报错了。

image.png

当然第二种方式是,你还可以在使用的地方用注释的方式进行表明,跟上面的效果是一样的,不过你每使用一次就得配置一次。

/* global TEST:readonly */

我们还可以使用字符串 "off" 禁用全局变量。例如,在大多数 ES2015 全局变量可用但 Promise 不可用的环境中,你可以使用以下配置

globals: {
  Promise: "off",
},

这样我们再使用Promise就会报错

image.png

Parser 解析器

解析器的作用是将JS代码解析成 AST ,ESLint 将通过遍历该AST 来触发各个检查规则。

由于 ESLint 默认的解析器ESPree只支持已经形成标准的语法特性,对于处于实验阶段以及非标准的语法,如 TypeScript ,是无法正确解析的,这时就需要使用其他的解析器,生成和 ESTree 结构相兼容的 AST 。对于 TypeScript 就需要使用"parser": @typescript-eslint/parser

"parser": "espree",

你可以在配置文件中指定一个不同的解析器,只要该解析器符合下列要求:

  1. 它必须是一个 Node 模块,可以从它出现的配置文件中加载。通常,这意味着应该使用 npm 单独安装解析器包。
  2. 它必须符合 parser interface

parserOptions 解析器选项

ESLint 允许你指定你想要支持的 JavaScript 语言选项。默认情况下,ESLint 支持 ECMAScript 5 语法。你可以覆盖该设置,以启用对 ECMAScript 其它版本和 JSX 的支持。

请注意,支持 JSX 语法并不等同于支持 React。React 对 ESLint 无法识别的JSX语法应用特定的语义。如果你正在使用 React 并且想要 React 语义支持,我们建议你使用 eslint-plugin-react

同样的,支持 ES6 语法并不意味着同时支持新的 ES6 全局变量或类型(比如 Set 等新类型)。对于 ES6 语法,使用 { "parserOptions": { "ecmaVersion": 6 } }指定;对于新的 ES6 全局变量,使用 { "env":{ "es6": true } }指定。 但是设置了{ "env": { "es6": true } } 会自动启用es6语法,并设置{ "parserOptions": { "ecmaVersion": 6 } }

解析器选项可以在 .eslintrc.* 文件使用 parserOptions 属性设置。可用的选项有:

  • ecmaVersion - 默认设置为 3,5(默认), 你可以使用 6、7、8、9 或 10 来指定你想要使用的 ECMAScript 版本。你也可以用使用年份命名的版本号指定为 2015(同 6),2016(同 7),或 2017(同 8)或 2018(同 9)或 2019 (same as 10)

  • sourceType - 设置为 "script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)。

  • ecmaFeatures - 这是个对象,表示你想使用的额外的语言特性:

    • globalReturn - 允许在全局作用域下使用 return 语句
    • impliedStrict - 启用全局 strict mode (如果 ecmaVersion 是 5 或更高)
    • jsx - 启用 JSX
    • experimentalObjectRestSpread - 启用实验性的 object rest/spread properties 支持。(重要: 这是一个实验性的功能,在未来可能会有明显改变。 建议你写的规则 不要 依赖该功能,除非当它发生改变时你愿意承担维护成本。)

rules 规则

ESLint 附带有大量的规则。想要使用哪种规则在rules配置即可

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

下面笔者举个例子,

我们配置了强制使用一致的反勾号、双引号或单引号规则

rules: {
  quotes: 2
},

我们使用单引号输出就会报错

image.png

我们再将规则设置为警告

rules: {
  quotes: 1
},

可以看到,不是报错而是警告了

image.png

当然规则集还有很多,上面我们只简单演示了一个,更父规则集可以查看eslint官方文档

extends 继承

我们的配置可以继承一些别人写好的配置。这样我们就不需要一个个去配置rules了,而是直接继承别人写好的配置。

extends的值可以是字符串或数组。

比如我们上面使用的就是eslint官方推荐的配置,使用的就是字符串格式。

{
  extends: "eslint:recommended"
}

"eslint:recommended"属性启用一系列核心规则,在 规则页面 打✅的都是该规则里面的。

extends 属性值可以由以下组成:

  • plugin:
  • 包名 (省略了前缀,比如,react)
  • /
  • 配置名称 (比如 recommended)
{
  extends: [
    'eslint:recommended', // 是 ESLint 官方的扩展,内置推荐规则
    'eslint:all', // ESLint 内置的所有规则
    'plugin:vue/essential', // 是插件类型扩展
    'eslint-config-standard', // eslint-config 开头的都可以省略掉前面 直接使用standard即可
    '@vue/prettier', // @开头扩展和 eslint-config 一样,只是在 npm 包上面加了一层作用域 scope;
    './node_modules/coding-standard/.eslintrc-es6' // 一个执行配置文件的路径
  ]
}

配置文件种类

eslint的配置支持很多种方式,我们可以使用独立的配置文件、或者在 package.json文件里的 eslintConfig 字段指定配置、或者使用文件内注释。

平时项目开发使用的最多的还是独立配置文件方式。所以我们重点说说配置文件。

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. .eslintrc
  6. package.json

如果想使用自定义配置文件的话传递-c、--config指定自定义文件就可以了

eslint -c ./my-eslint.js ./src/index.js

// 或者

eslint --config ./my-eslint.js ./src/index.js

禁用规则注释

有时我们写的某行、某几行、或者某文件不想让eslint检测怎么办呢?这就需要用到eslint的注释了。

禁用某行

// 禁用某行
alert('foo'); // eslint-disable-line

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

// 禁用下一行
// eslint-disable-next-line
alert('foo');

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

禁用某几行

禁用某几行,使用 /* eslint-disable *//* eslint-enable */包裹即可。

// ...

/* eslint-disable */

alert('foo');

/* eslint-enable */

// ...

禁用某个文件

禁用某文件将/* eslint-disable */放到文件顶部即可。

/* eslint-disable */

alert('foo');

// ...

除了禁用某些代码,我们还可以对某些代码进行具体规则的禁用

比如下面就是禁用这一行的alert规则。

alert('foo'); /* eslint-disable-line no-alert */

本文件禁用alert、quotes规则

/* eslint-disable no-alert, quotes */

alert('foo');

当前其他规则也是可以使用的,并且支持多个组合使用。

注意,为文件的某部分禁用警告的注释,告诉 ESLint 不要对禁用的代码报告规则的冲突。ESLint 仍解析整个文件,然而,禁用的代码仍需要是有效的 JavaScript 语法。

如果要在一些文件中禁用一些检查规则那该怎么办呢?总不能一个个文件去添加注释吧?

在一组文件中禁用某些规则

这就得需要使用 overrides 和 files了。

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

自动修复

ESLint是支持某些错误自动修复的,能自动修改的规则可以查看规则页面 ,里面带🔧标志的规则都是可以自动修复的。

使用自动修复我们使用--fix参数即可

eslint --fix ./src/index.js

--ext 文件后缀

ESLint默认只会检查.js后缀的文件,如果还有其它后缀我们需要使用--ext来指定。

下面的例子会检查src目录下的.js.jsx文件。

eslint --ext .jsx --ext .js src/

eslint --ext .jsx,.js src/

注意,该标记只在与目录一起使用时有效,如果使用文件名或 glob 模式,它将会被忽略。

例如,eslint lib/* --ext .js 将匹配 lib/ 下的所有文件,忽略扩展名。

.eslintignore 忽略文件

你可以通过在项目根目录创建一个 .eslintignore 文件告诉 ESLint 去忽略特定的文件和目录。.eslintignore 文件是一个纯文本文件,其中的每一行都是一个 glob 模式表明哪些路径应该忽略检测。例如,以下将忽略所有的 JavaScript 文件:

**/*.js

这个有点类似.gitignore,当然语法你也可以参阅 .gitignore 规范。

除了 .eslintignore 文件中的模式,ESLint总是忽略 /node_modules/* 和 /bower_components/* 中的文件。

如果你更想使用一个不同的文件,你可以在命令行使用 --ignore-path 选项指定它。

比如下面我们使用.jshintignore文件作为忽略文件而不是.eslintignore文件

eslint --ignore-path .jshintignore ./src/index.js

如果没有发现 .eslintignore 文件,也没有指定替代文件,ESLint 将在 package.json 文件中查找 eslintIgnore 键,来检查要忽略的文件。

{
  "name": "mypackage",
  "version": "0.0.1",
  "eslintConfig": {
      "env": {
          "browser": true,
          "node": true
      }
  },
  "eslintIgnore": ["hello.js", "world.js"]
}

扩展

禁用TS提示

如果有用TS的话,TS也会进行语法检查。如果想跳过检查的话有如下两种方式

禁用某行

// @ts-ignore

禁用某文件

// @ts-nocheck

启用某文件

// @ts-check

参考文档

eslint官方文档

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!