ITADN
prettier/eslint-config-prettier
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

eslint-config-prettier

关闭所有不必要的或可能与 Prettier 冲突的规则。

这让你可以使用你喜欢的共享配置,同时在使用 Prettier 时不让其风格选择妨碍你。

请注意,此配置 关闭规则,因此只有与其他配置一起使用时才有意义。

安装

  1. 安装 eslint-config-prettier:

    npm i -D eslint-config-prettier
    yarn add -D eslint-config-prettier
    pnpm add -D eslint-config-prettier
    bun add -D eslint-config-prettier
  2. 将 eslint-config-prettier 添加到你的 ESLint 配置中 – 无论是 eslintrc 还是 eslint.config.js (flat config)

    • eslintrc: 将 "prettier" 添加到你的 .eslintrc.* 文件中的 "extends" 数组。确保将其放在**最后,**以便它有机会覆盖其他配置。

      {
        "extends": [
          "some-other-config-you-use",
          "prettier"
        ]
      }
  • eslint.config.js(flat config):导入 eslint-config-prettier,并将其放入配置数组中 – 位于其他你希望覆盖的配置之后

    import someConfig from "some-other-config-you-use";
    // Note the `/flat` suffix here, the difference from default entry is that
    // `/flat` added `name` property to the exported object to improve
    // [config-inspector](https://eslint.org/blog/2024/04/eslint-config-inspector/) experience.
    import eslintConfigPrettier from "eslint-config-prettier/flat";
    
    export default [
      someConfig,
      eslintConfigPrettier,
    ];
  1. 最后,运行 CLI 辅助工具 以查找配置中 "rules" 部分的问题。

👉 正在使用 eslint-plugin-prettier?请查看 eslint-plugin-prettier 的推荐配置

插件

eslint-config-prettier 不仅会关闭 核心 规则,还会自动关闭来自以下插件的某些规则:

ℹ️ 注意:你可能会在互联网上看到指南,建议你也应该扩展诸如 "prettier/react" 之类的内容。从 eslint-config-prettier 的 8.0.0 版本开始,你只需要扩展 "prettier"!这包括所有插件。

eslint.config.js(扁平配置)插件注意事项

在使用扁平配置时,由你 来决定插件名称!例如:

import typescriptEslint from "@typescript-eslint/eslint-plugin";
import eslintConfigPrettier from "eslint-config-prettier/flat";

export default [
  {
    plugins: {
      // You’d typically use one of the following two:
      // typescriptEslint: typescriptEslint,
      // typescriptEslint,
      // But in this example we give it another name.
      // It might be tempting to use something shorter like “ts”:
      ts: typescriptEslint, // 🚨 Don’t do this!
    },
    rules: {
      // With eslintrc, this is _always_ called:
      // @typescript-eslint/indent
      // But in eslint.config.js (flat config), the name chosen above in `plugins` is used.
      "ts/indent": "error", // 🚨 Don’t do this!
    },
  },
  eslintConfigPrettier,
];

你可能期望 eslint-config-prettier 会关闭 ts/indent,但它不会!因为 eslint-config-prettier 只会关闭 @typescript-eslint/indent。它无法知道你将该插件命名为什么。CLI 辅助工具也是如此。

只需坚持使用官方插件名称,一切都会没问题。

如果你遇到一个使用非标准插件名称的共享 config,请要求他们改用标准名称。

排除已弃用的规则

eslint-config-prettier 关闭的一些规则可能已被弃用,甚至已从 ESLint 中移除。这完全没问题, 但如果你确实需要省略已弃用和已移除的规则,可以通过将 ESLINT_CONFIG_PRETTIER_NO_DEPRECATED 环境变量设置为非空值来实现。例如:

env ESLINT_CONFIG_PRETTIER_NO_DEPRECATED=true npx eslint-find-rules --deprecated index.js

CLI 辅助工具

eslint-config-prettier 还附带了一个小型 CLI 工具,帮助你检查配置中是否包含任何不必要的规则或与 Prettier 冲突的规则。以下是运行方法:

npx eslint-config-prettier path/to/main.js

(将 path/to/main.js 更改为你项目中存在的文件。)

是什么以及为什么

现在,让我们看看它的作用,以及你为什么可能想要使用它。

🚨 这个 eslintrc 示例启用了冲突规则 "indent"

{
  "extends": [
    "some-other-config-you-use",
    "prettier"
  ],
  "rules": {
    "indent": "error"
  }
}

对于 eslintrc,虽然 "prettier" 配置可以在 "some-other-config-you-use" 中禁用有问题的规则,但它无法触及 "rules"!(这就是 ESLint 的工作方式——它允许你覆盖所扩展的配置。)CLI 辅助工具报告 "indent" 与 Prettier 冲突,因此你可以将其移除。(这很好——简化了你的配置!)

🚨 这个 eslint.config.js(flat config)示例还启用了冲突规则 "indent"

import someConfig from "some-other-config-you-use";
import eslintConfigPrettier from "eslint-config-prettier/flat";

export default [
  someConfig,
  eslintConfigPrettier,
  {
    rules: {
      indent: "error",
    },
  },
];

使用新的 ESLint “flat config” 格式,你可以自行控制哪些配置覆盖哪些配置。解决上述冲突的一种方法是重新排列配置对象,使 eslint-config-prettier 位于最后:

import someConfig from "some-other-config-you-use";
import eslintConfigPrettier from "eslint-config-prettier/flat";

export default [
  someConfig,
  {
    rules: {
      indent: "error",
    },
  },
  eslintConfigPrettier, // eslint-config-prettier last
];

然而,查看上述配置可能会让人感到困惑。看起来我们启用了 indent 规则,但实际上由于下方的 eslintConfigPrettier 行,它已被禁用。相反,你可能希望在 eslint-config-prettier 之后拥有自己的规则,并运行 CLI 辅助工具来查找问题,从而可以完全从配置文件中移除冲突的规则(简化你的配置)。

检查多个文件

理论上,你需要为项目中的每个文件运行该工具,才能 100% 确定没有冲突的规则,因为 ESLint 支持为不同文件设置不同的规则。通常,你对所有文件使用大致相同的规则,因此在一个文件上运行命令就足够了。但如果你使用 multiple configuration filesoverrides,可以提供多个文件进行检查:

npx eslint-config-prettier index.js test/index.js legacy/main.js

退出码

  • 0: 未发现问题。
  • 1: 意外错误。
  • 2: 发现冲突的规则。

ESLINT_USE_FLAT_CONFIG 环境变量

与 ESLint 本身一样,你可以使用 ESLINT_USE_FLAT_CONFIG 环境变量来控制 eslint-config-prettier CLI 辅助工具:

  • ESLINT_USE_FLAT_CONFIG=true: 仅使用 eslint.config.js (flat config)。
  • ESLINT_USE_FLAT_CONFIG=false: 仅使用 eslintrc 文件。
  • 未设置或任何其他值: 先尝试 eslint.config.js,然后尝试 eslintrc。

警告
对于 eslint.config.js (flat config),CLI 辅助工具会导入 eslint/use-at-your-own-risk,这可能会随时失效。

遗留版本

7.0.0 之前的 eslint-config-prettier 版本具有一个略有不同的 CLI 工具,其运行方式也不同。例如:

npx eslint --print-config index.js | npx eslint-config-prettier-check

如果你在教程中看到类似的内容,在 7.0.0 或更高版本中,该命令的外观如下:

npx eslint-config-prettier index.js

特殊规则

eslint-config-prettier 禁用了少数实际上在某些情况下可以启用的规则。

  • 某些规则需要特定的选项。CLI 辅助工具会对此进行验证。
  • 某些规则在编写代码时需要特别注意。如果启用了这些规则,CLI 辅助工具会向你发出警告,但无法判断是否存在问题。
  • 如果同时使用 eslint-plugin-prettier--fix,某些规则可能会引发问题。

为了最大程度地方便使用,特殊规则默认是禁用的(前提是你已在 "extends" 中包含所有必需的内容)。如果你需要它们,需要在 ESLint 配置中显式指定。

arrow-body-styleprefer-arrow-callback

如果同时使用 eslint-plugin-prettier--fix,这些规则可能会引发问题。

有关详细信息,请参阅 arrow-body-styleprefer-arrow-callback 问题

有几种方法可以关闭这些规则:

  • 在你的 "extends" 中放入 "plugin:prettier/recommended"。这是 eslint-plugin-prettier 的推荐配置
  • 在你的 "extends" 中放入 "prettier/prettier"。(是的,既有一个名为 "prettier/prettier" 的_规则_,也有一个名为 "prettier/prettier" 的_配置_。)
  • 从你的配置中移除它们,或手动关闭它们。

使用哪种方法都无所谓。"plugin:prettier/recommended" 可能是最简单的。

注意:只有当 "prettier/prettier" 规则 对同一文件启用时,CLI 工具才会将这些规则报告为有问题。

如果你不使用 eslint-plugin-prettier,这些规则是安全的。换句话说,如果你将 eslint --fixprettier --write 作为单独的步骤运行。

curly

此规则需要特定选项。

如果一个代码块(例如在 ifelseforwhile 之后)仅包含一条语句,JavaScript 允许省略该语句周围的括号。此规则强制规定何时应省略这些可选的括号。

如果你使用 "multi-line""multi-or-nest" 选项,该规则可能与 Prettier 冲突。

例如,"multi-line" 选项允许以下行:

if (cart.items && cart.items[0] && cart.items[0].quantity === 0) updateCart(cart);

然而,Prettier 可能会认为该行过长,并将其转换为以下内容,而 "multi-line" 选项并不允许这样做:

if (cart.items && cart.items[0] && cart.items[0].quantity === 0)
  updateCart(cart);

如果你喜欢这条规则,只要不使用 "multi-line""multi-or-nest" 选项,就可以与 Prettier 配合使用。

ESLint 配置示例:

{
  "rules": {
    "curly": ["error", "all"]
  }
}

lines-around-comment (deprecated)

(以下内容同样适用于 @stylistic/lines-around-comment@stylistic/js/lines-around-comment@stylistic/ts/lines-around-comment@typescript-eslint/lines-around-comment。)

此规则可以配合某些选项使用。

此规则要求注释前和/或注释后有空行。Prettier 会保留空行,但有两个例外:

  • 连续的多行空行会被合并为单行空行。这没有问题。
  • 块、对象和数组开头和结尾的空行总是会被移除。这可能会导致冲突。

默认情况下,ESLint 在此情况下要求注释上方有空行:

if (result) {

  /* comment */
  return result;
}

然而,Prettier 会移除空行:

if (result) {
  /* comment */
  return result;
}

如果你喜欢这条规则,只要添加一些额外的配置以允许在块、对象和数组的开头和结尾处使用注释,就可以与 Prettier 一起正常使用。

ESLint 配置示例:

{
  "rules": {
    "lines-around-comment": [
      "error",
      {
        "beforeBlockComment": true,
        "afterBlockComment": true,
        "beforeLineComment": true,
        "afterLineComment": true,
        "allowBlockStart": true,
        "allowBlockEnd": true,
        "allowObjectStart": true,
        "allowObjectEnd": true,
        "allowArrayStart": true,
        "allowArrayEnd": true
      }
    ]
  }
}

max-len (deprecated)

(以下内容同样适用于 @stylistic/max-len@stylistic/js/max-lenvue/max-len。)

编写代码时,此规则需要特别关注。

通常,Prettier 会自动处理最大行长的限制。然而,在某些情况下 Prettier 无能为力,例如长字符串、正则表达式和注释。这些需要由人工进行拆分。

如果您希望强制执行比 Prettier 自动提供的更严格的最大行长策略,可以启用此规则。请记住保持 max-len 的选项与 Prettier 的 printWidth 选项同步。

请注意,如果 Prettier 以 max-len 规则不认可的方式格式化行,您可能需要对代码进行轻微重构。

ESLint 配置示例:

{
  "rules": {
    "max-len": ["error", {"code": 80, "ignoreUrls": true}]
  }
}

no-confusing-arrow(已弃用)

(以下内容同样适用于 @stylistic/no-confusing-arrow@stylistic/js/no-confusing-arrow。)

此规则需要特定选项。

例如,该规则可能会警告以下这一行:

var x = a => 1 ? 2 : 3;

使用 {allowParens: true}(自 ESLint 6.0.0 起的默认值),添加括号被视为避免箭头混淆的有效方式:

var x = a => (1 ? 2 : 3);

虽然 Prettier 会保留这些括号,但如果该行足够长以至于需要引入换行,它会将它们移除:

EnterpriseCalculator.prototype.calculateImportantNumbers = inputNumber =>
  1 ? 2 : 3;

使用 {allowParens: false} 时,ESLint 建议改为显式 return:

var x = a => { return 1 ? 2 : 3; };

这不会导致 Prettier 出现问题。

如果你喜欢这条规则,只要 allowParens 选项处于关闭状态,就可以与 Prettier 配合使用。

ESLint 配置示例:

{
  "rules": {
    "no-confusing-arrow": ["error", { "allowParens": false }]
  }
}

(注:CLI 辅助工具将 {allowParens: true} 视为默认值,自 ESLint 6.0.0 起即为如此。即使你使用的是旧版本的 ESLint,若使用默认值,该工具也会产生警告。尽管在技术上略显冗余,但显式设置 {allowParens: false} 并无害处。这样你可以为未来的 ESLint 升级做好准备,同时保持 CLI 工具的简洁性。)

no-mixed-operators(已弃用)

(以下内容同样适用于 @stylistic/no-mixed-operators@stylistic/js/no-mixed-operators。)

编写代码时,此规则需要特别关注。

此规则禁止混合使用某些运算符,例如 &&||

例如,该规则可能会警告以下这一行:

var foo = a + b * c;

该规则建议添加括号,如下所示:

var foo = a + (b * c);

然而,Prettier 会移除许多“不必要的”括号,将其还原为:

var foo = a + b * c;

如果你想将此规则与 Prettier 一起使用,你需要将该表达式拆分到另一个变量中:

var bar = b * c;
var foo = a + bar;

请记住,Prettier 会打印_一些_“不必要的”括号,不过:

var foo = (a && b) || c;

ESLint 配置示例:

{
  "rules": {
    "no-mixed-operators": "error"
  }
}

no-tabs (deprecated)

(以下内容同样适用于 @stylistic/no-tabs@stylistic/js/no-tabs。)

此规则需要特定选项。

此规则禁止使用制表符。默认情况下,该规则禁止使用_所有_制表符。只要你不将 Prettier 配置为使用制表符进行缩进,就可以与 Prettier 配合良好使用。

幸运的是,可以配置该规则,使其无论 Prettier 使用空格还是制表符都能正常工作:将 allowIndentationTabs 设置为 true。这样,Prettier 负责处理你的缩进,而 no-tabs 负责处理代码中其他位置可能存在的制表符。

ESLint 配置示例:

{
  "rules": {
    "no-tabs": ["error", {"allowIndentationTabs": true}]
  }
}

no-unexpected-multiline

编写代码时,此规则需要特别关注。

此规则禁止令人困惑的多行表达式,其中换行符看似结束了语句,但实际上并未结束。

例如,该规则可能会对此发出警告:

var hello = "world"
[1, 2, 3].forEach(addNumber)

Prettier 通常会以一种明显表明缺少分号的方式格式化此代码:

var hello = "world"[(1, 2, 3)].forEach(addNumber);

然而,在某些情况下,Prettier 会将内容拆分为多行,从而导致 no-unexpected-multiline 发生冲突。

const value = text.trim().split("\n")[position].toLowerCase();

不过,Prettier 会将其拆分为多行,从而导致冲突:

const value = text
  .trim()
  .split("\n")
  [position].toLowerCase();

如果你喜欢这条规则,它通常可以与 Prettier 一起使用而不会出现问题,但偶尔你可能需要暂时禁用该规则或重构你的代码。

const value = text
  .trim()
  .split("\n")
  // eslint-disable-next-line no-unexpected-multiline
  [position].toLowerCase();

// Or:

const lines = text.trim().split("\n");
const value = lines[position].toLowerCase();

注意: 如果你 确实 启用了此规则,你必须将 ESLint 和 Prettier 作为两个独立的步骤运行(且先运行 ESLint),才能从中获得任何价值。否则,Prettier 可能会以某种方式重新格式化你的代码,导致 ESLint 永远没有机会报告任何问题(如第一个示例所示)。

示例配置:

{
  "rules": {
    "no-unexpected-multiline": "error"
  }
}

quotes (已弃用)

(以下内容同样适用于 babel/quotes@stylistic/quotes@stylistic/js/quotes@stylistic/ts/quotes@typescript-eslint/quotes。)

此规则需要特定的选项和特定的 Prettier 选项。

通常,你完全不需要此规则。但有两种情况下它可能有用:

  • 强制字符串使用反引号,而不是单引号或双引号。
  • 禁止在可以使用常规字符串的地方使用反引号。

强制使用反引号

如果你希望所有字符串都使用反引号(从不使用引号),请启用 "backtick" 选项。

ESLint 配置示例:

{
  "rules": {
    "quotes": ["error", "backtick"]
  }
}

禁止不必要的反引号

在以下示例中,第一个数组项本可以用引号而非反引号来书写。

const strings = [
  `could have been a regular string`,
  `
    multiple
    lines
  `,
  `uses ${interpolation}`,
  String.raw`\tagged/`,
];

如果你希望 ESLint 强制执行 `could have been a regular string` being written as either "could have been a regular string" or 'could have been a regular string', you need to use some specific configuration. The quotes 规则,该规则有两个选项:一个字符串选项和一个对象选项。

  • 第一个(字符串)选项需要设置为 "single""double",并与 Prettier 的 singleQuote 选项保持同步。
  • 第二个(对象)选项需要以下属性:
双引号配置示例

ESLint:

{
  "rules": {
    "quotes": [
      "error",
      "double",
      { "avoidEscape": true, "allowTemplateLiterals": false }
    ]
  }
}

Prettier(这是默认设置,因此无需添加):

{
  "singleQuote": false
}
单引号配置示例

ESLint:

{
  "rules": {
    "quotes": [
      "error",
      "single",
      { "avoidEscape": true, "allowTemplateLiterals": false }
    ]
  }
}

Prettier:

{
  "singleQuote": true
}

unicorn/template-indent

此规则可与某些选项配合使用。

此规则会自动修复多行字符串模板的缩进,使其与其所在的代码保持对齐。使用可配置的白名单可确保不会编辑对空白字符敏感的字符串。

Prettier 处理以下内容:

  • HTML
  • CSS
  • GraphQL
  • markdown

通过使用各种标签、函数和注释。

unicorn/template-indent 默认情况下会格式化部分相同的标签模板,这可能会导致冲突。例如,该规则与 Prettier 在三元运算符中的缩进上存在分歧:

condition
  ? null
  : html`
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam in dui
        mauris.
      </p>
    `;

如果你喜欢这条规则,只要配置该规则不去处理与 Prettier 相同的模板,就可以与 Prettier 一起正常使用。

ESLint 配置示例:

{
  "rules": {
    "unicorn/template-indent": [
      "error",
      {
        "tags": [
          "outdent",
          "dedent",
          "sql",
          "styled"
        ],
        "functions": [
          "dedent",
          "stripIndent"
        ],
        "selectors": [],
        "comments": [
          "indent"
        ]
      }
    ]
  }
}

注意:如果你使用 "selectors",CLI 辅助工具无法检测你的选择器是否可能导致冲突。

vue/html-self-closing

此规则需要某些选项。

此规则强制规定元素是否应使用自闭合标签。

Prettier 通常会保留你编写元素的方式:

<div />
<div></div>
<MyComponent />
<MyComponent></MyComponent>
<svg><path d="" /></svg>
<svg><path d=""></path></svg>

但对于已知的 void HTML 元素,Prettier 始终使用自闭合样式。例如,<img> 会被转换为 <img />

如果你喜欢这条规则,只要将 html.void 设置为 "any",就可以与 Prettier 配合使用。

ESLint 配置示例:

{
  "rules": {
    "vue/html-self-closing": [
      "error",
      {
        "html": {
          "void": "any"
        }
      }
    ]
  }
}

其他值得提及的规则

这些规则与 Prettier 不冲突,但与 Prettier 一起使用时存在一些陷阱。

no-sequences

此规则禁止使用 JavaScript 中令人困惑的逗号运算符(序列表达式)。以下代码的实际行为与其表面看起来的不同:

matrix[4, 7];

Prettier 会为上述代码添加括号,以明确表明使用了序列表达式:

matrix[(4, 7)];

然而,no-sequences 规则允许使用逗号运算符,前提是表达式序列被显式地包裹在括号中。由于 Prettier 会自动将它们包裹在括号中,你可能永远不会看到 ESLint 关于逗号运算符的任何警告。

在重构过程中,意外产生序列表达式是很容易发生的。如果你希望 ESLint 能够捕获此类错误,建议通过 no-restricted-syntax (no-sequences 文档中所述) 完全禁止序列表达式:

{
  "rules": {
    "no-restricted-syntax": ["error", "SequenceExpression"]
  }
}

如果你仍然需要在某些边缘情况下使用逗号运算符,你可以在表达式上方的行上放置一个 // eslint-disable-next-line no-restricted-syntax 注释。如果你使用 no-restricted-syntax 方法,则可以安全地禁用 no-sequences

如果你愿意,还可以提供自定义消息:

{
  "rules": {
    "no-restricted-syntax": [
      "error",
      {
        "selector": "SequenceExpression",
        "message": "The comma operator is confusing and a common mistake. Don’t use it!"
      }
    ]
  }
}

贡献

请参阅 package.json 以获取 eslint-config-prettier 所测试的 ESLint、Prettier 及 ESLint 插件的确切版本。

自这些版本以来是否添加了新规则?我们是否遗漏了任何规则?是否有您希望看到排除配置的插件?请提交 issue 或 pull request!

如果您想为 eslint-plugin-foobar 添加支持,操作方式如下:

首先,将规则添加到 index.js

"foobar/some-rule": "off"

然后,创建 test-lint/foobar.js

/* eslint-disable quotes */
"use strict";

// Prettier does not want spaces before the parentheses, but
// `plugin:foobar/recommended` wants one.
console.log();

test-lint/foobar.js 在与 eslint-plugin-foobar 和 eslint-plugin-prettier 同时使用时必须失败 – 直到将 eslint-config-prettier 添加到 ESLint 配置中。该文件应按照 Prettier 进行格式化,且该格式化结果应与插件产生冲突。

最后,你需要在几个地方提及该插件:

  • 将 eslint-plugin-foobar 添加到 package.json 中的 "devDependencies" 字段。
  • 确保至少一条来自 eslint-plugin-foobar 的规则在 .eslintrc.base.jseslint.base.config.js 中被使用。
  • 将其添加到本 README.md 中支持的插件列表中。

完成后,运行 npm test 以验证你是否全部正确。它会运行其他几个 npm 脚本:

  • "test:prettier" 检查是否已对所有文件运行了 Prettier。
  • "test:eslint" 确保 test-lint/ 中的文件在使用 eslint-config-prettier 的排除项时通过 ESLint。它还会对 eslint-config-prettier 本身的代码进行 lint 检查。
  • "test:lint-verify-fail"test/lint-verify-fail.test.js 中的一个测试运行。
  • "test:lint-rules"test/rules.test.js 中的一个测试运行。
  • "test:jest" 运行单元测试,检查多项内容:
    • eslint-plugin-foobar 在上述所有位置均被提及。
    • 没有未知的规则被关闭。这有助于捕获拼写错误等。
    • CLI 正常工作。
  • "test:cli-sanity""test:cli-sanity-warning" 是 CLI 的健全性检查。

License

MIT.