解决Eslint 和 Prettier 之间的冲突

30,033 阅读3分钟

前言

最近学习前端的时候,在项目中同时使用了 eslintprettier,结果这两个工具相互冲突,经过一番查阅资料得以解决,仅做学习笔记记录下来。

冲突的原因

项目中使用了vscodeeslintprettier插件,并开启了保存时自动格式化和自动修复代码的功能,配置如下:

// .vscode/setting.json
{ 
  // 保存时 prettier 自动格式化
  "editor.formatOnSave": true,
  // 保存时自动启用 eslint --fix 自动修复
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

// .eslintrc
{
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": ["eslint:recommended", "standard"],
  "parserOptions": {
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["import", "node", "promise"],
  "rules": {}
}

// .prettierrc 
{
   // 使用双引号
  "singleQuote": false,
  // 每行末尾添加分号
  "semi": true
}

结果提示以下错误:

image.png 这里显示错误的原因是我在eslint中继承了eslint-config-standard,这套规则中推荐使用单引号,行末不添加分号,这与我的prettier配置相互冲突。理想状态下,由于开启了fixAll:true, 那么 eslint --fix 在保存时应该会自动启动,按道理讲这个错误应该被修复,但是屏幕一闪之后又回到了这个状态。经过查阅资料,发现是因为eslint 的 规则和 prettier 相冲突了,保存时先启用了 eslint --fix 修复了,然后又运行了 prettier 格式化,所以屏幕一闪又回到了这个状态。

解决办法

冲突的本质在于 eslint既负责了代码质量检测,又负责了一部分的格式美化工作,格式化部分的部分规则和 prettier不兼容。 能不能让eslint只负责代码质量检测而让prettier负责美化呢? 好在社区有了非常好的成熟方案,即 eslint-config-prettier + eslint-plugin-prettier

  • eslint-config-prettier 的作用是关闭eslint中与prettier相互冲突的规则。
  • eslint-plugin-prettier 的作用是赋予eslintprettier格式化代码的能力。 安装依赖并修改.eslintrc文件
// 安装依赖
yarn add eslint-config-prettier eslint-plugin-prettier -D

// .eslintrc
{
   // 其余的配置
 - "extends": ["eslint:recommended", "standard"]
 + "extends": ["eslint:recommended", "standard",  "plugin:prettier/recommended"]
  // 其余的配置
}

关键在于新增加的 plugin:prettier/recommended 这个规则。让我们看看它具体做了什么

// node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js
module.exports = {
  // plugin:prettier/recommended 就是加载这个
  configs: {
    recommended: {
      extends: ['prettier'],
      plugins: ['prettier'],
      rules: {
        'prettier/prettier': 'error',
        'arrow-body-style': 'off',
        'prefer-arrow-callback': 'off',
      },
    },
  },
  // 其他的
}

plugin:prettier/recommended 这个语法就是加载了 node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js 文件导出的 configs 中的 recommended 配置项。下面解析他们分别做了什么。

  1. extends: ['prettier']: 通过 eslint-config-prettier 关闭eslintprettier 相冲突的规则。
  2. plugins: ['prettier']: 加载 eslint-plugin-prettier,赋予 eslintprettier 格式化文档的功能
  3. 'prettier/prettier': 'error': 让代码文件中不符合prettier格式化规则的都标记为错误,结合vscode-eslint插件便可以看到这些错误被标记为红色,当运行eslint --fix 命令时,将自动修复这些错误。
  4. arrow-body-styleprefer-arrow-callback: 这两个规则在eslintprettier 中存在不可解决的冲突,所以关闭掉。

至此, prettiereslint 便可以无冲突协作,保存时候也能自动修复并格式化代码了。

注意事项

如果修改了.prettierrc的配置选项,会发现 eslintprettier又冲突了,这是因为vscode插件缓存没有及时更新,重启下vscode即可。

总结

eslint 既负责检测代码质量又负责格式化,导致格式化时与 prettier 冲突。 正所谓术业有专攻,格式化代码这等专业的事情就应该交给prettier 来做。 通过 eslint-plugin-prettier + eslint-config-prettier 可以完美地解决冲突,使得二者能相互协作。

这篇文章只是简单地描述了eslintprettier冲突的原因和解决办法。等有时间了再写一篇 eslint + prettier + husky + lint-staged + commit-lint 的终极指南,确保项目的代码质量。