[譯]回顧ESLint的成功

玄學醬發表於2017-10-16
本文講的是[譯] 回顧 ESLint 的成功,

回顧 ESLint 的成功

難以置信,我在 2013 年 6 月構思開發了 ESLint,7 月第一次對外發布。熟悉的讀者可能還記得,ESLint 最初主要設計目標是執行時載入的檢查工具(linter)。在工作中我看到我們的 JavaScript 程式碼中的一些問題,希望能有一些自動化的手段避免這些問題再次出現。

在 ESLint 釋出後的 2 年半里,它的受歡迎程度大大增加。上個月的 30 天在 npm 上就有超過 1 500 000 次下載,這是當初平均月下載量只有 600 時我不曾想象的。

所有這一切發生了,然而過去 2 年我患上了很嚴重的萊姆病,幾乎無法離開我的房子。這意味著我不能夠外出參加會議和聚會來宣傳 ESLint(前 2 年我可是會議常客)。但不知為何,ESLint 獲得了廣泛關注,並且繼續收到歡迎。我覺得是時候回顧其中緣由了。

JavaScript 使用量增加

過去三年,我們看到瀏覽器上 JavaScript 的使用量持續增加。根據 HTTP Archive[3],現在網頁的 JavaScript 比 2013 年增加了 100 KB。

Chart - Increasing JavaScript Usage in Browsers 2013-2016Chart – Increasing JavaScript Usage in Browsers 2013-2016

另一個因素是 Node.js 的爆炸性流行。以前 JavaScript 僅限於客戶端使用,而 Node.js 使另外一些開發者也能夠使用 JavaScript。隨著執行環境擴充到了瀏覽器和伺服器端,JavaScript 工具需求自然增加了。由於 ESLint 可以用於瀏覽器和 Node.js 上的 JavaScript,迎合了這一需求。

檢查工具更加流行

由於 JavaScript 工具的需求增加,對 JavaScript 程式碼檢查的需求也隨之增加。這很容易理解 — 你編寫的 JavaScript 程式碼越多,就越需要更多保障,避免一些常見錯誤。自 2013 年中以來 npm 上 JSHint、JSCS、ESLint 的下載量顯示了這一趨勢。

Chart - Increasing downloads for all JavaScript lintersChart – Increasing downloads for all JavaScript linters

JSCS 和 ESLint 幾乎是同時建立的,將它們各自的增加軌跡與更早一些的 JSHint 進行對比可以看到一些很有趣的地方。到 2016 年初,JSHint 在 JavaScript 程式碼檢查領域有著優勢地位,JSCS 和 ESLint 也在增長。最有趣的是這三個工具的下載量都在增長,說明每月下載檢查工具的人多於更換的人數。

所以 ESLint 確實迎合了開發者對 JavaScript 程式碼檢查需求增加的大趨勢。

ES6/Babel

在過去的四年裡,ECMAScript 6 的人氣一直在穩定增長,這也使 Babel 獲得了極大成功。開發者不用等瀏覽器和 Node.js 的正式支援就可以使用 ECMAScript 6 語法,這也需要 JavaScript 工具的新特性支援。在這一點上,JSHint 對 ECMAScript 6 特性支援不足,顯得有些落後了。

另一方面,ESLint 有一個巨大的優勢:你可以用其它的 parser 來代替預設的 parser — 只要它的輸出與 Esprima(或 Espree)相容。這意味著你可以直接使用 Facebook 的 Esprima 支援 ES6 的 fork (現在已不再維護)來檢查你的 ES6 程式碼。Espree 現在也已經支援 ES6 了(主要來自 Facebook 的 fork)。這使得開發者可以很方便的使用 ES6。

當然,Babel 並沒有止步於支援 ES6 — 它同樣也支援實驗特性。這就需要不但支援 ES 標準特性,還有其它開發中的特性(stage0 ~ stage4)。因此 ESLint 的 parser 可配置性就很重要了,因為 Babel 成員建立的 babel-eslint[4] 在其基礎上進行封裝,以便 ESLint 能夠使用。

不久以後,ESLint 就成為了使用 ES6 或者 Babel 的人推薦的檢查工具,這得益於允許相容 parser 替換預設 parser 的設計決策。

現在,ESLint 安裝時大約有 41% 使用了 babel-eslint(基於 npm 下載量統計)。

React

討論 ESLint 的流行離不開 React。React 的一個核心特性就是支援在 JavaScript 中嵌入 JSX,而其它檢查工具起初都不支援這一特性。ESLint 不但在其預設 parser 支援 JSX,使用者也可以通過配置使用 babel-eslint 或者 Facebook 的 Esprima fork 來支援 JSX。React 使用者也因此開始使用 ESLint。

我們收到很多在 ESLint 本身加入一些 React 特有規則的請求,但是原則上我不希望有庫專有的規則 — 因為這會帶來巨大的維護成本。2014 年 12 月,eslint-plugin-react[5] 引入了許多 React 專有規則,很快得到了 Recat 開發者的歡迎。

後來在 2015 年 2 月,Dan Abramov 寫了一篇文章《Lint like it`s 2015》[6]。這這篇文章中,他介紹了 ESLint 在 React 中的應用,並給出了高度評價:

如果你從未聽說過 ESLint — 它就是我一直想要 JSHint 成為的那樣。

Dan 也介紹瞭如何配置使用 babel-eslint,提供了極有價值的文件。明顯可以看到這是 ESLint 的一個大的轉折點:月下載量從 2015 年 2 月的 89,000 到 2015 年 3 月的 161,000 — 增長了近一倍。從這之後到現在,ESLint 經歷了一個快速增長的階段。

現在,eslint-plugin-react 在 ESLint 安裝中使用率有 45%+(基於 npm 下載量統計)。

可擴充套件性是關鍵

從一開始,我的想法就是 ESLint 本身是小核心工具,作為大生態的中心。我的目標是通過允許足夠的擴充套件使 ESLint 永不過時:即便無法提供的新特性,ESLint 仍然可以通過擴充套件獲得新功能。雖然現在 ESLint 還沒有完全滿足我的設想,但已經非常靈活:

  • 你可以在執行時增加新規則,這使得任何人都可以編寫自己的規則。為了避免每天花費大量時間處理使用者想要各種預料外的規則,我將其視為關鍵所在。現在,沒有什麼阻止使用者編寫自己的規則。
  • parser 的可配置性使 ESLint 可以處理任何和 Espree 相容的格式。正如上文所述,這也是 ESLint 流行的一個重大原因。
  • 配置可分享,所有人都可以釋出和分享配置,非常便於不同的專案共用相同配置(ESLint 安裝中 eslint-config-airbnb 的使用率有 15%)。
  • 外掛系統 人們可以很方便的通過 package 分享規則,文字處理器,環境和配置。
  • 良好的 Node.js API 可以很方便的用於構建工具外掛(Grunt,Gulp等),也可用於建立零配置的檢查工具(Standard,XO等)。

我希望 ESLint 未來可以提供更多的可擴充套件性。

聽取社群反饋

我非常努力做到的事情之一就是:聽取 ESLint 社群的反饋。雖然開始有些固執於對於 ESLint 最初的設想,後來我意識到了眾人的智慧。聽到同樣的建議次數越多,就越有可能是需要考慮的痛點。在這一點上我現在好多了,社群的很多好的想法也促成了 ESLint 的成功:

  1. parser 可配置 – 直接來自 Facebook的建議,他們希望將 Esprima fork 用於 ESLint。
  2. JSX 支援 – 起初我非常反對預設支援 JSX。但有持續不斷的建議,我最終同意了。如上文提到的,這一點也成為了 ESLint 成功的關鍵。
  3. 可分享配置 – 來自 Standard 和其它基於 ESLint 的封裝,它們的目標是使用特定的配置來執行 ESLint。看起來社群確實需要一種簡便的方式來分享配置,因此這個特性誕生了。
  4. 外掛 – 起初載入自定義規則的唯一方式是,從檔案系統使用命令列選項 --rulesdir 載入。很快人們開始在 npm 釋出自己的規則。這樣使用起來很痛苦,並且很難同時使用多個 package,因此我們增加了外掛以便能夠方便的分享。

很明顯,ESLint 社群關於這個專案的成長有許多極好的想法。毫無疑問,ESLint 的成功直接受益於它們。

群眾基礎

ESLint 釋出以來,我寫了兩篇相關文章。第一篇發表在我的個人部落格,第二篇在去年 9 月發表於 Smashing 雜誌。除此之外,對 ESLint 的推廣僅限於 Twitter 和 管理 ESLint Twitter 賬戶。如果我願意花心思去做些演講的話,我肯定會在推廣 ESLint 上做的更好。但是因為我沒有,我決定放棄嘗試去推廣它了。

然而我很欣喜的發現人們開始討論 ESLint,寫關於它的文章。起初是一些我不認識也沒聽說過的人。不斷有人寫文章(比如說 Dan),人們也在各種會議和聚會上討論 ESlint。網上的內容越來越多,ESLint 很自然的也更加流行了。

一個有趣的對比是 JSCS 的成長。最開始 JSCS 得到了 JSHint 的宣傳 — JSHint 決定去除所有程式碼風格相關的規則,而 JSCS 則作為這些規則的替代品。因此當 JSCS 遇到問題時,會提到 JSHint 團隊成員。有了這個領域的巨頭支援,早期一段時間內,JSCS 的使用遠超於 ESLint。第一年的一段時間內,我曾一度以為 JSCS 會碾壓 ESLint,讓我許多夜晚和週末的工作失去意義,然而這一切並沒有發生。

強大的群眾基礎支援著 ESLint,最終幫助它得到了巨大成長。使用者帶來了更多使用者,ESLint 也由此獲得了成功。

關注實用性而非競爭

這是 ESLint 一路走來我最驕傲的事情之一。我從來沒有說過 ESLint 優於其它工具,從來沒有要求人們從 JSHint 或 JSCS 轉向 ESLint。我主要說明了 ESLint 能更好的支援你編寫自定義規則。到今天為止,ESLint README 裡面這樣寫(在 FAQ):

我不是說服你 ESLint 比 JSHint 更好。我只知道 ESLint 在我的工作中比 JSHint 更好。極小可能性你在做類似的工作,它可能更適合你。否則,繼續使用 JSHint,我當然不會勸說你放棄使用它。

這一直是我的立場,現在也是 ESLint 團隊的立場。一直以來,我始終認為 JSHint 是很好的工具,它有著很多優勢 — JSCS 也一樣。很多人非常滿意於使用 JSHint 和 JSCS 這一對組合,對他們來說,我鼓勵他們繼續使用。

ESLint 關注於盡可能有用,讓開發者來決定是否適合他們。所有決策都基於有用性,而非與其它工具競爭。這個世界可以有很多檢查工具的空間,不必只有一個。

耐心

我以前說過[8],現在開源專案間似乎有一種不理性競爭:對人氣的關注高於一切。ESLint 是一個專案從誕生到成功的很好的例子。在專案誕生初的近 2 年裡,ESLint 的下載量遠低於 JSHint 和 JSCS。ESLint 和 社群的成熟都花費了時間。ESLint 的“一夜成名”並不是發生在一夜,它經歷了持續不斷的基於有用性和社群反饋的改進。

優秀的團隊

我很幸運有很優秀的團隊為 ESLint 做貢獻。由於我沒有太多精力和時間在 ESLint 上,他們做了很多工作。一直令我吃驚的是我從來沒有當面見過他們,也沒有聽過他們的聲音,但我很期待能夠每天和他們對話。由於我需要恢復健康,他們永恆的激情和創造力使得 ESLint 能夠繼續成長。雖然我一個人開始了 ESLint 這個專案,但他們無疑是它能夠發展達到目前的人氣的原因。

非常感謝 Ilya Volodin, Brandon Mills, Gyandeep Singh, Mathias Schreck, Jamund Ferguson, Ian VanSchooten, Toru Nagashima, Burak Yiğit Kaya, 和 Alberto Rodríguez,謝謝你們的大量工作。

結論

有許多因素導致了 ESLint 的成功,我希望通過分享它們,能給其他人建立成功的開源專案提供一個指引。最值得做的事情,一點幸運,其他人的幫助和對要實現的東西的一個清晰的願景,這就是所有關鍵。我堅信如果你關注於創造一些有用的東西,願意付出辛苦的工作,最終將得到應得的回報。

ESLint 也在繼續成長和改變,團隊和社群也是。期待 ESLint 的未來。

References

  1. ESLint (eslint.org)
  2. Introducing ESLint (nczonline.net)
  3. HTTP Archive Trends 2013-2016 (httparchive.org)
  4. babel-eslint (github.com)
  5. eslint-plugin-react (github.com)
  6. Lint like it`s 2015 (medium.com)
  7. ESLint: The Next Generation JavaScript Linter (smashingmagazine.com)
  8. Why I`m not using your open source project (nczonline.net)

免責宣告:文中任何觀點都屬於 Nicholas C. Zakas 本人所有,不代表僱主、同事,Wrox PublishingO`Reilly Publishing或其他人。





原文釋出時間為:2017年7月26日

本文來自雲棲社群合作伙伴掘金,瞭解相關資訊可以關注掘金網站。


相關文章