一文掌握 eslint,再也不怕项目报错
版权声明:本人文章仅在掘金平台发布,请勿抄袭搬运,转载请注明作者及原文链接 🦉
网页版带有主题和代码高亮,阅读体验更佳 🍉
很多初学 vue
的同学一开始如果使用 vue-cli
创建项目并且采用了严格模式的 eslint
的话,肯定深受其扰,各种莫名报错导致项目跑不起来,也不知道那些乱七八糟的配置到底有什么用,一气之下直接删除项目重新搭建,并将这该死的 eslint
列入自己的黑名单。
但是稍微看过一点开源项目的源码,或者你的公司前端技术和氛围很不错的话,可以看到每个工程都有 eslint
,虽然它并不能从根源上杜绝屎山代码,但是能帮助开发者减少犯错的可能。作为前端,扪心自问,自己是否具备高级的审美,对代码的排版及格式具备一定的审美能力?写代码时,是否养成了缩进、换行的良好习惯?
来看看没有空格的代码和有空格的代码的区别:
// ===== bad =====
const a=1;
const a===1?true:false
function(a,b){
return a+b
}
arr.filter(item=>item.a===1&&item.b===2)
// ===== good =====
const a = 1;
const a === 1 ? true : false
function(a, b) {
return a + b
}
arr.filter(item => item.a === 1 && item.b === 2)
孰优孰劣,不言而喻。但是每个人的代码风格都是迥异的,只靠标准和规范来推动只是徒劳,统一代码风格这种脏活累活应该交给工具来做。
而 eslint
天生就是做这个的,可以说是团队项目必备工具。如果你在公司项目里写代码时,看到 eslint
报错就束手无策,又或者你想彻底搞清楚 eslint
的配置,比同事稍微多懂一丢丢,那么本篇文章就能满足你。
文章末尾有惊喜~。
搭建 eslint 代码检查环境
如果使用 vscode
那么必须下载 eslint
扩展,使用 webstorm
的话应该内置了。
执行 npm init -y
。
执行 npx eslint --init
。
它会询问我们期待 eslint
做什么:
- 仅仅检查语法
- 检查语法,发现问题
- 检查语法,发现问题,强制代码风格
一般我会选择第二个。
它会继续询问你,代码使用哪种模块化,这就根据你自己的项目来定了,我们选择第一个。
它继续询问你是否在 vue
或者 react
中使用 eslint
,我们选择第三个,你可以根据你的项目来选择。
是否需要 typescript
,我们选择需要。
代码运行在浏览器还是 node
,我们选择浏览器。
这一步比较关键,它将根据我们之前的选择生成配置文件 eslintrc
,这一步就是在选择 eslintrc
文件的后缀,这里我建议选择 json
,不建议选择 js
和 yaml
。
关于 eslintrc 如何选择文件后缀
我想 yaml
熟悉人的不多,不建议大家选择,如果你选择 js
呢?因为在同一个项目下多个 eslintrc
是依靠后缀来区分优先级的,js
> yaml
> json
。那选择 js
就真的好吗?由于我们的项目可能使用 esmodule
和 commonjs
两种模块化语法,有些时候 .js
、.cjs
的 eslintrc
自身就会报错,初学的同学可能一下就懵了,我是用你来检查错误的,你倒好自己就先报错了。加上后续如果你再使用 typescript
的话,与 tsconfig.json
可能还会继续存在一些冲突,实在没有必要。
为了避免模块化语法带来的各种乱七八糟的问题,我建议你选择 json
作为 eslintrc
的文件后缀,如果没有后缀默认就是 json
。我的做法也是不要后缀,默认 json
格式,简洁美观。
eslintrc 初始化配置
初始化生成的配置:
{
"root": true,
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"globals": {
},
"overrides": [
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
}
}
可以看到这个 json
文件是 4
个缩进,我个人喜欢 2
个缩进,但是在 vscode
里没有缩进线:
新增一个 .editorconfig
文件,做如下配置:
# Editor configuration, see http://editorconfig.org
root = true // 是否从根目录起开始生效
[*]
charset = utf-8 // 编码字符集
indent_style = space // 缩进风格 space 或者 tab
indent_size = 2 // 缩进个数
insert_final_newline = true // 末尾插入新行
trim_trailing_whitespace = true // 空格过滤
[*.md]
max_line-length = off
trim_trailing_whitespace = false
该配置文件主要是告诉编辑器,该以怎样的形式表现,例如缩进,编码格式,空格过滤等,在团队协作中也有利于统一代码风格。
配置都比较语义化,就不再赘述了,不懂的可以访问官网 editorconfig。
可以看到缩进线出来了:
eslintrc 配置字段解读
root
该字段表示,你就识别我当前根目录下的 eslint
配置,别再看其他目录下的配置了。这在 menorepo
的项目里比较有用。当 workspace
下有配置,项目目录下又有配置,那么配置可能就会冲突,把范围限定在本项目下就是该字段的意义。
env
该字段表示 eslint
如何看待你的代码,例如 esmodule
下,import
,window
之类全局变量和语法不需要声明定义,而 commonjs
下,require
,process
不需要声明。来看下效果:
我们在 env
字段下添加 "node": true
,报错消失。
其中 "es2021": true
的意思也是一样的,识别 es2021
及之前的新语法,那 2022
后的新特性可能就会报错了。这个看你个人选择,es2021
其实也够用了。
globals
现在,我要在 uniapp
项目里使用 eslint
,uni
这个全局变量都不在 broswer
、es2021
、node
里,那 eslint
就会报错找不到这个变量,这时候在 globals
里定义 uni
为全局变量,就不会报错了。
extends
这个字段可以理解为继承、扩展。有些时候 eslint
的内置规则我们会觉得不够用,又或者社区有更好的规则,再或者我们自己有自己定义的规则集,这时候就需要用到这个字段了,他表示我们需要继承扩展的规则集。例如现在社区最流行的是 airbnb
规则集,那么我们就可以:"extends": "eslint-config-airbnb"
。当然了,可以扩展多个:
...
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"eslint-config-airbnb"
],
...
不过规则集之间可能会各有冲突,使用时还需要注意。
最关键的是,我们看似仅仅只是扩展了规则集,实际上:
extends
会继承别人写好的一份.eslintrc
的配置,这份配置不仅仅包括了rules
还有parser
,plugins
之类的东西。 (海怪)
规则集的命名规则一般是:eslint-config-xxxx
,所以后续看到此类包就知道是 eslint
规则集了。
overrides
如果你想对某些特殊的文件指定解析器,那么可能会用到此字段。使用示例:
...
"overrides": [
{
"files": ["*.md"],
"processor": "a-plugin/markdown"
},
// 下面的配置就是小型的 eslintrc,parser、parserOptions 之类的字段也可以继续配置
{
"files": ["**/*.{js,jsx}"], // 只处理 js 和 jsx 文件
"parser": "@babel/eslint-parser", // 使用 babel 来解析 js 文件
"parserOptions": {
"sourceType": "module", // 支持 import/export
"allowImportExportEverywhere": false,
"ecmaFeatures": {
"globalReturn": false,
},
},
},
]
...
但你基本上用不到这个字段,了解即可。
parser
这个选项指定解析器,例如,eslint
是用来检查 js
语法的,但是 ts
它不支持,这时候需要使用 ts
提供的解析器来进行解析。
...
"parser": "@typescript-eslint/parser",
...
...
"parser": "vue-eslint-parser",
...
这些 parser
都是独立的 npm
包,需要下载使用。针对不同的主语言环境使用不同的解析器。
parserOptions
这里我们直接看官网的解释好了:
plugins
plugins
可以理解规则扩展,例如针对 vue
、react
等前端框架,他们有自己的文件后缀,还有自己的语法规则,这些语法校验都需要社区来提供。此时 eslint
自己提供的规则就不够用了,所以需要插件来扩展校验规则。
插件的命名规则一般是:eslint-plugin-xxxx
,所以后续看到此类包就知道是 eslint
插件了。
例如,vue
语法检查需要下载 eslint-plugin-vue
,react 语法检查需要下载 eslint-plugin-react
。一般来说,parser
和 plugins
是成对使用的,请记住这点,很重要。
例如,支持 vue 语法检查:
"parser": "vue-eslint-parser",
"plugins": ["eslint-plugin-vue"]
支持 typescript
语法检查:
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint/eslint-plugin"]
rules
这个就是自己自定义的规则,没啥特别的。例如我们设置没有分号报错:
报错级别有三种:error
,warn
,off
,分别对应数字 2
,1
,0
。还有一些写法,感兴趣的可以自行研究:
"react/jsx-filename-extension": [
1,
{
"extensions": [
".js",
".jsx"
]
}
],
parser、extends、plugins 的区别
可能看到这里有些朋友已经懵了,那这三者有啥区别?
parser
是让 eslint
能认识语法。
plugins
是提供特殊语法的检查规则集。
extends
说白了就是 parser
和 plugins
配置的简写(可以简单这么理解,但不全对),我们前面说过 plugins
和 parser
是成对出现的。
而 extends
的作用就在于只要我声明了继承的规则集,即使我没有配置 parser
和 plugins
,我扩展的语法规则集也能生效。
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
来看示例,我们把 plugins
和 parser
删除,错误提示依旧生效。
.eslintignore
有些时候,我们并不希望 eslint
对某些文件做代码检查,例如我们 build
产物,这时候要将这些产物代码检查进行忽略。在项目根目录下新建一个 .eslintignore
文件,如果你懂配置 .gitignore
,那么语法都是一样的,类似于正则匹配,来看示例:
node_modules/*
test/*
dist/*
build/*
开头是文件目录名,*
表示目录下所有文件都进行忽略。配置后这些文件下的代码都将不再进行代码检查。
写在最后
恭喜你看到最后,相信你已经掌握 eslint
,再也不怕代码报错了。答应给大家的惊喜:
推荐大家去看海怪的Linter上手完全指南,这本电子书从各种 lint
的发展由浅入深地带领大家学习 lint
工具,帮助你理清各个 linter
之间的发展关系,从此离前端工程化更进一步。
往期推荐
开发一个 npm 库应该做哪些工程配置? 40+
👍🏻 50+
💚
分享我在前端学习与开发中用到的神仙网站和工具 40+
👍🏻 110+
💚
uniapp 踩坑记录(二) 130+
👍🏻 150+
💚
闲来无事,摸鱼时让 chatgpt 帮忙,写了一个 console 样式增强库并发布 npm 100+
👍🏻 110+
💚
uniapp 初体验踩坑记录 30+
👍🏻 60+
💚
两小时学会 JS 正则表达式,终身不忘 50+
👍🏻
【一年前端必知必会】如何写出简洁清晰的代码 50+
👍🏻
【一年前端必知必会】了解 Blob,ArrayBuffer,Base64 40+
👍🏻 90+
💚
转载自:https://juejin.cn/post/7254476003065020473