零起點的開源社群貢獻指南

doodlewind發表於2017-11-01

【開源社群貢獻者】聽起來是個專屬於頂級開發者的頭銜,但它真的有這麼遙不可及嗎?下面的分享旨在揭開它的神祕面紗,幫助感興趣的同學更輕鬆地參與到社群專案中來。

首先需要澄清的是,本文作者自己並不是社群高大上專案的原創作者,只是在一個 5k+ Star,100+ 貢獻者的專案中貢獻排名前十而已(作為參考,Vue 的貢獻者不到 150 人),和《維護一個大型開源專案是怎樣的體驗》這個問題裡閃耀的群星相比,只不過是個小透明的存在。不過因為自己也只有一年有餘的經驗,在很多方面上和剛剛入門的新人同學們都很相似,因此相信個人經驗能有一定的參考價值,才在此做了些總結。文中如有不妥之處,請 dalao 們斧正。

下文內容主要分為這兩部分:

  • 起步與進階,介紹在對程式設計一無所知的時候,能夠通過什麼方式參與到社群中來。以及在有了貢獻的條件後,如何通過 Issue 和 PR 在開源專案中協作。
  • 技巧與總結,介紹一些技術性的細節,以及如何在 Github 上商業互吹的溝通技巧。

起步

參與開源專案的主要方式,由易到難不外乎這三種:

  • 翻譯文件
  • 報告 bug
  • 提交程式碼

在起步階段,翻譯文件的難度無疑是最低的。因為這甚至不需要你編寫或執行任何程式碼,只要在編輯頁面裡翻譯就足夠了。

以 Mozilla 維護的 MDN 文件為例,也許有不少同學不知道,MDN 文件和維基百科一樣,是允許所有使用者編輯的。比如,一篇介紹 CSS 定位方式的 MDN 文件,頁面頂部大概長這樣:

mdn-large
mdn-large

注意到 LanguagesEdit 了嗎?你可以在 Languages 裡選擇你需要的語言,或者新增新語言的翻譯。如果已有翻譯,可以直接點選 Edit 編輯!

在翻譯時,Mozilla 的富文字編輯器會分為左右兩個部分,可以直接對照:

mdn-editor
mdn-editor

現在只要點選儲存,你就會出現在這個頁面的貢獻者裡了!你的更改也會在文件歷史中儲存,所以在提交前不妨檢查下內容吧。另外,並不是一次儲存就必須搞定一整篇文件,寫到一半準備儲存的話,可以點選頁面最下方的 本地化進行中 選項,這樣就能夠在瀏覽頁面中新增一個【翻譯正在進行中】的標識啦。

這個過程裡我們似乎一行程式碼都沒有寫,那麼這有什麼用嗎?個人的觀點是,翻譯文件是一個很好的開始,因為它可以:

  • 幫助你更好地理解英文技術文件的行文結構,為後面和其他開發者的交流打好基礎。後面我們也會提及,很多時候需要為一兩行程式碼編寫的文件遠遠不止一兩行。
  • 很大地鍛鍊你的行文水平。在初期你可能會寫出比較翻譯腔、不通順的技術文件,熟悉以後會有很大的進步。
  • 讓你的貢獻迅速地得到反饋。MDN 的權重在 Google 並不低,通過 Google 在第一頁查到你翻譯的內容,還是挺有成就感的。
  • 提高你自己對文件內容的瞭解。以作者本人為例,在瞭解富文字編輯領域時首先就是從搬運 Mozilla 中的富文字編輯器文件作為開始,完成翻譯後就這個領域內的基礎概念瞭然於心了。

除了 MDN 文件外,中文技術社群也有不少優秀的相關專案可以參與。這方面個人的參與不多,就不班門弄斧了。

進階

只是翻譯文件的話,你可能很快就會達到【寫膩了】的階段,這時候就不妨來看看更大的世界吧。找一個 Github 上的活躍專案作為開始吧!對於在 Github 上維護的開源專案,主要的參與方式包括 Issue 和 PR 兩種:

Issue

對一箇中大規模的開源專案,Issue 主要用來:

  • 報告 Bug 與提問
  • 提出並討論新特性
  • 設定 Todo 目標

需要注意的是,許多專案是有自己的 Discuz 論壇或 Slack 群的,有一些類似【為什麼安裝失敗了】的新手向問題可以先在已有 Issue 中搜尋,然後再在論壇和 IM 中提出。如果隨意地提出 Issue,很可能會得到 Duplicate of #xxx 的回覆然後被關掉。對於新同學,一個非常好的參考是《提問的藝術:如何快速獲得答案》

只要給專案提出過 Issue,你當天的 Github 貢獻圖就會刷綠,並且也能夠把這個專案固定在個人主頁裡了!看起來同樣不需要寫程式碼,並不難呀。不過,單純地提 Issue 並不會讓你出現在專案的貢獻者列表裡,如果想真正地【貢獻】程式碼的話,PR 是必須的。

PR

Pull Request 顧名思義,就是請求別人拉取你的程式碼的意思。這是十分符合開源工作流的:開發者們 fork 出自己的倉庫,在自己的 分支裡 commit 程式碼,然後請求維護者將自己的更改合併進來。一般而言一個 PR 只要做好一件事情就足夠了,其作用不外乎以下之一:

  • 修復 bug
  • 實現新特性
  • 優化效能
  • 例行更新(如文件、依賴版本等)

新同學如果想要貢獻 PR,不妨先從自己擅長或關注的方面去著手,比如一些簡單的文件拼寫錯誤,或者標記為 help please 一類的 Issue。

只要提出 PR,不論合併與否當天的 Github 貢獻圖都會刷綠,而 PR 合併入主幹時,當天的貢獻圖也會刷綠。假設你發現了一個小 bug,只要一行就能夠修復,那麼整個流程走下來大概是這樣:

  1. 提出 Issue,貢獻 +1
  2. 提出 PR,貢獻 +1
  3. 回覆維護者的 Review 評審,貢獻 +1
  4. PR 通過,貢獻 +1

所以,哪怕僅僅提交一行程式碼,最多也足夠點綠四天的貢獻圖了。並且,維護者們在 Review 或併入你的 PR 時,他們的貢獻也會相應增加。這樣想來,大型專案貢獻者們一年動輒幾千的貢獻數量也不是隻能讓人仰望的了吧。

技巧

上面僅僅介紹了開源工作流中的幾個基礎概念。在真正參與時,還有一些可以稍加註意的技巧。下面介紹的就是一些與此相關的小細節。

問題導向的原始碼閱讀

在需要提出 bugfix、新 feature 或效能優化類 PR 的時候,閱讀框架原始碼基本是繞不開的。當然,我們經常能夠在技術社群看到很多【原始碼解析】類的文章(在近期以 Redux / Vue / Koa 為甚)。作者寫這些文章的出發點肯定是好的,不過令人有些遺憾的是,許多這類文章的閱讀量相對並不高,並且多數這類文章的作者並不是這些框架的貢獻者

是我們太浮躁了嗎?我們不妨從動機上考慮一下,我們為什麼需要閱讀原始碼呢?是為了解決實際遇到的問題,還是僅僅為了寫一篇部落格來展示自己的技術水平呢?如果只是貼上一個個看起來高大上的程式碼截圖,然後把註釋翻譯成中文,這樣的文章對讀者、對社群又有什麼幫助呢?【我讀過這個框架的原始碼】和【我修過這個框架的 bug】相比起來,哪個的貢獻更大呢?

個人的觀點是,帶著問題去除錯原始碼,收穫會比簡單的閱讀理解大很多。在你真正需要解決一個 bug 的時候,你才會真正去思考呼叫的順序、執行的流程、變數的意義,然後在一個個斷點、日誌和錯誤堆疊的幫助下,真正知道一些看起來漫不經心的判斷是多麼不可或缺,看似簡單的地方又隱藏著怎樣的預設條件。

從這個角度而言,以修復 bug 的動機驅動去維護開源專案,對技術水平的鍛鍊,會比在單純的原始碼閱讀或在技術社群裡逛部落格點贊要來的更高。而每一個發展中的專案,都會有不少已發現或未發現的 bug 等待我們去修復。在這個參與的過程中,你的工作不僅能讓社群收益,也能夠更多地讓自己獲益。

不過,【如何閱讀原始碼】已經脫離了本文的討論範圍。在此我們點到為止就足夠了。

友善的互吹評價

參與開源專案和搬運文件相比,很重要的一點區別在於和其他人之間的互動。你的 Issue 會有人評論、程式碼會有人 Review,PR 也會有人點贊。這時候,和其他人的互動是少不了的。在 Github 這樣的英文技術社群,合適的交流方式對促進社群發展是很有幫助的。

這裡我們只分享一點:如何更友善地對其他人的工作作出評價。在中文社群,除了【伸手黨】以外,還經常能夠看到【噴子】直接抨擊專案質量或者給人蓋上【抄襲】的帽子。不過,吐槽別人的程式碼肯定是少不了的。在社群中交流時怎麼樣更委婉地指出 PR 的問題或在 Issue 中回覆觀點呢?

很有趣的一點是,在 Github 上很少看到這些詞:

bad wrong dirty terrible ***...複製程式碼

更基本看不到這樣的說法:

I think this code is bad and do things wrong!複製程式碼

與直接吐槽程式碼 bad 相對地,不妨這麼說:

  • 表達 API 笨重不好用,可以說 heavy to work with
  • 表達模組結構不好,可以說 not intuitive
  • 表達處理方式太粗暴,可以說 overkill
  • 表達邏輯可能有漏洞,可以說 leaky
  • 表達要引入的東西太多,可以說 aggressive
  • ...

I think 則顯得非常武斷,可以這樣:

  • 萬能的 IMOIMHO,即 In my (humble) opinion
  • 補充一個 Not sure, maybe missing something
  • To my knowledge 或者 For me

以及,在請求其他貢獻者 Review 或合併時,記得加上 Would you pleaseCould you please 也是很不錯的。哦對了別忘了 Thanks 啊。

總之探索合適的溝通詞彙是一件很有趣的事情,不過對英語的要求並不高,運用上面的介紹其實只要初中英語水平就足夠了吧…相信有興趣的同學能夠總結出更多【開源黑話】?另外,不少專案的 Code of Conduct 也值得一讀。

有效的溝通

貢獻社群的過程並不是上來就把程式碼砸到人臉上,許多 bugfix 都是需要和上游維護者討論方案後再做決定的。這時除了客氣的言辭外,溝通的方式也很重要。在此個人總結了這麼幾點:

提問式的反駁

蘇格拉底有種和人辯論的方式是,不停地向對方提問,直到對方答不上來為止。在社群的交流中,這種方式同樣很常見。

比如,在認為一個 PR 存在著未考慮到的邊界情形時,作為 Reviewer,比起直接判斷 You are missing XXX,評論 How is it when XXX 就巧妙地【把鍋丟了回去】,能夠客氣地讓提交者進一步說明對特殊情況的判斷或修改程式碼,而不是直接【把天聊死】。

同樣地,在不認可某種 Workaround 方式時,回覆 I don't know what you mean at... 然後等待對方的解釋,效果也比直接說 This is wrong 要更好。

注意描述方式

在提交 Issue 時,不同的描述方式可能會帶來不同的優先順序與不同的處理結果。舉一個最近遇到的例子:

我們參與的專案中,有一個描述【效能問題】的 Issue,內容大致是【輸入內容大的時候速度特別慢】。這個 Issue 被晾了一兩週沒有人處理。而我在除錯後找到了一個特殊的場景,這時反覆的重繪會讓頁面崩潰。在將【頁面死迴圈】作為標題提交 Issue 後,作者在當天就修復了這個問題,而效能問題也一併解決了。

模板與工具

其實上面的不少內容是有固定的套路可循的。比如,Issue 和 PR 都有相對固定的模板,幫助參與者提高溝通的效率。

對 Issue 來說,常見的模板大致是這樣的三段論:

  1. Bug or Feature?
  2. Current Behavior?
  3. Expected Behavior?

而對於 PR 來說倒不一定需要長篇大論,正式一些的結構大致是:

  1. This Closes #xxx
  2. Current Behavior / Reason
  3. Solution

在提交 Issue 時,提供復現的例子、步驟或 GIF 是非常重要的。這時我們可以用 JSFiddle 提供簡單的復現例子,在 Mac 上也有 Giphy Capture 這樣免費的 GIF 動畫錄製工具來提供幫助。

最後,在 Git 提交時,整潔的提交記錄也是很大的加分項,這方面有興趣的同學不妨參考作者之前的文章:使用 git rebase 提高 PR 質量

總結

參與到開源社群中是個既有挑戰也有成就感的事情。比起國內網際網路公司常見的招聘 slogan【你的一行程式碼,能影響多少多少人】來,貢獻到開源專案中,就意味著【你的程式碼能夠被多少多少公司】使用,這無疑是更高的層次,也會有更多的挑戰。如果覺得日常的增查改刪邏輯已經讓你感到厭煩,那麼參與到社群中來或許能為你開啟新世界的大門。

這裡順便安利一下我們目前維護的編輯器專案 Slate。這是一個優秀而迭代迅速的富文字框架,目前還處在大刀闊斧地新增新特性和新功能的 beta 時期,有非常多參與貢獻的機會,原始碼的風格與註釋也相當完備。另外有趣的一點是作者和 Evan You 一樣有著設計師的背景(不妨想象一堆程式設計師給 UI 設計師寫的程式碼修 bug 的場景)。我也在之前的部落格裡安利過 Slate,希望能有更多的同學來嚐鮮!

最後我們引用 Chrome V8 專案的一個原則作為本文的總結吧:

In short, do the right thing for the project, not the easiest thing to get code committed, and above all: use your best judgement.

相關文章