计划于 2023 年 11 月 3 日星期五发布的 ESLint v8.53.0 将正式弃用我们的格式化规则。格式化规则是指那些仅强制执行代码约定(例如空格、分号、字符串格式等)的规则。出于各种原因(在本帖中讨论),这是 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 自愿将这些规则作为单独的包进行维护也为我们提供了帮助。我们希望本文中提到的可用选项之一能够确保人们能够继续以他们喜欢的方式格式化其源代码。