eslint和prettier打架?

前端 0 1060 0
发表于: 2022-10-10 06:40:33

简介: 用最小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", // 这个插件一定要放在最后
  ],
};
eslint prettier

最后更新于:2022-10-11 12:01:46

欢迎评论留言~
0/400
支持markdown
Comments | 0 条留言
按时间
按热度
目前还没有人留言~