【问题标题】:Airbnb, ESLint, Prettier conflict over Switch and Case indentationAirbnb、ESLint、Prettier 在 Switch 和 Case 缩进上的冲突
【发布时间】:2019-10-10 07:45:40
【问题描述】:

我正在设置我的 React Redux 项目以将 ESLint 与 Airbnb 配置和 Prettier 一起使用。我一直在按照我想要的方式修改某些内容,但现在我遇到了我似乎无法修复的 switch 和 case 语句的缩进问题。

我正在 VSCode 中编辑我的项目。我点击错误并使用 ESLint 修复,将缩进减少 4 个空格,但随后 Prettier 出现更多错误,要求将所有内容重新缩进 4 个空格。

我想改变的一个关键是缩进:我想为制表符使用 4 个空格,并相应地调整了我的设置。我对 switch/case 缩进没有强烈的意见(从 switch 缩进的 case 更可取,但无论如何),我只是不想得到错误。

我已经安装了:

prettier
eslint
eslint-config-airbnb
eslint-plugin-import
eslint-plugin-jsx-a11y
eslint-plugin-react
eslint-import-resolver-webpack
eslint-config-prettier
eslint-plugin-prettier

我的.eslintrc.json 文件的相关部分:

{
    "extends": ["airbnb", "prettier", "prettier/react"],
    "plugins": ["react", "prettier"],
    "rules": {
        "react/jsx-filename-extension": [
            1,
            {
                "extensions": [".js", "jsx"]
            }
        ],
        "prettier/prettier": "error",
        "indent": ["error", 4, { "SwitchCase": 1 }],
        "react/jsx-indent": ["error", 4],
        "react/jsx-indent-props": ["error", 4],
        "class-methods-use-this": 0,
        "no-else-return": 0,
        "no-plusplus": [2, { "allowForLoopAfterthoughts": true }],
        "no-param-reassign": 0
    },

package.json 中的其他设置(需要正确设置标签宽度):

  "prettier": {
    "tabWidth": 4
  }

还有代码,cmets 会指出哪些行出现错误(这是针对刽子手游戏的):

    switch (action.type) {
        case GUESS_LETTER:
            return Object.assign(
                {},
                state,
                state.guessWord.includes(action.guessLetter)
                    ? addCorrectGuess(
                          state.rightLetters.slice(), // <-- error here!
                          action.guessLetter, // <-- error here!
                          state.guessWord // <-- error here!
                      ) // <-- error here!
                    : addWrongGuess(
                          state.wrongLetters.slice(), // <-- error here!
                          action.guessLetter // <-- error here!
                      ) // <-- error here!
            );

我第一次尝试将{ "SwitchCase": 1 } 添加到 ESLint 配置文件中。这减少了错误的数量(几乎是整个块),但仍然存在错误。我无法弄清楚冲突的确切位置。

[更新] 令我永远感到羞耻的是,我相信我发现了问题所在。我只是从 ESLint 配置中删除了意图的配置。我删除了这个:

"indent": ["error", 4, { "SwitchCase": 1 }],
"react/jsx-indent": ["error", 4],
"react/jsx-indent-props": ["error", 4],

现在它似乎表现正常。我认为这是因为它在尝试处理缩进时搞砸了 Prettier。我只需要 Prettier 的配置。

课程:通过在发布前删除可能导致冲突的配置进行更多测试。

【问题讨论】:

    标签: eslint prettier eslint-config-airbnb


    【解决方案1】:

    为了确保这被标记为已解决:

    我只是从 ESLint 配置中删除了缩进配置。我删除了这个:

    "indent": ["error", 4, { "SwitchCase": 1 }],
    "react/jsx-indent": ["error", 4],
    "react/jsx-indent-props": ["error", 4],
    

    现在它似乎表现正常。我认为这是因为它在尝试处理缩进时搞砸了 Prettier。我只需要 Prettier 的配置。

    课程:通过在发布前删除可能导致冲突的配置进行更多测试。

    【讨论】:

      【解决方案2】:

      我遇到了与上面问题中提到的相同的问题,但是我想出了如何以一种方式解决它,不仅可以保留“缩进”设置,而且可以调整它,允许 tabWidth 是随意设置。

      首先我想指出,所以我们都在同一个页面上,我用于 linting/formatting 的设置到底是:

      1. 源代码编辑器:V.S.代码
      2. Linting 实用程序:ESLint
      3. 自以为是的格式化程序:更漂亮
      4. 风格指南:AirBnB

      此外,我还配备了以下内容,我使用 NPM 下载:

      1. eslint-plugin-prettier
      2. eslint-config-prettier
      3. eslint-config-airbnb

      对于那些在使用 V.S. 时熟悉 linting 的人。代码,你们知道我使用的实际上是短名单。可以获取各种其他配置、插件和扩展。这里要注意的重要一点是,我使用的是经过验证的真实设置,它允许 Prettier 和 ESLint 和谐地协同工作。

      话虽如此,即使有一个好的配置和所有正确的扩展,我仍然对上述规则有疑问,与发布问题的开发人员相同。我知道问题与 ESLint 的规则有关,以及它们是如何在我的 .eslintrc.json 文件中配置的。经过大量研究,几乎掌握了 ESLint,我发现我是正确的。但是,您需要正确配置一些 ESLint 规则(3 个 ESLint 规则和 1 个 Prettier Setting);同时您需要确保您的 .prettierrc 文件设置与您的 .eslintrc.json 文件规则同步。一旦你了解了这一切,它实际上并不像听起来那么复杂。




      步骤 #1 知道你想要什么 tabWidth 并在 .prettierrc 中设置它


      • 首先,您需要确定您想要的样式选项卡宽度。 (大多数样式指南将制表符宽度设置为 (2x Space-Width),但许多开发人员会将那里的设置更改为 (4x Space-Width)。除 2x 和 4x 之外的任何东西都被视为禁忌。)

      • 继续打开你的 .prettierrc 文件(或者你使用的更漂亮的配置文件的任何 mimetype),然后根据你的喜好设置“tabWidth”,只要确保你从现在开始坚持使用一致的 tabWidth,因为 ESLint需要与 prettier 同步。


      您的“.prettierrc”文件应如下所示:

      {
          "printWidth": 90,
          "tabWidth": 4,
          "useTabs": false,
          "trailingComma": "all",
          "singleQuote": true,
          "semi": true,
          "bracketSpacing": false,
      }
      
      



      第 2 步:在 .eslintrc.json 中设置“max-len”规则**


      • 打开您的 .eslintrc.json 文件(或您使用的任何版本的 ESLint 配置文件 mime-type),并在 eslintrc.json 的 rules 属性中设置“max-len”规则。默认情况下,该规则不在文件中,因此您必须将其写入。要了解如何操作,请查看我在下面创建的示例
      • 确保 ESLint 的“max-len”规则中的“tabWidth”属性与 .prettierrc 文件中的“tabWidth”设置保持完全相同的值。
      • 这里还有一些其他规则选项对于正确设置也很重要。第一个,'code',设置每行可以容纳的最大字符数,也就是(ma​​x-line-length)。当设置“code”时,ESlint 将不允许比“code”设置更多的字符。问题是您绝对必须确保 .prettierrc 文件中的“printWidth”设置(您可能必须写入)设置为与 .eslintrc.json max 中的“code”属性值相同的值-len 规则。
      • “ignoreUrls”可以任意设置,并通过保留“error”一词来确保规则确实引发错误。

      这是我在 ESLint 中的 max-len 规则示例

      "rules": {
          "max-len": [
              "error",
              {
                  "code": 90,
                  "tabWidth": 4,
                  "ignoreUrls": true
              }
          ],
      }
      

      参见上面的 .prettierrc 示例,了解如何设置“printWidth”

      第 3 步:ESLint 的“无标签”规则

      • “无选项卡”规则是“必须设置”,如果您的 linting 和格式设置没有它 > 可以不同步。
      • 您可以根据需要设置“allowIndentationTabs”,允许或禁止缩进选项卡不会有任何影响。

      无标签规则应该是什么样子:

      "rules": {
          "no-tabs": ["error", {"allowIndentationTabs": true}],
      
          "max-len": [
              "error",
              {
                  "code": 90,
                  "tabWidth": 4,
                  "ignoreUrls": true
              }
          ],
      }
      

      第 4 步:ESLint 的“缩进”规则,目前为止讨论中最重要的规则

      说真的,这一点很重要。它是为了解决开关缩进问题而被抛弃的,它不能让您控制其他设置,例如设置自己的制表符宽度。 “缩进”规则。

      • 首先通过将错误设置为您看到的错误来确保缩进处于活动状态,您也可以将其设置为警告,但最好将其设置为错误,以便更漂亮地知道立即修复它。下一个设置是缩进的宽度,它必须与 .prettierrc 文件中的 tabWidth 以及“max-len” ESLint 规则中的值完全相同。
      "indent": ["error", 4, {"SwitchCase": 1}],
      
      • 括号中的最后一个设置“SwitchCase”可能会造成混淆。起初没有人向我解释这些,所以我不得不自己弄清楚,这让我有点搞砸了。 “SwitchCase”设置为的数字与之前的 4 不同。前面的 4 是“缩进”规则的初始设置,可以像这样单独存在:
      "indent": 4; // throws error
      // or
      "indent": ["warn", 4] // Throws warning, which is somtimes less annoying than an error
      

      所以重要的是要注意,您在“缩进”规则中看到的值 4 是缩进的空格数。这让我相信“SwitchCase”后面的 1 表示 switch 关键字大小写将缩进多少个空格。

      示例:

      switch(x){
          case 1:
              break;
      }
      

      但这不是它的工作方式。规则“SwitchCase”设置为的数字告诉编辑器缩进关键字“case”的次数。因此,如果“缩进”规则设置为 4,而“SwitchCase”规则设置为 4,那么 ESLint 将期望缩进 4x4=16。在一天结束时,ESLint 实际上会期望超过 16 个,因为 ESLint 将承担来自 switch 语句所在的不同级别块的所有缩进,这最终导致 ESLint 期望 24-36 个缩进空间,太疯狂了。

      “SwitchCase”需要设置为 1。

      "rules": {
          "indent": ["error", 4, {"SwitchCase": 1}],
          
          "no-tabs": ["error", {"allowIndentationTabs": true}],
      
          "max-len": [
              "error",
              {
                  "code": 90,
                  "tabWidth": 4,
                  "ignoreUrls": true
              }
          ],
      }
      

      如果您设置了所有适合您的规则

      如果仍然无法正常工作,请尝试从头开始,删除您的 .eslintrc.json 文件,然后创建一个新的 eslintrc.json 文件,然后重新构建它。您不必从新的 .prettierrc 文件重新开始。

      总结

      Prettier 想要缩进所有不知情的东西。因此,如果 tabWidth 设置为 4,并且 tabWidth & indent 在 ESlint 中设置为 4,那么每个块都会缩进 4 个空格更漂亮,不多也不少。

      整个问题最初是,样式指南经常要求关键字大小写不缩进,所以当设置 ESLint 时,这就是你在初始化 ESLint 时安装的 NPM 配置所配置的。但是,这不适用于 prettier。

      这个答案比我想象的要长得多。让 Prettier、ESLint 和 VS Code 和谐地协同工作是一项非常复杂的任务,尤其是对于初学者而言。我在这个 AST 堆栈之上使用了 Babel(我把这个术语编了出来,哈哈,你还能叫它什么?)。如果您希望能够对包含 TC39 ECMAScript Stage-3 Proposals 的文档进行 lint,这包括私有成员、静态方法等功能,那么您将需要使用配置 ESLint 来使用 Babel 的解析器。

      【讨论】:

      • 非常感谢您的详尽回答。 (没有其他东西对我有用。)
      • @Ryan 太棒了,我也遇到了这个问题。这就是为什么我在这个答案上付出了这么多努力。 IMO 试图让 'dev dependencies' 彼此和谐地工作,但有时可能会很痛苦。我很欣赏你的评论。让我知道这个答案很有帮助是非常有益的。
      • 完全同意 :-) 最重要的是,我还必须这样做,因为我使用的是 TypeScript:stackoverflow.com/a/67526930/470749
      • @Ryan TS Env 需要花费一些精力和时间来设置,而且不仅仅是一次,而是每次创建新项目时。我将 ESLint 配置为使用 Babel 解析器(或“@babel/eslint-parser”),它为 ESLint 提供了 TC39 提案支持(因此我可以对静态类成员进行 lint,并创建私有成员)。问题是,为我开始的每个项目配置这样做很快就很烦人,所以现在我保留了一个私人 GitHub 存储库,它基本上只是一个项目模板。当我开始一个新项目时,我只是克隆存储库,然后复制、粘贴和提交新项目存储库中的文件。每次我这样做可以节省一个小时。
      • 是的,最近几个月我开始做同样的事情。我不想每次都重新学习复杂的配置。所以这是我使用的那个基础仓库的最新改进。谢谢。
      猜你喜欢
      • 2022-08-09
      • 2021-08-21
      • 2020-12-25
      • 2021-03-17
      • 2020-06-19
      • 2018-02-22
      • 2018-07-18
      • 2020-01-30
      • 2017-11-23
      相关资源
      最近更新 更多