Airbnb、ESLint、Prettier 在 Switch 和 Case 缩进上的冲突

Posted

技术标签:

【中文标题】Airbnb、ESLint、Prettier 在 Switch 和 Case 缩进上的冲突【英文标题】:Airbnb, ESLint, Prettier conflict over Switch and Case indentation 【发布时间】: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 的配置。

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

【讨论】:

【参考方案2】:

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

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

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

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

    eslint-plugin-prettier eslint-config-prettier 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:***.com/a/67526930/470749 @Ryan TS Env 需要花费一些精力和时间来设置,而且不仅仅是一次,而是每次创建新项目时。我将 ESLint 配置为使用 Babel 解析器(或“@babel/eslint-parser”),它为 ESLint 提供了 TC39 提案支持(因此我可以对静态类成员进行 lint,并创建私有成员)。问题是,为我开始的每个项目配置这样做很快就很烦人,所以现在我保留了一个私人 GitHub 存储库,它基本上只是一个项目模板。当我开始一个新项目时,我只是克隆存储库,然后复制、粘贴和提交新项目存储库中的文件。每次我这样做可以节省一个小时。 是的,最近几个月我开始做同样的事情。我不想每次都重新学习复杂的配置。所以这是我使用的那个基础仓库的最新改进。谢谢。

以上是关于Airbnb、ESLint、Prettier 在 Switch 和 Case 缩进上的冲突的主要内容,如果未能解决你的问题,请参考以下文章

Atom 与 prettier、eslint 和 airbnb 风格的 React 开发指南

eslint-config-airbnb vs prettier vs standard

如何使用 ESLint + Prettier + Airbnb 规则 + TypeScript + Vetur 配置 Vue CLI 4?

使用 airbnb 和 prettier 扩展的 ESLint 配置,用于使用 typescript、jest 和 react-hooks 的 react 项目

如何配置VSCode中的Prettier和ESLint标准

更漂亮 + eslint 换行符