[譯]回顧ESLint的成功
- 原文地址:Reflections on ESLint`s success
- 原文作者:Nicholas C. Zakas
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:薛定諤的貓
- 校對者:H2O-2、warcryDoggie
回顧 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-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 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 的成功:
- parser 可配置 – 直接來自 Facebook的建議,他們希望將 Esprima fork 用於 ESLint。
- JSX 支援 – 起初我非常反對預設支援 JSX。但有持續不斷的建議,我最終同意了。如上文提到的,這一點也成為了 ESLint 成功的關鍵。
- 可分享配置 – 來自 Standard 和其它基於 ESLint 的封裝,它們的目標是使用特定的配置來執行 ESLint。看起來社群確實需要一種簡便的方式來分享配置,因此這個特性誕生了。
-
外掛 – 起初載入自定義規則的唯一方式是,從檔案系統使用命令列選項
--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
- ESLint (eslint.org)
- Introducing ESLint (nczonline.net)
- HTTP Archive Trends 2013-2016 (httparchive.org)
- babel-eslint (github.com)
- eslint-plugin-react (github.com)
- Lint like it`s 2015 (medium.com)
- ESLint: The Next Generation JavaScript Linter (smashingmagazine.com)
- Why I`m not using your open source project (nczonline.net)
免責宣告:文中任何觀點都屬於 Nicholas C. Zakas 本人所有,不代表僱主、同事,Wrox Publishing、O`Reilly Publishing或其他人。
相關文章
- [譯] 回顧 ESLint 的成功EsLint
- 【譯】回顧Swift 3, 展望Swift 4Swift
- [譯] 2018 前端全面回顧前端
- [譯] 關於使用 GRAPHQL 構建專案的回顧
- 【譯】2018 年前端開發回顧前端
- 兩年的工作回顧
- 一個老程式設計師的30年生涯回顧(譯文)程式設計師
- 基礎回顧
- Git指令回顧Git
- 自學javase的回顧(2/10)Java
- 串知識的重新回顧
- JSP_EL的回顧JS
- javascript中陣列的回顧JavaScript陣列
- 活動精彩回顧|GopherChina 2019乾貨回顧!Go
- 掘金翻譯計劃 2017 回顧 — 致謝譯者及近期規劃
- js回顧:原型鏈JS原型
- PHP 回顧之 cookiePHPCookie
- 回顧 crash log 分析
- javascript知識回顧JavaScript
- flex知識回顧Flex
- 5. SQL回顧SQL
- SpringMVC 回顧servletSpringMVCServlet
- GoogleDeveloperDay 回顧GoDeveloper
- 回顧工作5年
- PLSQL儲存回顧SQL
- mybatis---回顧jdbcMyBatisJDBC
- 【譯】Visual Studio 中的 GitHub Copilot:2023年回顧Github
- 前端工作兩年多的回顧前端
- 關於成都 Gopher Meetup 的回顧Go
- PHP執行流程回顧PHP
- 程式碼大全回顧篇...
- 回顧 Firefox 歷史Firefox
- PHP回顧之ComposerPHP
- openLayers 3知識回顧
- oracle打補丁回顧Oracle
- Docker 核心知識回顧Docker
- Java基本語法回顧Java
- 【指標】-簡單回顧指標