【導讀】:作者 Vincent Voyer 用親身經歷鼓勵大家從事開源活動:他在 Nodejs 原始碼裡改了兩個字元,解決了記憶體洩漏,信心大增;沒找到合適的圖片 lazy load 的庫,自己動手做,竟被印度電商巨頭的網站用上了,信心倍增。
今年我做了一次演講,內容是如何讓我們的開源專案獲得其他人的貢獻,比如提問、寫文件或者更新程式碼,從而打造一個成功的開源專案。在這次演講結束後,我得到了這樣的反饋:“你展示瞭如何開發一個成功的開源專案,但是我應該怎樣開始一個開源專案呢?”。本文便是來回答這個問題的。文章闡述瞭如何開始貢獻開原始碼以及如何建立自己的開源專案。
本文分享的知識是基於我們的工作經驗:在 Algolia 工作時,我們釋出和維護了許多成功的開源專案,它們都經過了長時間的檢驗。同時,我也花了很多時間來練習和建立自己的開源專案。
開始我們的開源專案之旅吧
我職業生涯的關鍵時刻是六年前我在 Fasterize(一家做網站應用加速的公司)工作的時候。在 Node.js 工作程式中,我們遇到了一個很嚴重的記憶體洩漏問題。除了 Node.js 原始碼庫,我們找遍了所有可能引發這個問題的地方,結果一無所獲。我們的臨時解決辦法是每天重啟這些工作程式(這會使記憶體使用量歸零),但是我們知道這不是一個優雅的解決辦法,所以我想從整體考慮問題。
當我的聯合創始人 Stéphane 建議我檢查一下 Node.js 的原始碼時,我幾乎笑了出來。我想:“如果有 bug,很可能來自我們自己的程式碼,而不是來自於創造革命性伺服器端框架的開發人員程式碼。但是,我還是會看一下的”。兩天之後,我提交的 2 個字元的改動被合併到了 Node.js 的原始碼中,修復了 http 層的 bug,解決了記憶體洩漏問題。
這次的舉動給予了我足夠大的信心。http.js 檔案的其他 30 個程式碼貢獻者都是我崇拜的人,比如 isaacs(npm 的創造者)—— 這使我明白了不管是誰寫的程式碼,都可能會有瑕疵。
在使用開源專案的時候,你是否遇到了 bug?嘗試查閱原始碼,不要停留在本地的程式碼上。你的答案會使其他人收益,引導著你去給更多的開源專案做貢獻。閱讀其他人的程式碼,也許不能馬上解決你的問題,而且需要花費很長時間才能理解原始碼,但是你會學到新的模組,新的語法以及編碼的不同技巧,這些都會促使你成為一名出色的開發者。
抓住貢獻開源專案的機會
Node.js 原始碼倉庫的第一個貢獻標籤
“我沒有好想法”,這是那些想為開源做貢獻,但又自認為沒有好的點子或專案來分享的開發者通常會抱怨的一點。那麼,我會說:沒關係。為開源做貢獻的機會有很多。許多專案已經開始通過分類或標籤列出那些優秀的首次貢獻者。
你可以通過瀏覽這些網站獲得一些開源靈感:Open Source Friday,First Timers Only,Your First PR, CodeTriage,24 Pull Requests,Up For Grabs, Contributor-ninja 和 First Contributions。
建立一些工具
建立工具是幫助他人的一種很好的方式,而且不用考慮太多複雜的問題或 API 設計。你可以開發一個你最喜歡的框架或平臺的模板。你可以將從許多部落格上學到的知識和工具集中到一個專案中進行很好的詮釋,並做好隨時更新和釋出新特性的準備。create-react-app 是這種開源工具的一個優秀案例.
在 GitHub 上有 5 萬 8 千多個開源模板倉庫,開發一個這樣的專案比較容易而且受歡迎。
今天,你也可以開發 Atom 和 Visual Studio Code 的純 JavaScript 外掛,比如我們開發了 Atom 自動補全模組匯入的外掛。那些 Atom 或 Sublime Text 中的優秀外掛是不是還沒有出現在你喜歡的編輯器中?趕快去開發一個吧。
最後,你也可以為 webpack 或 babel 開發外掛,用於解決 JavaScript 技術棧的特殊用例。
好訊息是,很多平臺都會告訴你如何去建立和釋出外掛,所以你不用花費太多的時間去思考怎麼下手。
成為新的維護者
當你在 GitHub 上瀏覽專案時,你也許會發現和使用那些建立者不再維護的專案。雖然它們有價值,但還有很多建立者沒有回答的 issues 和 pull requests 。這時你會怎麼做?
- fork 一份並用一個新名字釋出
- 成為新的維護者
我建議你兩者都做。前者有助於推進你自己的專案,而後者對你自己和社群都有好處。
你會問,那麼如何成為一個新的維護者呢?向建立者發一封郵件或推特,說:“你好,我想繼續維護這個專案,你覺得可以嗎?”這種方式通常效果不錯。這是開始你自己的開源專案的好辦法,因為這個專案已有很多人知曉和受益。
成為新維護者的推特訊息示例
建立你自己的開源專案
建立自己的開源專案最好的方式是尋找那些至今還沒有很好的解決方案的問題。如果你發現你在網上沒有找到能解決你問題的特定的庫,那麼這正是去開發一個開源庫的好時機。
下面是我職業生涯中另一個關鍵點。在 Fasterize 工作時,我們的網站效能加速器需要一個快速、輕量級的圖片延遲載入庫 —— 不是一個 jQuery 外掛,而是一個單獨的專案,它必須能嵌入所有瀏覽器的所有網站並正常工作。我花了數個小時在網上搜尋已經存在的優秀的開源庫,可是最終沒有找到合適的。所以我說道:“完蛋了。我不能找到一個完美的開源庫,我們的工作沒法開展了。”
對於這種情況,Stéphane 回覆說:“那麼,我們自己來創造一個吧”。嗯..好吧!我將 StackOverflow 上的一段答案複製貼上到了我的 JS 檔案中,就這樣開始了我自己的開源專案之旅。最終,我建立了一個圖片延遲載入的庫,它被像 Flipkart.com(每月大約 2 億的訪問量,在印度排名第 9)這樣的網站使用著。有了這次成功經歷之後,我便無時不刻關注著開源專案。我突然意識到,開源專案可以成為我程式設計師職業生涯的另一部分,而不是僅有傳奇人物和能力超群的程式設計師才能做開源專案。
一個沒有好的解決方案的問題:可以嘗試以重用的方式解決它!
時間點很重要。如果你不打算創造一個可重用的庫,而是在自己的專案中寫一些只適用於你係統的程式碼,那麼你便錯失了一次機會。在某個時刻,其他人會開發出你之前可能有機會做出的專案。所以與其被他人搶先一步,你應該儘快從你的專案中抽離和釋出可重用的模組。
釋出,宣傳和分享
為了確保任何想使用你的模組的開發者能確切地找到你的開源專案,你需要做到以下幾點:
- 你的 README 文件上需要有徽章和虛榮指標
- 開發一個有著漂亮的設計和線上演示的網站來專門介紹說明你的專案。需要一些靈感麼?看一下 Prettier 吧。
- 在 StackOverflow 和 GitHub 上回答一些相關的問題,並在答案中寫上你的開源專案
- 將你的專案釋出到 HackerNews、reddit、ProductHunt、Hashnode 和任何其他技術社群網站
- 將你的新專案推薦到相關技術平臺的新聞媒體
- 和別人交流你的專案,或做一次演講
向大家展示你的新專案
不要害怕向網站投稿;只要你真的相信自己的專案是有價值的,那些網站從來不嫌文章太多。通常,技術社群都是十分歡迎大家投稿分享的!
要有耐心,不要怕迭代
在“虛榮指標”(stars 數和下載數量)方面,有些專案在第一天會迅速飆升,但是很快會停止增長。而其他人,在他們準備好登上 Hacker News 首頁之前,也許需要等上一年。你要相信,你的專案在某一時刻會被他人所注意到,如果沒有,那麼你也學到了一件事情:這個專案可能只對你有價值 —— 這為你下一個專案的成功做了鋪墊。
我有許多 0 個 stars 的專案(比如 mocha-browse),但是我從來不沮喪,因為我沒有很高的期待。在開始做一個專案時,我總是這麼想:我發現了一個問題,我用我自認為最好的方式解決了它,也許有的人會使用我的方法,也許沒有。這不是什麼大不了的事情。
一個解決方案,兩個專案
這是我做開源專案最喜歡的部分之一。2015 年,在 Algolia 工作時,我們嘗試尋找單元測試的解決方案,暫停了為 React UI 庫 InstantSearch.js 編寫 React 元件時用 JSX 輸出 html 。
由於 JSX 會被轉換成函式呼叫,當時我們的解決方案是寫成這樣expect(<Component />).toDeepEqual(<div><span/></div)
。這只是比較兩個函式呼叫的輸出結果。但是這兩個方法輸出的是複雜的物件:當執行這段程式碼時,會出現“Expected {-type: ‘span’, …}”這樣的錯誤。輸入和輸出結果無法進行對比,所以當開發者們寫單元測試時,他們會瘋掉的。
為了解決這個問題,我們創造了 algolia/expect-jsx,它可以在單元測試中輸出對比 JSX 字串,而不是輸出無法閱讀的物件。輸入輸出的測試會使用相同的語義。我們並沒有就此停止。我們從程式碼中又提煉開發出了另一個庫,並最終釋出了兩個開源庫,而不是一個:
- algolia/react-element-to-jsx-string 將 JSX 的函式呼叫轉換成 JSX 字串的庫
- algolia/expect-jsx 將斷言庫 mjackson/expect 和上方的 react-element-to-jsx-string 庫結合了起來
- 通過釋出兩個模組來共同解決一個問題,社群的開發者可以將你的低階方案在不同的專案中重用。甚至,他們會以一種你從未想到過的方式來使用你的模組庫。
比如,react-element-to-jsx-string 已經被使用到了許多其他的測試斷言框架中,同時也被用到了像 storybooks/addon-jsx 這樣的文件外掛中。現在,一般都使用 Jest and snapshots testing 來測試你的 React 元件的輸出,在這些場景下已經用不上 expect-jsx 了。
反饋和貢獻
圖中有許多 issues。其實這只是為了好看而使用的假數字?
一旦你開始收到反饋和貢獻程式碼,你要以一種開放和樂觀的心態去面對它們。你會得到熱情的反饋,但也會有負面的評論。記住,與使用者的任何互動都是可以看作一種對於專案的貢獻,即使有些看起來像是在抱怨。
首先,用文字來表達意圖和語氣不是那麼的容易。“這很奇怪…”也許會被你解讀成:這很棒/這實在是很糟糕/我不理解/我很開心/我很沮喪。詢問更多的細節,嘗試重新解讀這個問題,來更好地理解問題的根源。
避免抱怨的一些建議:
- 為了更好地引導使用者提出反饋,可以提供一個問題反饋模板,讓他們在提問時可以參考。
- 儘量對新貢獻者的嚴苛程度降到最低。請記住,他們可能還沒有測試,並很樂意向你學習。不要由於少個分號而對於新的貢獻者的 Pull Requests 置之不理。讓他們感受到溫暖。你可以禮貌地要求他們把分號加上。如果,這樣不行,你也可以就這樣將 Pull Request 合併,然後自己完成測試和文件工作。
- 提供一個良好的開發環境,包括自動化測試、錯誤檢查和程式碼格式化或自動重新整理示例。
總結
感謝閱讀,我希望你們能夠喜歡這篇文章,並幫助你們建立開源專案。貢獻開原始碼是擴充技能的好辦法,並不是每個開發者都需要有這種經歷,但是這是一個讓你快速進步的好機會。
我很期待你的第一個或下一個開源專案。記得在推特上 @vvoyer,我會很樂意給你的專案提出建議。
如果你喜歡開源專案,同時想在工作中去貢獻開原始碼而不是在你的空閒時間,Algolia 有相應的 JavaScript 開源專案研發的職位。
你可能會喜歡的其他資源:
- opensource.guide,學習如何建立和提升你的專案。
- Octobox,將 GitHub 的通知以郵件的形式傳送給你。一個很棒的方式讓你避免由於 issues 太多,而忽視了其中重要的問題。
- Probot,一個GitHub 的 App,幫助提升你的工作流程,使其更自動化,比如關閉時間久遠的 issues。
- Refined GitHub 為 GitHub 介面在許多層面提供了更好的體驗和特性。
- OctoLinker 給你更好的體驗來檢視他人的 GitHub 程式碼。
感謝 Ivana,Tiphaine,Adrien,Josh,Peter 和 Raymond 對於這篇文章的幫助、建議和貢獻。