
在預計於 2023 年 11 月 3 日星期五發布的 ESLint v8.53.0 中,我們將正式棄用我們的格式化規則。格式化規則是指那些僅僅強制執行關於空格、分號、字串格式等的程式碼慣例的規則。由於多種原因(將在本篇文章中討論),這是 ESLint 未來發展的正確決定。然而,為了理解我們是如何走到這一步的,回顧一下過去是有幫助的。
背景
當 ESLint 最初於 2013 年發布時,JavaScript 生態系統正陷入關於原始碼格式化是否應成為 linter 一部分的爭論。JSLint,最初的 JavaScript linter,在其工具中大量編碼了作者的格式化偏好。這些偏好被繼承並在 JSLint 的繼任者 JSHint 中有所放寬,但到了 2013 年,JSHint 宣布它將 棄用其格式化選項,並將在下一個主要版本中移除它們。雖然這些選項從未被移除,但它們仍然 顯示此警告
警告 此選項已被棄用,並將在 JSHint 的下一個主要版本中移除。
JSHint 將其範圍限制在程式碼正確性的問題上。如果您想強制執行與程式碼風格相關的規則,請查看 JSCS 專案。
JSCS 專案的誕生是為了滿足 JavaScript 開發人員對以更特定方式格式化其程式碼日益增長的渴望。與 ESLint 同年出現,在人們嘗試使用 JSHint、JSCS 和 ESLint 的不同組合來實現其 linting 和格式化需求時,經歷了一段實驗期。
早期,我認為 ESLint 要合理地與 JSHint 競爭的唯一方法是確保所有可用的 JSHint 規則都有 ESLint 對應項。雖然 ESLint 的優勢過去是(現在仍然是)在於創建自訂規則,但我認為如果每個人都必須為自己重新創建 JSHint 規則,ESLint 將不會獲得太多採用。我的最初計劃是製作幾十個核心規則,然後將其餘的留作外掛程式來實現。
隨著時間的推移,ESLint 收到了越來越多將格式化和風格規則添加到核心的請求。許多請求提到他們不想在他們的程式碼上使用兩個工具(ESLint 和 JSCS),如果 ESLint 可以做 JSCS 所做的一切,他們就可以放棄 JSCS 而只使用 ESLint。因此,既然 ESLint 已經有一個團隊,我們就專注於獲得功能對等性以支援此用例。最終,我們做得如此出色,以至於 JSCS 的使用率下降,並且我們 將 JSCS 合併到 ESLint 中。
我們當時不知道的是,JSHint 的想法是正確的,儘管 ESLint 已成為 JavaScript 的主要 linter(和原始碼格式化工具),但我們也承擔了大量的工作。
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。我們推薦兩種格式化工具
如果您不喜歡使用專用的原始碼格式化工具的想法,您也可以為 JavaScript 使用 @stylistic/eslint-plugin-js
,或為 TypeScript 使用 @stylistic/eslint-plugin-ts
。這些套件包含來自 ESLint 核心和 typescript-eslint
的已棄用格式化規則,分別由 Anthony Fu 維護,他已決定繼續維護這些規則。如果您想繼續使用本文中提到的規則,那麼我們建議切換到這些套件。
結論
我們知道很多人依賴 ESLint 來實現程式碼品質和格式化目的,因此,我們不會輕易做出像這樣重大的決定。不幸的是,我們一直以來做事的方式無法進一步擴展,我們需要做出這個改變。專用原始碼格式化工具的普及和流行使這個決定變得更容易一些,Anthony Fu 自願將這些規則作為一個單獨的套件維護也是如此。我們希望本文中提到的可用選項之一將確保人們可以繼續以他們喜歡的方式格式化他們的原始碼。