ESLint(包括其他一些 lint 工具)的主要功能包含代码格式和代码质量的校验。
Prettier 是一款代码格式化工具,用于检测代码中的格式问题,比如单行代码长度、tab长度、空格、逗号表达式等。在功能职责上,ESlint 偏向于把控项目的代码质量,而 Prettier 更偏向于统一项目的编码风格。
在 ESlint 推出 --fix 参数前,ESLint 并没有自动化格式代码的功能,要对一些格式问题做批量格式化只能用 Prettier 这样的工具。并且,Prettier 在代码风格的检测上比 ESlint 更全面,所以两者通常是结合在一起使用的。
vscode
中安装插件后,如果项目根目录下有 .eslintrc.js
和 .prettierrc
配置文件,VSCode 插件会自动读取配置文件中的配置检查你的代码和格式化文件。"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.enable": true, // eslint生效
"eslint.options": {
// 执行eslint命令的时候有效
"extensions": [".js", ".vue", ".ts", ".tsx"]
},
"editor.formatOnSave": true,
"eslint.validate": [
// eslint检查的语言
"javascript",
"javascriptreact",
{
"language": "html",
"autoFix": true
},
{
"language": "vue",
"autoFix": true
},
{
"language": "typescript",
"autoFix": true
},
{
"language": "typescriptreact",
"autoFix": true
}
],
"eslint.trace.server": "verbose",
# 直接利用cra初始化一个项目
yarn create create-react-app my-app --template typescript
yarn add eslint --dev
生成配置文件.eslintrc.js
,如果没有配置该文件,那么在vscode
的输出面板中可以看到报错。
./node_modules/.bin/eslint --init
创建.eslintignore
文件
build
output
node_modules
src/idl
lib
.temp/
mock.js
.eslintrc.js
idl/
yarn add prettier --dev
生成配置文件.prettier.js
module.exports = {
semi: true,
trailingComma: "all",
singleQuote: true,
jsxSingleQuote: false,
printWidth: 120,
tabWidth: 2,
useTabs: false,
arrowParens: "avoid",
endOfLine: "auto",
};
yarn add @typescript-eslint eslint-plugin-react eslint-config-prettier eslint-plugin-prettier --dev
.eslintrc.js
文件module.exports = {
extends: [
'eslint:recommended', // 继承eslint官方推荐的一些配置
'plugin:@typescript-eslint/recommended', // 继承了一个由typesript官方提供的适合于ts代码检查的配置
"plugin:react/recommended", // 继承了一个由react官方提供的适合于ts代码检查的配置
"prettier" // 由于eslint和prettier都具备代码格式化的功能,并且可能出现冲突,所以继承eslint-config-prettier提供的配置,将eslint中冲突的配置项关闭了
],
parser: '@typescript-eslint/parser', // eslint默认的parser只能解析js,所以配置了parser
plugins: [
'prettier' // 注册eslint-plugin-prettier插件
],
parserOptions: { // 对parser进行配置
warnOnUnsupportedTypeScriptVersion: false,
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
rules: {
// 开启eslint-plugin-prettier中的prettier规则
// 开启这条规则后,会将prettier的校验规则传递给eslint,这样eslint就可以按照prettier的方式来进行代码格式的校验
"prettier/prettier": "error"
}
}
Eslint中plugins和extends的区别
eslint通过配置多条rules来执行lint校验。比如下面配置了一条eslint规则
// .eslintrc.js
module.exports = {
rules: {
'quotes': 'error' // 字符串必须使用双引号,否则报错
}
}
对于一些特性的场景,eslint默认提供的rules可能不能满足需求,此时可通过配置plugin插件来扩展可用的规则。比如插件eslint-plugin-react
中实现了一些react项目中需要的校验规则。
// eslint-plugin-react
module.exports = {
rules: {
'jsx-boolean-value': {
meta: {
docs: {
description: 'Enforce boolean attributes notation in JSX',
category: 'Stylistic Issues',
recommended: false,
url: docsUrl('jsx-boolean-value')
},
fixable: 'code'
},
create(context) {}
}
// ...
},
}
那插件中新增的规则,如何应用的自己的项目呢?
yarn add eslint-plugin-react --dev
// .eslintrc.js
module.exports = {
plugins: [
'eslint-plugin-react' // 加载插件
],
rules: {
'eslint-plugin-react/jsx-boolean-value': 2 // 开启插件中的特定规则
}
}
Eslint中plugins和extends的区别
上面plugins和rules的结合能解决扩展规则的问题,但是一条一条的开启规则的过程并不友好,extends提供了集成的配置方案。
以上述的eslint-plugin-react为例,它实现了多种配置规则,为了方便其他人使用,它默认实现了两种最佳实践all以及recommened(在configs中可以看到具体的名称)
通过extends可以直接继承配置好的最佳实践。
module.export = {
extends: [
'eslint-plugin-react/recommended'
]
}
ESLint 之解析包名
以 eslint:
开头,加载 ESLint 内置规则
如果是 eslint:recommended
,加载 ESLint 推荐的规则;
如果是 eslint:all
,加载 ESLint 所有的规则;
以 plugin: 开头
首先分离出 pluginName,它就是 plugin: 和最后一个 / 的之间部分;有如下几种情况:
plugin:@typescript-eslint/recommended
的 pluginName 是 @typescript-eslint
;
plugin:@typescript-eslint/eslint-plugin/recommended
的 pluginName 是 @typescript-eslint/eslint-plugin
;
plugin:@typescript-eslint/test/recommended
的 pluginName 是 @typescript-eslint/test
;
plugin:@typescript-eslint/eslint-plugin-irene/recommended
的 pluginName 是 @typescript-eslint/eslint-plugin-irene
;
plugin:prettier/recommended
的 pluginName 是 prettier
;
然后根据 pluginName 得到标准化的包名;
如果 pluginName 以 @ 开头,说明使用的是 scoped modules;有如下几种情况:
pluginName 是 @scopeName
或 @scopeName/eslint-plugin
,对应的包名是 @scopeName/eslint-plugin
;
@typescript-eslint
对应的是 @typescript-eslint/eslint-plugin
;
@typescript-eslint/eslint-plugin
对应的是 @typescript-eslint/eslint-plugin
;
pluginName 是 @scopeName/xxx
,且 xxx 不以 eslint-plugin
开头,对应的包名是 @scopeName/eslint-plugin-xxx
;
@typescript-eslint/test
对应的是 @typescript-eslint/eslint-plugin-test
;
pluginName 是 @scopeName/eslint-plugin-xxx
,对应的包名是 @scopeName/eslint-plugin-xxx
;
@typescript-eslint/eslint-plugin-irene
对应的是 @typescript-eslint/eslint-plugin-irene
;
如果 pluginName 不以 eslint-plugin- 开头,对应的包名是 eslint-plugin-xxx;例如:prettier 对应的是 eslint-plugin-prettier;
ESLint 之与 Prettier 配合使用
冲突问题
假如这样一行代码 const a = "irene"
,用 Prettier 格式化后变成了 const a = 'irene'
,再用 ESLint 去检测,就会报 Strings must use doublequote;
当你用 eslint --fix
自动修复这个问题后又无法通过 Prettier 的校验,结果陷入死循环。
解决方案
思路:禁掉 ESLint 中与 Prettier 冲突的规则,然后使用 Prettier 做格式化, ESLint 做代码校验。
社区提出了这样一种解决方案:
目的:使用 eslint --fix 就能完成格式化和校验的工作,格式化使用 Prettier,代码校验使用 ESLint。
具体步骤:
首先禁掉 ESLint/插件 中与 Prettier 冲突的规则,创建一个包 eslint-config-prettier,里面定义了被禁掉的 ESLint/插件 规则。(这个包中值是禁用了一些规则,没有新增规则。https://github.com/prettier/eslint-config-prettier/blob/main/index.js)
创建一个插件 eslint-plugin-prettier,定义一条规则 prettier/prettier,调用 Prettier,配合 ESLint 实现运行 eslint --fix
按 Prettier 规则自动格式化代码。
{
extends: [
..., // 其他
"prettier", // eslint-config-prettier
]
plugins: ["prettier"], // 注册eslint-plugin-prettier
rules: {
"prettier/prettier": "error" // 开启规则
}
}