ESLint v8.53.0 计划于 2023 年 11 月 3 日星期五发布,届时我们将正式弃用我们的格式化规则。格式化规则是指仅强制执行代码约定(例如空格、分号、字符串格式等)的规则。出于各种原因,在本帖中进行了讨论,这是 ESLint 未来发展的正确决定。但是,要了解我们是如何走到这一步的,回顾一下过去很有帮助。
背景
ESLint 最初于 2013 年发布时,JavaScript 生态系统正围绕源代码格式化是否应成为代码检查工具的一部分展开一场辩论。 JSLint(最初的 JavaScript 代码检查工具)在其工具中大量编码了其作者的格式化偏好。这些偏好被继承到 JSLint 的后继者 JSHint 中,并略有放松,但到 2013 年,JSHint 宣布其 将弃用其格式化选项,并在下一个主要版本中将其移除。虽然这些选项从未被移除,但它们仍然 显示此警告
警告 此选项已弃用,将在 JSHint 的下一个主要版本中移除。
JSHint 将其范围限制在代码正确性问题上。如果您想强制执行与代码风格相关的规则,请查看 JSCS 项目。
JSCS 项目的诞生是为了满足 JavaScript 开发人员日益增长的以更具体的方式格式化代码的需求。与 ESLint 同年出现,当时有一段实验期,人们尝试使用 JSHint、JSCS 和 ESLint 的不同组合来满足其代码检查和格式化需求。
早期,我认为 ESLint 要合理地与 JSHint 竞争,唯一的方法是确保所有可用的 JSHint 规则都有 ESLint 等效项。虽然 ESLint 的优势在于(现在仍然在于)创建自定义规则,但我认为如果每个人都必须为自己重新创建 JSHint 规则,ESLint 不会获得太多采用。我最初的计划是创建几十条核心规则,然后将其余规则作为插件实现。
随着时间的推移,ESLint 收到了越来越多的请求,要求将格式化和风格规则添加到核心。许多请求提到他们不想在代码上使用两个工具(ESLint 和 JSCS),如果 ESLint 可以完成 JSCS 做的所有事情,他们就可以放弃 JSCS 并且只使用 ESLint。因此,现在 ESLint 有了一个团队,我们专注于获得功能奇偶校验以支持此用例。最终,我们做得非常好,以至于 JSCS 的使用量下降了,我们 将 JSCS 合并到 ESLint 中。
当时我们不知道的是,JSHint 的想法是正确的,尽管 ESLint 已成为 JavaScript 的主要代码检查工具(和源代码格式化工具),但我们也承担了大量工作。
JavaScript 的爆发和维护负担
在随后的几年中,尤其是在 ECMAScript 6 和 React 的增长推动下,人们编写 JavaScript 的方式发生了巨大变化。越来越流行的风格指南(如 Airbnb 和 Standard)鼓励 JavaScript 开发人员更加具体地说明其代码的编写方式。结果,ESLint 接到了大量关于格式化规则的异常和选项的请求。在过去的十年里,我们看到了各种奇特的风格,以及在 ESLint 核心规则中强制执行这些风格的请求。每次引入新的语法时,我们都会收到大量更新现有规则和实现新规则的请求。
当我们的核心规则接近 300 个时,我们尝试通过 冻结风格规则 来减少维护负担,这样我们就不再需要追逐各种极端情况来满足每个人的个人偏好。这在一定程度上有所帮助,但还不够。
- 规则冲突。人们期望核心规则能够很好地协同工作,这意味着任何两条规则都不应标记相同的问题,任何两条核心规则都不应给出相互冲突的建议。虽然在核心规则少于 30 个时这很容易做到,但在有 300 个规则的情况下,实现起来变得困难,甚至不可能。
- 不切实际的期望。拥有大量核心格式化规则后,用户期望仅使用核心规则即可实现所有可能的风格指南,而无需涉及插件。这给团队带来了更大的压力,要求他们继续添加选项,这也增加了核心的规模。
- 努力与价值错位。持续添加新选项和异常以支持每个人的风格指南的维护负担落在了 ESLint 团队身上,而价值则由少数用户提取。
- 机会成本。我们花在维护格式化规则上的时间越多,花在对大量用户有益的事情上的时间就越少。
- 缺乏兴趣。虽然 ESLint 受益于外部贡献,但这些贡献者只是对追逐空格的极端情况不感兴趣。ESLint 团队本身也优先考虑其他任何工作,而不是这些规则,这通常会导致问题长时间处于开放状态。
- 一致性问题。由于 ESLint 的规则旨在是原子的,并且无法访问其他规则,因此我们会遇到无法正确修复错误的问题,因为信息在另一个规则中。例如,如果自动修复需要添加新的一行代码,它需要知道文件的缩进方式才能应用正确的修复。但是,
indent
规则控制 ESLint 的缩进,这意味着其他规则需要在没有缩进的情况下应用修复,然后相信indent
规则将在后续传递中修复缩进。
所有这些问题随着 ESLint 的发展而不断增长,我们终于到了无法继续应对这些问题的地步。
已弃用的规则
以下列表包含将在 v8.53.0 中弃用的所有规则
array-bracket-newline
array-bracket-spacing
array-element-newline
arrow-parens
arrow-spacing
block-spacing
brace-style
comma-dangle
comma-spacing
comma-style
computed-property-spacing
dot-location
eol-last
func-call-spacing
function-call-argument-newline
function-paren-newline
generator-star-spacing
implicit-arrow-linebreak
indent
jsx-quotes
key-spacing
keyword-spacing
linebreak-style
lines-between-class-members
lines-around-comment
max-len
max-statements-per-line
multiline-ternary
new-parens
newline-per-chained-call
no-confusing-arrow
no-extra-parens
no-extra-semi
no-floating-decimal
no-mixed-operators
no-mixed-spaces-and-tabs
no-multi-spaces
no-multiple-empty-lines
no-tabs
no-trailing-spaces
no-whitespace-before-property
nonblock-statement-body-position
object-curly-newline
object-curly-spacing
object-property-newline
one-var-declaration-per-line
operator-linebreak
padded-blocks
padding-line-between-statements
quote-props
quotes
rest-spread-spacing
semi
semi-spacing
semi-style
space-before-blocks
space-before-function-paren
space-in-parens
space-infix-ops
space-unary-ops
spaced-comment
switch-colon-spacing
template-curly-spacing
template-tag-spacing
wrap-iife
wrap-regex
yield-star-spacing
所有这些规则从下一个版本开始将被弃用,但至少在 ESLint v10.0.0(如果不是更晚)之前不会被移除。您可以继续使用它们,尽管您可能会在 ESLint CLI 中看到弃用警告。
您应该怎么做
我们建议使用源代码格式化工具而不是 ESLint 来格式化您的代码。源代码格式化工具旨在理解整个文件并在整个文件中应用一致的格式。虽然您可能无法像使用 ESLint 那样对异常进行太多控制,但与使用数十个单独规则配置 ESLint 相比,您可以获得简单性和速度。我们推荐两个格式化工具
如果您不喜欢使用专用的源代码格式化工具,您也可以使用 @stylistic/eslint-plugin-js
用于 JavaScript 或 @stylistic/eslint-plugin-ts
用于 TypeScript。这些包分别包含来自 ESLint 核心和 typescript-eslint
的已弃用格式化规则。这些包由 Anthony Fu 维护,他决定继续维护这些规则。如果您想继续使用本文中提到的规则,那么我们建议您切换到这些包。
结论
我们知道很多人依赖 ESLint 来进行代码质量和格式化,因此我们不会轻易做出这样的重大决定。不幸的是,我们一直以来的做事方式无法再扩展太多,我们需要进行此更改。专用源代码格式化工具的普遍性和流行性使这个决定变得相对容易,而 Anthony Fu 自愿将这些规则作为单独的包进行维护也使这个决定变得更容易。我们希望本文中提到的可用选项之一将确保人们能够继续以其首选方式格式化其源代码。