参考帖:
在Typescript项目中,如何优雅的使用ESLint和Prettier
在 Vue + Typescript 项目中使用 eslint 和 Prettier 的配置
Using ESLint and Prettier in a TypeScript Project
最后有ESLint + TS + Prettier的完整配置及需要的依赖和编辑器插件
ESLint核心依赖、编辑器插件和Webpack中的ESLintWebpackPlugin之间的关系
我们先不关心ESLint的具体配置,从整体上来看,先了解编辑器+ESLint+打包工具的整体生态链 如果你使用其他的编辑器或者打包工具,可以在这里查询ESLint的相关整合插件/依赖
ESLint核心依赖
依赖下载:npm install eslint -D
在我们编写项目的时候,直观的感受上ESLint会做以下事情:
- 检查语法错误
- 将错误输出到控制台
- 开发环境页面上增加一个错误modal
- 生产环境发现error,直接停止打包运行
- 文件保存时格式化(可以配合prettier)
但是实际上,这些操作并不是ESLint单独完成的,其中ESLint完成的核心步骤是检查语法错误,识别了文件中的错误后,才能进行后面的操作,错误检查步骤:
- 通过定义的解析器(parser)去解析文件,生成AST树
- 通过预设/自定的规则对错误进行归类(error、warning)
这个网站可以让你直观的理解各种解析器和AST树 astexplorer.net/
错误检查只能将错误找出来,并不会进行任何操作,这时候控制台不会报错,编辑器也不会标红代码,这个功能主要是由ESLint核心依赖提供,也就是说,项目中通过npm install eslint -D下载ESLint依赖并进行配置之后,就拥有根据配置查找到错误的能力,但是具体需要如何展示这些错误,就需要另外的插件支持。
VSCode插件-ESLint
下载:VSCode应用商店搜索eslint
功能:当代码不符合eslint配置的规范时,标红代码,或是开启一系列eslint相关的配置,比如ESLint保存自动调用代码修复(--fix)功能就需要编辑器的支持
以VSCode为例,下载ESlint插件后需要在首选项-设置中配置编辑器需要检测的文件类型,如果不配置是不生效的
// ESLint插件的基本配置 settings.json
{
"eslint.validate": [
"javascript",
"typescript",
"javascriptreact", // JSX
"typescriptreact" // TSX
]
// 保存自动调用eslint --fix [file],该功能由VSCode的ESLint插件提供
"editor.codeActionOnSave": {
"source.fixAll.eslint": true
}
Webpack插件 ESLintWebpackPlugin
下载:npm install eslint-webpack-plugin —save-dev
功能:webpack插件,项目在打包时如果遇到eslint检查出的语法错误,在开发环境:控制台打印报错信息,可以在页面中嵌入全屏modal,展示错误信息;在生产环境:可中止打包运行。 可以通过改变ESLintWebpackPlugin的配置来改变具体处理的方式。ESLintWebpackPlugin
可以这么理解,如果使用Webpack打包项目,借助webpack-dev-server启动本地开发环境,那么开发环境下控制台的打印信息是受到webpack控制的,Webpack并不知道ESLint的报错信息有哪些,必须通过一个桥梁,也就是eslint-webpack-plugin来建立它们的连接。生产环境下也是同理。
如何在项目中配置ESLint、Typescript以及Prettier
基本思路
上面介绍的ESLint+编辑器+打包工具的三个依赖,其实已经可以满足我们格式化代码的所有要求
如果项目中想要用Prettier来进行代码格式化,有两种方式,一种是Prettier为ESLint提供规则,使用ESLint的fix功能去格式化代码;第二种方式是先使用Prettier为ESLint提供规则,再借助编辑器的Prettier插件,用相同的prettier规则来格式化代码
我们项目中使用第一种方式,单纯只用Prettier来提供规则,这样的好处是项目的格式化配置结构更清晰,也不需要下载多余的编辑器插件
格式化的思路如下:
- ESLint读取配置文件
.eslintrc.js来检查代码中不符合规范的错误或警告 - 配置编辑器(VSCode),开启文件的保存自动修复功能(自动—-fix),只有一些特定的错误可以被自动修复,比如分号、冒号等
无论你使用Vue、typescript或React,格式化代码的步骤都完全一样,他们的区别只在于第一步中,ESLint是如何去定义这些错误的,也就是说,针对于不同的技术栈,只有ESLint的配置不一样而已,这也是为什么ESLint的相关插件那么多的原因
先看一下ESLint的基本配置,这是一份没有添加任何额外插件的配置:
// .eslintrc.js
module.exports = {
// enviroment 项目运行的环境,配置这个可以为你提供一些全局变量,比如browser环境下允许使用windows API
env: {
browser: true,
node: true
},
parser: 'espree', // eslint的默认解析器
extends: ['eslint:recommended'], // 启用eslint的一些核心规则,也可以根据项目需求添加其他预设的规则
rules: { // 用户自定义的规则,可以覆盖extends中配置的预设规则
semi: ["error", "always"],
quotes: ["error", "double"]
},
plugins: [] // 第三方插件,可以提供额外规则、预设配置(config)、全局环境变量等
}
整个ESLint配置的最终目的是制定一份规则,然后检查代码是否符合该规则,针对某些规则,如果错误等级为error,可以通过eslint --fix来修复文件
这份配置文件可以分两部分,其中:
env、extends、rules、plugins字段都是为了规则服务parser字段指定解析器,用于生成AST树,ESLint的默认解析器是espree,只能解析JS文件,无法识别ts文件,项目文件如果使用typescript就需要借助第三方依赖来改变解析器
添加typescript检测
相关依赖
- @typescript-eslint/parser ESLint的解析器,用于解析typescript,从而检查和规范Typescript代码
- @typescript-eslint/eslint-plugin 这是一个ESLint插件,包含了各类定义好的检测Typescript代码的规范 加入typescript规则检测后的配置
module.exports = {
env: {
browser: true,
node: true
},
parser: '@typescript-eslint/parser', // 使用typescript解析器
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended'
], // 增加typescript的核心规则
plugins: ['@typescript-eslint'] // 添加typescript插件,这样就可以使用typescript的规则
rules: {
semi: ["error", "always"],
quotes: ["error", "double"],
'@typescript-eslint/no-explicit-any': 0 // typescript的规则
},
}
添加Prettier规则
相关依赖
- eslint-config-prettier 解决ESLint中的样式规范和prettier中样式规范的冲突,以prettier的样式规范为准,使ESLint中的样式规范自动失效
- eslint-plugin-prettier关闭ESLint和Prettier有冲突的规则 加入Prettier规则检测后的配置 要注意的一点是extends数组中后面的配置项会覆盖前面的,prettier必须放在最后一项,保证fix的修复规则以prettier为准
module.exports = {
env: {
browser: true,
node: true
},
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier'
], // 增加Prettier的核心规则
plugins: ['@typescript-eslint', 'prettier'], // 添加prettier插件来提供prettier的rule
rules: {
// semi: ["error", "always"],
// quotes: ["error", "double"], // rules里的规则会覆盖extends中的规则,要删掉这些影响格式化的规则
'@typescript-eslint/no-explicit-any': 'error',
'prettier/prettier': 'error', // 配置prettier的错误等级为error,为了让exlint --fix可以修复其错误
'arrow-body-style': 'off',
'prefer-arrow-callback': 'off'
},
}
eslint-plugin-prettier提供了一个快捷配置,下面的prettier配置和上面的配置效果一样:
module.exports = {
env: {
browser: true,
node: true
},
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended'
], // 增加Prettier的核心规则
plugins: ['@typescript-eslint'],
rules: {
// semi: ["error", "always"],
// quotes: ["error", "double"],
'@typescript-eslint/no-explicit-any': 'error',
},
}
arrow-body-style 和 prefer-arrow-callback这两个规则是prettier推荐添关闭的,在某些情况下,这两个规则会导致ESLint autofix的BUG
If you use arrow-body-style or prefer-arrow-callback together with the prettier/prettier rule from this plugin, you can in some cases end up with invalid code due to a bug in ESLint’s autofix – see issue #65 .
-- 摘自eslint-plugin-prettier官方文档
Prettier会读取项目根目录下的.prettierrc.js的配置作为自己的规则,这些定义的规则也会覆盖掉extends中的预设规则,如果遇到配置不生效的情况,关掉编辑器重新打开即可
module.exports = {
semi: false,
trailingComma: 'all',
endOfLine: 'auto',
tabWidth: 2,
singleQuote: true
// ... 可参考官方配置
}
这样就完成了ESLint+Typescript+Prettier的格式化配置,如果你的项目使用了Vue或React或是其他技术栈,只需要修改一下ESLint的规则即可,建议配置时根据自己的项目在这里挑选符合自己的依赖包
项目需要的依赖:
- eslint
- prettier
- typescript
- @typescript-eslint/parser
- @typescript-eslint/eslint-plugin
- eslint-config-prettier
- eslint-plugin-prettier
编辑器需要的插件(我们选择使用eslint来做autofix,不需要prettier插件)
- eslint
- typescript
完整的配置:
// .eslintrc.js
module.exports = {
env: {
browser: true,
node: true
},
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended'
], // 增加Prettier的核心规则
plugins: ['@typescript-eslint'],
rules: {
// semi: ["error", "always"],
// quotes: ["error", "double"],
'@typescript-eslint/no-explicit-any': 'error',
},
}
// setting.json
{
"eslint.validate": [
"javascript",
"typescript",
"javascriptreact",
"typescriptreact"
],
// 文件保存自动调用eslint --fix
"editor.codeActionOnSave": {
"source.fixAll.eslint": true
}
}
// .prettierrc.js
module.exports = {
semi: false,
trailingComma: 'all',
endOfLine: 'auto',
tabWidth: 2,
singleQuote: true
// ... 可参考官方配置
}
每次配置eslint都觉得依赖很多,但其实它的整体流程很简单,配置文件也不多
希望这篇文章可以帮助你理解ESLint是如何搭配其他插件完成代码格式化的
计划之后会加入git的提交验证,测试完后会写一篇文档来记录