eslint和prettier打架?
简介: 用最小case测试~
prettier和eslint
eslint其实最主要是是语法校验,但是eslint也有一丢丢的格式化方面校验,那prettier也是做代码格式化的,两者之间就会打架,本篇文章主要讲将如何让eslint和prettier不起冲突,文章的结尾总结以eslint怂了结尾hhh
假设eslint使用了airbnb:
// .eslintrc.js
console.log(' INFO 读取了: .eslintrc.js');
module.exports = {
extends: [
"airbnb-base", // airbnb要求字符串是单引号
],
};
此时eslint就会要求字符串都使用单引号(因为airbnb要求的),而我们的代码的字符串没有使用单引号,而使用了双引号的话:
// a.js
const a = "1";
执行npx eslint --config ./.eslintrc.js a.js
命令的时候,就会报错:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Strings must use singlequote quotes
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
注意这是airbnb的eslint规则,本质还是是eslint报的错,我们直接改成将a.js文件里的字符串改成单引号就好了。
// a.js
const a = '1';
此时执行npx eslint --config ./.eslintrc.js a.js
命令的时候,quotes报错就没有了:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
✖ 1 problem (1 error, 0 warnings)
➜ utils git:(master) ✗
但是,如果我们的项目里面使用了prettier的话,或者说我们的项目并没有安装prettier这个npm包,但是项目里面有prettier的配置文件.prettierrc.js:
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: false, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
而我们的vscode编辑器又安装了prettier插件,那么编辑器的插件就会读取这个.prettierrc.js配置,然后在保存的时候自动帮我们格式化,此时就会导致编辑器帮我们把字符串的引号全都格式化成双引号,这是编辑器的行为,我们命令行执行eslint命令的时候实际是不会管这个prettier配置文件的!
原本a.js的字符串是单引号,但是由于vscode编辑器配置了prettier插件的原因,保存的时候自动将字符串的单引号改成了双引号:
// a.js
const a = "1";
此时再执行npx eslint --config ./.eslintrc.js a.js
命令
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Strings must use singlequote quotes
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
结果一眼就看出来了,prettier配置文件的打印没有输出,说明了eslint并没有读取这个prettier文件,而结果也是报错说字符串必须使用单引号,其实对eslint来说只要是字符串使用了双引号,eslint就会给你报错,eslint才不管是你手写的双引号还是编辑器给你格式化成的双引号。
eslint-plugin-prettier
此时就会有一个问题,我希望Airbnb的eslint规则生效,又希望我的prettier规则也生效,那么就得让eslint和prettier产生关联,那么首先就先安装这两插件
npm install --save-dev eslint-plugin-prettier prettier
然后修改.eslintrc.js
// .eslintrc.js
console.log(' INFO 读取了: .eslintrc.js');
module.exports = {
extends: [
"airbnb-base", // airbnb要求字符串是单引号
],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error',
},
};
此时的.prettierrc.js
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: false, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
此时的a.js
// a.js
const a = '1';
执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Replace `'1'` with `"1"` prettier/prettier
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
此时可以看到结果是 prettier的规则生效了(控制台输出了prettier配置文件里面的打印),prettier要求将字符串的单引号替换成双引号,那么我们就替换试试:
// a.js
const a = "1";
再执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Strings must use singlequote quotes
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,符合了prettier的规则后,又轮到了Airbnb的eslint的规则报错了,Airbnb的eslint的规则要求字符串得是单引号,这不又冲突了吗,你可以将prettier配置文件改成单引号,这样就肯定不会冲突了,因为都是单引号
修改prettier配置
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: true, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
修改a.js
// a.js
const a = '1';
再执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
✖ 1 problem (1 error, 0 warnings)
➜ utils git:(master) ✗
此时就不冲突了,因为我们都使用了单引号,我们把把a.js的字符串改成双引号再看看结果
// a.js
const a = "1";
再执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Replace `"1"` with `'1'` prettier/prettier
1:11 error Strings must use singlequote quotes
✖ 3 problems (3 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,很明显prettier和eslint都要求使用单引号,这样肯定不冲突,那这样岂不是prettier向eslint妥协了?其实你也可以改eslint的规则,让eslint要求字符串使用双引号,让eslint兼容prettier
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: false, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
// .eslintrc.js
console.log(' INFO 读取了: .eslintrc.js');
module.exports = {
extends: [
"airbnb-base", // airbnb要求字符串是单引号
],
plugins: ["prettier"],
// rules优先级最高,会覆盖上面的
rules: {
// quotes: ["error", "double"], // 要求尽可能使用双引号
"prettier/prettier": "error",
quotes: ["error", "double"], // 这个规则不管写在哪都会覆盖prettier的singleQuote
},
};
// a.js
const a = "1";
再执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:15 error Insert `⏎` prettier/prettier
1:15 error Newline required at end of file but not found eol-last
✖ 3 problems (3 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到这样字符串就可以使用双引号了,因为eslint要求使用字符串使用双引号,而prettier配置也是双引号,两者兼容。
eslint-config-prettier
那如果有prettier和eslint有很多规则冲突,得一个个的改吗,有没有办法不手动的改他们的配置,也能让他们不冲突,其实有的,使用eslint-config-prettier这个插件就可以了
npm install --save-dev eslint-config-prettier
修改eslint配置
// .eslintrc.js
console.log(' INFO 读取了: .eslintrc.js');
module.exports = {
extends: [
"airbnb-base", // airbnb要求字符串是单引号
"plugin:prettier/recommended", // 这个插件一定要放在最后
],
};
此时的prettier配置
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: false, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
此时的a.js
// a.js
const a = "1";
执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:15 error Insert `⏎` prettier/prettier
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,感觉上好像是prettier的配置生效了,我们将a.js使用单引号再试试
// a.js
const a = '1';
执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Replace `'1';` with `"1";⏎` prettier/prettier
✖ 2 problems (2 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,确实是prettier配置生效了,其实是因为eslint-config-prettier这个插件,它关闭了所有和格式化相关的eslint规则,其实就是在格式化方面,让eslint向prettier妥协了(注意,仅仅是格式化相关的代码),约等于就是给rules添加了 quotes: 0
,我们可以不用eslint-config-prettier插件,用eslint-plugin-prettier插件,然后再手动关闭所有的格式化eslint规则,也能达到效果:
// .prettierrc.js
console.log(' INFO 读取了: .prettierrc.js');
module.exports = {
singleQuote: false, // 默认为false。即要求:const a = "1";,可改为true,即要求const a = '1';
};
// .eslintrc.js
console.log(' INFO 读取了: .eslintrc.js');
module.exports = {
extends: [
"airbnb-base", // airbnb要求字符串是单引号
],
plugins: ["prettier"],
// rules优先级最高,会覆盖上面的
rules: {
"prettier/prettier": "error",
quotes: 0, // 关闭对字符串引号的校验
},
};
// a.js
const a = '1';
执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:11 error Replace `'1';` with `"1";⏎` prettier/prettier
1:15 error Newline required at end of file but not found eol-last
✖ 3 problems (3 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,好像是prettier的规则生效了,我们再把a.js的字符串改成双引号试试
// a.js
const a = "1";
执行 npx eslint --config ./.eslintrc.js a.js
:
➜ utils git:(master) ✗ npx eslint --config ./.eslintrc.js a.js
INFO 读取了: .eslintrc.js
INFO 读取了: .eslintrc.js
INFO 读取了: .prettierrc.js
/Users/huangshuisheng/Desktop/hss/github/billd/packages/utils/a.js
1:7 error 'a' is assigned a value but never used no-unused-vars
1:15 error Insert `⏎` prettier/prettier
1:15 error Newline required at end of file but not found eol-last
✖ 3 problems (3 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
➜ utils git:(master) ✗
可以看到,在格式化这方面,确确实实的是以prettier的规则为准了~
代码格式化最佳实践
总结来说,就是让关闭eslint的所有格式化相关规则,使用prettier的规则作为格式化的标准~
首先装这三个包
npm i eslint-plugin-prettier eslint-config-prettier prettier -D
然后配置你的prettier配置文件,然后在eslint配置文件的extend数组最后最后添加 "plugin:prettier/recommended"
即可:
// .eslintrc.js
module.exports = {
extends: [
// ...
"plugin:prettier/recommended", // 这个插件一定要放在最后
],
};
最后更新于:2022-10-11 12:01:46