2011年在 Nicole Sullivan舉辦的 Velocity大會(huì)上我介紹了第一個(gè)CSS代碼質(zhì)量工具 CSS Lint, 我們花費(fèi)之前的兩周瘋狂的編碼, 嘗試著構(gòu)建一個(gè)終用戶有用并且易于修改的應(yīng)用. 我們所有人都沒(méi)有啟動(dòng)這樣一個(gè)開(kāi)源項(xiàng)目的經(jīng)驗(yàn), 因此我們也在這過(guò)程中學(xué)到了很多.
初期經(jīng)過(guò)一段時(shí)間的試錯(cuò), 項(xiàng)目后進(jìn)入正軌, 現(xiàn)在也時(shí)常獲得CSS Lint用戶和CSS Lint貢獻(xiàn)者們的贊許. 其實(shí)在你經(jīng)過(guò)思考確定目標(biāo)之后創(chuàng)建一個(gè)成功的開(kāi)源項(xiàng)目并沒(méi)有想象的困難.
你的目標(biāo)是什么?
這一段時(shí)間, 好像很多人寫(xiě)了一代代碼加上一段開(kāi)源軟件協(xié)議, 再把它發(fā)布到GitHub, 然后說(shuō): "我把它開(kāi)源了". 創(chuàng)建一個(gè)開(kāi)源項(xiàng)目并不僅僅是讓你的代碼可以自由的被訪問(wèn)獲取. 所以, 在向世界宣稱你開(kāi)源了那么些除了你自己在空閑時(shí)間使用而還沒(méi)有其他人使用的東西之前, 停下來(lái)問(wèn)一下你自己, 對(duì)于這個(gè)項(xiàng)目, 你的目標(biāo)是什么?
首要的目標(biāo)通常是: 創(chuàng)建點(diǎn)有用的東西. 對(duì)于CSS Lint, 我們的目標(biāo)是為提升CSS 代碼質(zhì)量,創(chuàng)建一個(gè)易適應(yīng)各開(kāi)發(fā)者開(kāi)發(fā)流程且易擴(kuò)展的工具. 而不論這開(kāi)發(fā)流程是否是自動(dòng)化的. 另外, 通過(guò)找尋做類似項(xiàng)目的人, 并且想清楚你面向的用戶基數(shù)有多大來(lái)確保你所提供的東西是有用的.
在那之后, 應(yīng)該被放在第一位的是 決定為什么你要開(kāi)源這個(gè)項(xiàng)目. 僅僅是因?yàn)槟阆敕窒砟阃瓿傻臇|西? 你有打算持續(xù)開(kāi)發(fā)這些代碼還是僅僅只是把他們?nèi)拥酵饨缭僖膊还? 如果你沒(méi)有打算持續(xù)開(kāi)發(fā)這些代碼, 那么這篇文章剩下的部分不適合你. 確保在你代碼庫(kù)中的readme文件里面清晰的聲明了你會(huì)持續(xù)開(kāi)發(fā)這一點(diǎn)以避免找到這個(gè)項(xiàng)目的人對(duì)此感到困惑.
如果你準(zhǔn)備持續(xù)開(kāi)發(fā)你的代碼, 你考慮過(guò)接受別人的貢獻(xiàn)嗎? 如果答案否定, 再一次, 這篇文章不適合你. 如果答案肯定, 接下來(lái)你有些工作要做了. 創(chuàng)建一個(gè)接受外界貢獻(xiàn)的開(kāi)源項(xiàng)目的工作量比它表面上看起來(lái)需要做的多. 你不得不創(chuàng)建一個(gè)環(huán)境, 這個(gè)環(huán)境可以讓那些不熟悉這個(gè)項(xiàng)目的人都能很快上手并應(yīng)用此項(xiàng)目迅速提高他們的開(kāi)發(fā)速度和生產(chǎn)能力, 要做到這點(diǎn)需要一些計(jì)劃.
這篇文章是讓你了解如何開(kāi)始一個(gè)開(kāi)源項(xiàng)目并達(dá)到下面這些目的:
創(chuàng)造一個(gè)對(duì)他人有幫助的東東
制訂項(xiàng)目計(jì)劃并不斷完善你所創(chuàng)造的項(xiàng)目
接受其它人貢獻(xiàn)的代碼(也許會(huì)有money)
選擇開(kāi)源許可證
在發(fā)布你的代碼之前,重要的一個(gè)事情是選擇一個(gè)開(kāi)源許可證。選擇不同的開(kāi)源許可證會(huì)影響你項(xiàng)目的參與者。所有的開(kāi)源許可證都會(huì)保留你個(gè)人作為代碼創(chuàng)建者的版權(quán)。雖然許可證的授權(quán)概念有點(diǎn)復(fù)雜,但一些常用的許可證和基本的東西還是要了解的。(如果你的開(kāi)源項(xiàng)目屬于公司性質(zhì),在選擇許可證之前先咨詢一下公司的法律顧問(wèn))
GPL
GNU公共協(xié)議是為GNU項(xiàng)目而創(chuàng)建,并且隨著linux作為一種可變的操作系統(tǒng)已被大家所接受,GPL許可要求任何使用基于GPL授權(quán)的組件也必須要在GPL下可用。簡(jiǎn)單而言之,任何使用基于GPL授權(quán)的組件在任何方式下都必須在GPL許可下開(kāi)源。GPL授權(quán)的程序沒(méi)有在使用上限制,這個(gè)限制僅僅和派生作品的修改和發(fā)布有關(guān)
GNU寬通用公共許可證是一種GPL更加寬松的版本。基于LGPL授權(quán)的組件可能關(guān)聯(lián)到程序,但是程序本身并不必開(kāi)源或者基于GPL或LGPL授權(quán),換句話說(shuō),LGPL和GPL相似,因此任何派生作品也必須開(kāi)源。
MIT
亦被稱為X11協(xié)議。該協(xié)議相對(duì)寬松,對(duì)于使用該協(xié)議的項(xiàng)目,協(xié)議的遵循者必須自動(dòng)放棄對(duì)該項(xiàng)目代碼發(fā)布權(quán)以及使用權(quán)的私有,而賦予公眾相應(yīng)權(quán)利。因此,遵循MIT協(xié)議的代碼或許被會(huì)被引用在一些沒(méi)有聲明遵循某項(xiàng)協(xié)議的特定代碼中。此外,MIT協(xié)議與GPL協(xié)議兼容,所以你完全可以用MIT協(xié)議下的代碼來(lái)開(kāi)發(fā)GPL協(xié)議的應(yīng)用。
BSD3
協(xié)議有點(diǎn)松,有點(diǎn)松……該協(xié)議相對(duì)寬松,對(duì)于使用該協(xié)議的項(xiàng)目,協(xié)議的遵循者必須自動(dòng)放棄對(duì)該項(xiàng)目代碼發(fā)布權(quán)以及使用權(quán)的私有,而賦予公眾相應(yīng)權(quán)利。此外,項(xiàng)目中任何以二進(jìn)制形式發(fā)布的代碼(譯者注:貌似.bin文件之類的),也需要在許可文檔中聲明該協(xié)議。那么,該協(xié)議與MIT協(xié)議的區(qū)別在哪里呢?當(dāng)該協(xié)議的標(biāo)的物(譯者注:一般,這里的“標(biāo)的物”是聲明使用該協(xié)議的代碼,為了保證嚴(yán)謹(jǐn)性,在此進(jìn)行注釋)被其他人使用時(shí),他們不可以用該標(biāo)的物的所有權(quán)人的名字進(jìn)行商業(yè)宣傳。例如,如果我寫(xiě)了一段遵循該協(xié)議的代碼,而你把他用著自己的應(yīng)用里面,你是不可以用哥哥我的名字去做宣傳的,除非經(jīng)過(guò)我的同意。后,BSD3協(xié)議也是和GPL兼容的。
好吧,其實(shí)還有很多開(kāi)源協(xié)議本文沒(méi)有介紹,但是以上協(xié)議應(yīng)該是受大家關(guān)注的。
需要注意的一點(diǎn)是 Creative Commons許可證并非設(shè)計(jì)來(lái)于軟件的. 所有的 Creative Commons許可證都是為"創(chuàng)造性工作"制定的, 例如音頻, 圖像, 視頻和文字. 制定 Creative Commons 的組織他們自己也不推薦將 Creative Commons許可證用于軟件, 應(yīng)該在軟件中使用專門為軟件制定的許可證, 通常也是上文討論的四種.
因此, 你應(yīng)該選擇哪個(gè)許可證呢? 這點(diǎn)大部分由你想別人怎么使用你的代碼決定. 因?yàn)長(zhǎng)GPL, MIT 和 BSD3都和GPL完全兼容, 這還不是需要關(guān)注的. 如果你想所有你軟件的修改版本都只被用于開(kāi)源軟件, 那么你應(yīng)該選擇GPL. 如果你的代碼是設(shè)計(jì)成一個(gè)不需要修改而可以直接引入別人的項(xiàng)目使用的組件, 那么你可能會(huì)考慮LGPL. 否則, MIT和BSD3許可證時(shí)比較通常的選擇. 個(gè)人比較趨向于喜好MIT許可證, 而商業(yè)上可能更加的偏向于喜好BSD3許可證以保證他們的公司名稱不會(huì)被未授權(quán)的使用.
為了幫助你做決定, 看一下這些流行的開(kāi)源軟件項(xiàng)目都使用了些什么協(xié)議:
jQuery: MIT license
YUI: BSD3 license
Dojo Toolkit: dual-licenced under BSD3 and Academic Free License
Backbone: MIT license
另外一個(gè)選擇是直接把你的代碼發(fā)布為 public domain(公有領(lǐng)域), 在 public domain中的代碼沒(méi)有版權(quán)擁有者, 這些代碼可以完全隨意使用. 如果你沒(méi)有打算保持你對(duì)代碼的控制全 或者 你只是想向世界分享你的代碼而不打算持續(xù)開(kāi)發(fā)它, 那可以考慮一下把代碼發(fā)布到 public domain.
想進(jìn)一步了解許可證與它們相關(guān)的法律問(wèn)題以及這些許可證如何工作, 請(qǐng)閱讀 David Bushell的 Understanding Copyright and Licenses.
代碼組織
決定在你的開(kāi)源項(xiàng)目中使用何種許可證以后, 這幾乎是時(shí)候把你的代碼放出來(lái)了. 但是在這之前, 你得先看看代碼是怎么組織的. 不是所有代碼都會(huì)得到大家的貢獻(xiàn). 如果一個(gè)潛在的貢獻(xiàn)者無(wú)法通讀你的代碼, 那么他非常可能也沒(méi)法做出任何貢獻(xiàn). 在你分享你的代碼給公眾之前, 你組織代碼的方式, 包括文件目錄結(jié)構(gòu), 代碼風(fēng)格都是需要認(rèn)真考慮的因素. 別隨意把你胡亂寫(xiě)的代碼扔出來(lái). 多花點(diǎn)時(shí)間考慮別人可能會(huì)怎么閱讀你的代碼以及他們?cè)谶@過(guò)程中可能會(huì)遇到什么問(wèn)題.
對(duì)于CSS Lint, 我們選用了一個(gè)基本的 頂層目錄結(jié)構(gòu): src 用于主源代碼, lib 用于外部依賴, test 用于測(cè)試代碼。 src目錄進(jìn)一步分為子目錄, 分類相關(guān)的文件。 所有的CSS Lint規(guī)則都在 rules 子目錄; 所有的輸出格式化都在 formatters 目錄等等。 test目錄劃分子目錄與src目錄相同, 這樣可以標(biāo)示測(cè)試代碼和主代碼的關(guān)系。 隨著時(shí)間過(guò)去, 我們因?yàn)樾枰呀?jīng)添加了頂層目錄, 但基本結(jié)構(gòu)和開(kāi)始做的是一樣的。
文檔
很多對(duì)開(kāi)源項(xiàng)目的抱怨是由于缺乏文檔。寫(xiě)文檔往往沒(méi)有寫(xiě)程序來(lái)得有趣,但對(duì)于開(kāi)源項(xiàng)目成功卻至關(guān)重要。如果你不想要?jiǎng)e人使用你的軟件,不想要人們貢獻(xiàn)代碼,那么只要不提供文檔行了。我們的CSS Lint一開(kāi)始犯了這個(gè)錯(cuò)誤。項(xiàng)目剛啟動(dòng)時(shí),我們沒(méi)有提供文檔,結(jié)果大家都不知道怎么用這個(gè)東西。不要重蹈我們的覆轍,在啟動(dòng)項(xiàng)目之前,一定要做好文檔的工作。
文檔應(yīng)該很容易被更新,而且不需要push代碼可以更新,必須能根據(jù)用戶的反饋快速地修改。也是說(shuō),不要把文檔與代碼放在一個(gè)倉(cāng)庫(kù)里。如果你把代碼放在GitHub上,那么可以用GitHub內(nèi)置的wiki來(lái)放文檔。我們的CSS Lint是把文檔放在wiki上。如果你的代碼不是放在GitHub上,那么可以用自己的wiki或其它類似的系統(tǒng)來(lái)放文檔,以便實(shí)時(shí)地更新它們。好的文檔系統(tǒng)應(yīng)該是很容易更新的,否則你可能永遠(yuǎn)都不會(huì)去更新它們。
終用戶文檔
無(wú)論你寫(xiě)的是命令行程序、應(yīng)用框架、工具庫(kù)還是其它什么東東,都要把終用戶深深地放在腦海里。終用戶并不是修改你代碼的人,而是使用你代碼的人。拿我們的CSS Lint來(lái)說(shuō),大家一開(kāi)始不知道怎么用,因?yàn)槲覀儧](méi)有給出終用戶文檔。爭(zhēng)取不到終用戶,也爭(zhēng)取不到貢獻(xiàn)者。對(duì)你的代碼滿意的終用戶們后會(huì)成為貢獻(xiàn)者,因?yàn)樗麄兛吹搅颂N(yùn)含在代碼中的價(jià)值。
開(kāi)發(fā)者指南
即時(shí)你的代碼布局合理,文檔豐富,也無(wú)法保證一定會(huì)有貢獻(xiàn)者出現(xiàn)。你需要一份開(kāi)發(fā)者指南,讓那些貢獻(xiàn)者們快速融入進(jìn)來(lái)。一份好的開(kāi)發(fā)者指南應(yīng)該有下面這些內(nèi)容:
如何獲取源代碼:你當(dāng)然希望貢獻(xiàn)者們都知道怎么check out代碼,但世事無(wú)。一份友好的介紹總是受人歡迎的。
代碼是如何組織的:即使你的代碼和目錄結(jié)構(gòu)很清晰,完全能自我說(shuō)明,也好寫(xiě)下來(lái),總有用處的。
如何設(shè)置構(gòu)建系統(tǒng):如果你用了某種構(gòu)建系統(tǒng),那么應(yīng)該提供一份怎么設(shè)置這個(gè)系統(tǒng)的說(shuō)明。如果構(gòu)建時(shí)的一些依賴項(xiàng)沒(méi)有包含在你的倉(cāng)庫(kù)中,那么這份說(shuō)明中還應(yīng)該包括怎么獲取這些依賴項(xiàng)的信息。
如何構(gòu)建:如何進(jìn)行構(gòu)建以及單元測(cè)試的步驟。