
在預計於 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 自願維護規則作為一個獨立套件,使得這個決定變得容易一些。我們希望本文中提到的可用選項之一將確保人們能夠繼續以他們喜歡的方式格式化他們的原始碼。