引言:如今的JavaScript已經是Web上最流行的語言,沒有之一。從Github上的語言排行榜https://github.com/languages上即可看出,也是如今最為活躍的開源社群。隨著Node的加入,JavaScript開枝散葉進入伺服器領域,為這個語言榜的佔比,也貢獻了幾分熱度。儘管經歷了Web2.0的洗禮 ,但在國內談及開源,開源人士似乎都當這門語言並不存在,這也意味著國內的開發中堅階層,並沒有改變JavaScript以及前端過去二流形象的認識,也沒意識到JavaScript如今真正的價值。歷史原因造就如今的局面,但是你並不能就此否認,一個出身不好,小時候還挺調皮的孩子,他長大後就是沒有出息。本文將介紹一個優秀的JavaScript模組應該是怎樣煉成的,以期望未來國內的開源社群能夠湧現出更多的優秀模組。
引起我寫這篇文章衝動的是近期接觸到moment模組時的震驚。用JavaScript寫程式,通常要經歷兩個階段:第一個階段是採用一些模組來擦除JavaScript語言(跨平臺)自身的問題;第二個階段是自己寫一些方法來擦除引入的模組的問題。第三個階段才會真正進入業務開發中,前兩個階段俗稱“擦屁股”。時常在第三個階段時,我會陷回到第二個階段,和各種模組碰撞,往往會引起一些心情上的不舒爽。而在接觸到moment時,這些煩惱瞬間消散,我在心底知道為何會如此釋懷,如碰到心儀的女神。這也讓我回頭反思過去在使用和寫模組過程中遇到的挫折和收穫,這落差讓我產生了如此的衝動,此文算是一個總結,期望能在汲取優秀模組的經驗中,國內開源社群能夠成長起來。
為什麼是模組,而不是庫或者框架
在過去幾年做前端的同學多半談論的是庫,或是框架,提及庫則是Prototypejs和jQuery,框架則是YUI3,Dojo、Extjs等。關於庫或者框架的,對應的比喻則是大教堂和集市。在最早的時間,大教堂和集市的建設都在同步行進,具有代表意義的是YUI3和jQuery,前者Yahoo!投入許多精力,歷時兩代完成,後者則是集市建造的典範,由John Resig建立,社群參與。最後看看後續的反饋:
大教堂未必優質
大教堂模式產出的作品,讓享用者可以有一步到位的服務,無需其他。但是由於大教堂的建設過程中承擔著解決所有問題的使命,這導致它逐漸變得龐大,儘管它有著巨集大而美妙的結構,像一首長長的讚美詩,任何一段都可以被唱詩班演唱得動聽。但是,弱點依舊暴露出來:
1、區域性的優良程度未必是最好的;
2、龐大的結構導致靈活度下降,升級困難。
3、任何一條龍服務,都不能保證每個環節都是優異的。
小集市鑽石閃爍,沙礫良多
小集市的特點是開放式建設、週期短、成本低。大多數建立出來的集市是功能簡陋、品質平庸的。jQuery是一個值得玩味的現象,品質極高,但是它帶來的外掛市場,卻體現了小集市的另一面,大多數的jQuery外掛的質量卻十分低下。
可以說小集市模式建立出來的作品,在單點上,是能夠超越教堂模式作品中對應的那部分。前者缺乏一個巨集偉的結構,但是在微觀上,它是完善的,可以隨意挪移的。後者雖然具備優良的結構,但在單點上並非優秀,這也容易讓人懷疑是否其他點上也並不優秀,而且教堂式作品的一個特點則是,區域性是不可移植的,非獨立性的,這在YUI3中表現十分明顯。
上述對比很容易讓人聯想到,如果一個架構的特性具備單點可移植,可拆卸,自身極其輕量,汲取了大教堂和小集市的優點。那必將是一個全新的時代,那是一個可以DIY的時代。原有的大教堂模式由於缺失了靈活性,在迭代迅速的開發中,必將淘汰。而小集市儘管良莠不齊,好在預留了選擇權利給使用者,並且他的開放性也預示著它的可成長性,所以還有未來可期。
沒錯,如今這個時代已經到來。庫通常是一個比框架小一個粒度的單元,模組則是比庫更小一個粒度的單元。一個庫可能由幾個模組組成,框架則可能是在幾個庫的基礎上構建。不再談論庫和框架的原因是將庫和框架的架構部分還給開發者,以便開發者可以根據實際業務去構建合適的解決方案。任何框架或庫都只具備解決某一方面的能力,不具備普適性。當粒度降低到模組級別的時候,構建任何上層業務,可以實現按需使用。由於模組的粒度更小,所以相對庫而言,更加專注,變優秀的成本更低。類比孩子在充滿沙礫的海邊奔跑,但很容易裝滿一口袋的貝殼。對於稍具慧眼的開發者而言,挑選一堆適合的模組來解決業務的問題,比使用教堂式作品或者更高效。
這種方案因為CommonJS模組規範的影響,已經在既定事實中成型。在Node中,NPM平臺(https://npmjs.org/)上13000+的模組數量可以說明這個問題。前端中由於受到歷史原因的影響,進展較慢,國內玉伯的SeaJS在推動此事,Arale是在SeaJS基礎上建立了一些模組,這類模組可以非常容易遷移到其他符合CommonJS模組規範的環境中。除此之外騰訊的JX也具備SeaJS的特性,可以輕鬆將別的庫應用到JX中,但是還不夠規範。
如果非得給這種模組提供方式一個名稱,我覺得該叫做小教堂模式,具備小集市的小,意味著這個教堂可能只提供祈禱服務,如果註冊結婚,則需要換另一家小教堂。但是這類小教堂的服務是最優質的。建立這類小教堂只比建立一個優異的小集市略費成本,換言之,優異的小集市就是小教堂,它的建立方式是沿襲小集市的開放、透明的、有既定目標的成長性的。
另一個考慮是,在大部分的情況下,我們是不需要大教堂的,現實中為了整體環境,我們寧願在大教堂中祈禱,但是程式設計中,我們不會因為喜歡一棵樹木,而買下整塊山頭,我們幾乎不喜歡任何看起來多餘的部分。同時我們也不需要小集市,我們需要的是一個品質優良的商場。開發者是採購者,採購模組的過程既是架構的設計的過程。
前文我也提到這種小教堂的模式依然存在不理想的功能重疊、功能多餘、功能缺陷、功能衝撞等問題。可謂說完美的小教堂是可遇不可求的,但一旦它完美,將再難被替換。目前階段的JavaScript模組開發還存在著這些問題。是故,如果開發者瞭解如何去打造一個優秀的JavaScript模組,並樂於貢獻到開源社群,這將大幅提升社群JavaScript水平,後續的開發者在做業務架構時,將具備更優質的材料來DIY更優異的產品。
煉成優秀模組的最佳實踐
其實這並不算是精確的最佳實踐,只是從別的模組哪裡學習到的和自己過去的一些經驗,僅做一定的總結。歡迎補充和討論。
模組自身的素質要求
要寫出一個優秀的模組,模組自身的素質十分重要,如果自身條件太差,成為優秀模組的概率是極小的。這些自身素質包括美好的願景、專注的定位、名字、API設計、文件、測試等。
合理的願景:設定既定目標
如果你打算寫作一個模組,並貢獻到開源社群中,並期望它是優異的,並被許多人使用的,那麼為它設定一個既定目標是首要的。如果這個目標是沒有意義,沒有趣味的,那多半沒有人使用,甚至自己開發到一半都沒有興趣繼續寫下去。沒有理想的屌絲,註定不能成為高富帥。
對於具備眾多坑爹問題的JavaScript語言而言,找到一個目標並非難事。典型的例子如:jQuery專注解決DOM操作和Ajax、Underscore專注物件和集合的操作、QUnit和Jasmine專注BDD和TDD的單元測試、moment模組專注解決從Java那裡學過來的Date的問題;拿近一些的例子,玉伯的SeaJS專注模組載入,老趙的Wind.js專注非同步程式設計同步化來解決流程控制問題;拿一個有趣的例子,PNGDrivehttps://github.com/MadeInHaus/PNGDrive這個專案雖然沒有什麼實際用處,但是將檔案編碼為圖片顯示出來的方式足夠有趣。
另外這個目標必須是既定的。也就意味著餅不用畫為無限的,這個目標一定是可以完成的。如果目標太大,也就意味著模組自身會變複雜。jQuery相容各種瀏覽器的DOM操作這個目標,在移動平臺上變得沒有意義,所以存在著Zepto.js這樣的專案。更小的目標意味著模組自身簡潔,且能夠更專注,目標更容易抵達。一旦抵達目標,該模組就是穩定的,未來被替換的機會極小。
為模組或專案起一個貼切的名字
模組需要一個貼切而好記的名字。這個名字何以幫助使用者最直觀地感受模組。SeaJS在起名上算是一個表率,讓人很容易有海納百川的聯想,這也正是SeaJS的行為。一個好的名字可以使得模組的後期推廣事半功倍,而且一旦開始推廣,儘量不要換名字。
不做逾越的事
並非每個使用者都喜歡買一送一的感覺,因為後面這個一,對於使用者而言,並非是期望的,所以它的優良無法直觀的判定好壞。無關的方法一定不要提供。評判一個模組是否完美,不是可以新增API,而是無法再減少API了。
不汙染公共環境
每個人都不喜歡公共環境被人汙染。破窗效應揭示,如果一輛汽車的門窗稍有損壞,不立即修復,那麼很快整輛車就會被破壞甚至偷走。 在JavaScript,公共環境包括全域性變數,原型鏈等。jQuery和Underscore為了程式碼的寫作方便,佔用了$和_兩個符號,儘管他們都提供了noConflict方法來避免衝突,但是抱怨者還是大有人在。所幸這兩個庫太過於知名,幾乎沒有再有的庫來使用這兩個變數名。另一個例子是Prototype.js庫對物件進行擴充套件時,直接在Array、Object等原生物件的原型鏈上新增方法,儘管它看起來不影響,但是總有衝突的一天,並且使用者並不一定知曉原型鏈被改動,在他的預設上下文中,難保他也不去修改原型鏈。相比Prototype.js的做法,Underscore提供的方法則優雅許多,另行提供API來處理操作,而不是修改共有的原型鏈。
在Node和瀏覽器中,global和window是全域性物件,如果隨意放置變數到全域性物件上,也容易遭到他人修改或者覆蓋你變數的事情。
CommonJS提供的require、exports則十分優雅解決這個問題。誰使用,誰引入。而不是通過全域性變數。在前端沒有AMD或者CommonJS環境下,則是採用名稱空間和閉包來解決這個問題。
不汙染公共環境是模組與模組之間互相不影響的基本保證。如果引入你的模組,導致其他模組失效的事情,多半是不招人待見的。
抵制墨菲效應
有可能變糟糕的事情,它變糟糕的可能性就會變大。模組在升級,迭代的過程中,如何避免這種糟糕的事情發生呢?答案是單元測試。當單元測試覆蓋了你認為會出問題的地方,可以避免相同的錯誤再次發生。這是模組穩定迭代的基本保證。當我發現一個僅僅為了解決日期操作的moment模組,它為數不多的API竟然具有多達7000+的斷言時,十分驚訝。
過去JavaScript只做簡單的事情,地位低下,所以對於JavaScript的質量保證也極少。這個思維需要改變,一個使用者在評估採用你的模組時,如果單元測試都無法看到,心裡該是有多不踏實。
除此之外,還有效能測試,效能測試結果可以橫向比較,也可以縱向比較,有利於感知模組的具體效能表現。
資料通常容易打動理性的人。
保持簡潔
對於任意看起來複雜的事物,使用者均會覺得它很複雜。老趙的Wind.js(前身是Jscex)是一個想法獨特的模組,但在提供的API上由於eval,以及需要引入的模組較多,讓它看起來比較複雜,讓使用者感覺潛意識裡複雜,這種複雜的訊號很容易變成它有問題的訊號,讓人心生疏遠。
將能不暴露給使用者看到的東西,儘量隱藏,過多的步驟只會讓使用者覺得麻煩和不靠譜。
職責單一
這裡的反面例子來自於Require.js。如果你用過RequireJS,可以看到require方法是一個變態的設定,引數為’a’、[‘a’]、[‘a.js’]、{}他們的行為都是不一致的。這種引數型別可以隨意變化是JavaScript的靈活的地方,但是函式的行為如果也發生變化,這會讓人產生迷惑。適當的過載並不意味這行為也要完全不同。
功能過多,帶來的問題的可能性也會變大,使用者在呼叫過程中也會增加無形的壓力。分離功能可以保持方法職責單一會是你API優秀的一部分。
編碼風格
編碼風格一定需要統一,而且編碼風格一定不要顯得外行。如果你的使用者發現你的編碼風格是PHP或者C#的,他們可能會產生你不是專業的這個感覺。推薦貼近JavaScript社群,採用JSLint或JSHint來矯正編碼風格。這有利於原始碼的閱讀,在不同的人之間傳遞不會有不換了一門語言的感覺。
API介面漂亮
API介面漂亮包含幾個方面:
命名
對外API的命名需要謹慎對待,方法名太長、方法名不直觀、方法名大小寫不對、方法名單詞太複雜都會影響到使用者的直觀感受。由於國內的英文水平高低不一,使用者遇見不認識的單詞,都會造成障礙。
jQuery在方法命名上十分優秀。簡短,直觀,優雅。
呼叫
實參的傳入也是考驗API設計者的地方。如果需要呼叫者傳入的引數較多,則該反思該API是否適合暴露給呼叫者。如果呼叫引數確實較多,並且支援可選項,則傳入一個物件作為引數較為合適。由於物件帶有明確的key,獲取引數也無需一個一個檢測。
$.ajax()是一個典型的例子,它支援的引數非常多,並且大多可選。所以暴露的API為$.ajax(url, obj)或$.ajax(obj)。
在JavaScript中,鏈式呼叫也是讓使用者較為喜愛的一點。Underscore除了提供普通的API外,還支援包裝物件之後進行鏈式呼叫。這讓熟悉函數語言程式設計的人,頓生親切。
習慣
Zepto.js是一個經典的案例,它提供了與jQuery幾乎完全相容的API,為的是照顧使用者對於jQuery的熟悉。這讓它可以零成本被應用到移動瀏覽器上。
jQuery的另一件反面例子則是它的each方法,與原生陣列的forEach方法的回撥傳入值次序不同,這與習慣不同的介面,會造成一定反感心理。 在設計API的過程中,儘量尋找貼合使用者習慣的已有形式,這會讓使用者易於接受。
可擴充套件性
模組在開發的過程中,可以包括有限的部分和無限的部分。有限的部分將會通過專案迭代,臻於完美。如果模組存在無限的部分,並且在有限的部分留出擴充套件來衍生無限,這對於模組的成長,這是一個大大的加分項。
jQuery留出$.fn來供使用者擴充套件它,形成的影響是大量的jQuery外掛湧現了出來。儘管大多數情況沒有被正確使用,但不能掩蓋它是一個漂亮的設計。
moment模組在它的lang部分,也提供了優雅的擴充套件它的部分。使得不同地區的使用者可以自定義語言的顯示。
擴充套件性的存在,使得開源社群能夠參與,能夠起到拋磚引玉的效果,反過來會增進模組的功能。
使用合適的設計模式
合適的設計模式可以讓模組自身無瑕。不合適的設計模式則會適得其反。
這裡的正反例子都與jQuery相關。正例子是Deferred的應用。過去ajax操作success和fail回撥都必須寫到$.ajax(obj)的引數物件中,但是Deferred物件使得呼叫更加自然:
1 2 3 |
$.get("test.php").done(function() { alert("$.get succeeded"); }); |
LABjs的設計模式也十分優秀,script和wait兩個用於載入和阻塞的API,通過鏈式呼叫,其樂融融:
1 2 3 4 5 6 7 |
<script> $LAB .script("framework.js").wait() .script("plugin.framework.js") .script("myplugin.framework.js").wait() .script("init.js").wait(); </script> |
反例子則是來自jQuery外掛。jQuery.fn不失為一個好的擴充套件點,但是有大量的jQuery外掛操作的並非DOM,卻生搬硬套將方法掛靠在jQuery.fn上。另一個例子則來自jQuery社群得意的UI元件。
1 |
$(foo).dialog('open') |
這類通過傳入引數,又不能得到期望的返回值的場景,並不適合操作這個元件物件,API的引數傳遞更是顯得不倫不類。如果是直接操作元件物件,則更友好一些。相比jQuery UI,YUI3的元件則優秀太多,API漂亮,元件的層次結構分明,易於擴充套件和自定義,jQuery UI通過外掛方法的呼叫方式,自定義元件的代價極大。
合理的目錄結構
開發方式多半會影響到後續的使用方式。儘管前端指令碼多半都是提供一個檔案給使用者,但是在開發過程中,合理地組織自己專案的目錄結構是值得注意的。jQuery的原始碼目錄中,各個功能點都分別寫在各自的檔案中,使得開發過程中編寫程式碼方便。
另一方面,CommonJS的包規範還定義了以下目錄和檔案:
1 |
<span style="color: #888888;">bin doc test lib package.json</span> |
分別用於存放二進位制檔案、專案文件、單元測試用例、原始碼。package.json檔案則用於描述該包的一些包括包名、版本號、依賴等的資訊,詳情見http://wiki.commonjs.org/wiki/Packages/1.0。遵循規範的目錄結構通常更好一點,因為大家都有同一個準則來參考,彼此更熟悉。
鉅細的註解
通常使用者真正需要去閱讀你的程式碼的時候,是出現問題的時候。在開源社群,如何讓發現你問題的人剛你改進程式碼,註釋的作用功不可沒。
另外,當一個使用者真正是來欣賞你的程式碼時,如果看到Underscore這樣密度的註解時(http://documentcloud.github.com/underscore/docs/underscore.html),還有拒絕它的勇氣嗎?
清晰明瞭API的文件
優秀的模組不僅僅體現在程式碼寫得好上,更多的體現在如何讓使用者使用時更舒適。API文件必不可少。我心目中的API文件應該詳細描述方法作用、引數、返回值的。甚至還應該有demo程式碼伴隨。
API文件可以通過jsdoc之類的註解文件來生成。也可以另起文件來寫。
API文件的一個特點是應該能方便查詢,能在一個頁面中展現完成的,儘量不要頁面跳轉或翻頁。
API文件最大的作用讓使用者精確理解API,使得不造成誤解,和清楚輸入輸出。
Underscore的API文件(http://documentcloud.github.com/underscore/)借用模版生成了漂亮的頁面,使得查閱方便。
一見鍾情的demo
相比Node,前端JavaScript模組更擅長做這件事情,尤其是UI庫。男女之間首次見面的第一印象,很大程度可以決定某兩個人是否會談戀愛的概率。demo提供的形式可以影響到使用者的直觀體驗,一般而言,使用者覺得越炫,但是旁邊提示的示例程式碼越簡單,越會引發使用者的好奇心。如果只有程式碼,或者只有demo,都會在表現性上打折扣。
對於Node的模組而言,由於沒有live demo的感覺,儘量展示sample程式碼,讓使用者瞭解到他的目標是否與模組的目標一致。不要讓使用者錯過你的模組,也不要讓你的模組錯過了它的使用者。
README.md
README檔案承擔的作用僅次於demo,無需讓使用者產生心動的感覺,但是一定要引導使用者更深度的瞭解你的模組,詳細閱讀你README的人,多半是有興趣使用你的模組的人在做實地考察了。一個geting start入門是必不可少的,到API文件的連結也應該有。如果空落落的README,會立馬有生疏感的。後期使用者的心得體會等相關文章,也記得更新到README中。
模組的社群打造
話說酒香也怕巷子深。在滿足成為優秀模組的基本素質要求後的首要事情是如何將模組推向開源社群,積極到社群中宣傳。
放到Github開源:不僅僅是程式碼
每一個程式設計師都應該有屬於自己的Github帳號。如果你沒有,不是Github的遺憾,而是你的遺憾。關於Github有什麼,可以參看這篇文章:如何高效利用GitHub (http://www.yangzhiping.com/tech/github.html)。 排除掉文化上帶來的好處。Github可以幫我們託管程式碼,幫我們解決版本控制的問題。它可以提供一個wiki,幫我們存放文件。它提供Issues頁面,使得別人可以為模組提出意見和反饋。提供Pull Requests頁面,使得別人可以幫我們修改程式碼後,供我們合併修改。
交流平臺的建立
交流平臺主要用於討論、答疑,使得模組作者和使用者之間可以產生思維的碰撞。交流過程可以不斷完善模組自身的不足,形成文件。主要的形式有如下:
郵件列表
國外的社群大多采用Google Groups的郵件列表來交流。郵件列表可以將討論傳送到每一個關注它的人手中。
實時交流
國外多采用IRC頻道來進行此事。國內的情況,可以選擇合適的QQ群來進行交流。
留言版
留言版的功能Github的issue具備了該功能。但是如果具備單獨的介紹頁面或者站點,整合Disqus來收集使用者的反饋會是個不錯的選擇,因為這更符合普通使用者的習慣。
版本控制
這裡的版本控制不是git的版本控制。而是模組的整體版本。標註好模組的版本是分場重要的,如果使用者需要升級模組,它能夠得到明確的指導。前端模組中通常是在檔名上,或者檔案內部寫明版本。對於Node而言,寫在package.json檔案中。
最好能夠在大版本的釋出時,通過正式的新聞頁面,或是郵件列表發出新聞通知,以顯得版本釋出的正式。
悠揚的歷史:Change Log
不要小看Change log的作用,長長的,細碎的Change log可以給使用者該模組歷史悠揚的感覺,也能讓使用者體會到寫作該模組的過程細節。每次迭代釋出的過程中,展現給使用者看當前的change log也能讓使用者知道改動的影響範圍。如果碰巧釋出了一個使用者需要的方法,他會有收到禮物的感覺。
選擇合適的License
國內的環境中,也許大家不太關心License的問題。事實上,License的選擇,會影響到使用者的評估。目前只有BSD和MIT兩種License可以讓人放心使用。對於商業公司而言,如果不是這兩種License,他們需要投入更多的精力和時間週期來評估這個模組是否可用。
但是對於JavaScript社群而言,通常採用的是MIT,所以也基本沒有問題。選好License,並在明顯且不重要的位置表明該模組在什麼License下發行。
釋出到NPM中
在Node中,搞定程式碼後,釋出到NPM中是最應該做的事。
易於獲得的感覺
npm install module
或是一個顯眼又不失素雅的Download按鈕會在潛意識中讓使用者覺得易於獲得,容易整合到現有系統中。不要做了各種分享介紹之後,讓使用者找不到獲取模組的地方。
持續整合
一個隨時都能拿出鑰匙,開出跑車的青年,必將被認為是高富帥。支支吾吾不能隨時給出結果的人,基本是屌絲無疑。
推薦註冊你的專案到travis-ci,並執行它。綠色的Passing時刻昭示該專案的可靠指數、穩定指數較高。這個小圖示也能幫助你檢測迭代是否出現問題。
漂亮的站點
註冊一個模組名字的org域名,一套簡潔明瞭的UI,清晰的導航,簡單的demo等等。細節在前後的實踐中都有提及。
標緻的Logo
如果你沒有任何視覺設計的天賦,厚著臉皮找你的視覺設計師同事要一枚吧,儘管它是一個錦上添花的事情,但是Logo在品牌認知上的功勞是不用質疑的。
線下分享交流
開發完模組後,一定記得分享給團隊的同事,他們應該是模組的首批使用者,他們給予的反饋也是最寶貴的。
另外,還可以線上下社群分享,將你的模組的推廣範圍從身邊延續到這個城市。儘管線上下社群分享模組的機會不多,但是一旦有,不要忘記介紹自己得意的模組給他人。
分享帶來的收益是明顯的,有利於自己梳理對模組的認識,也能收到使用者的直觀反饋。
及時響應反饋
也許你的模組已經很久沒有更新,但是使用者還是會發來反饋或提出問題,甚至提交pull request,請及時響應需求。如果是提出問題,說明你的文件還不夠完善。如果是提出需求,則說明你最初設定的目標還沒有完成。
善意營銷:賞金獵人
如果有使用者指出你的低階bug,或是幫你寫作了模組的體驗文章,這些事情都是值得模組作者有所表示的時候,因為這些使用者是你的忠實使用者,他們在幫你的模組成長。有所表示並不意味著要給多少錢,一些有意義的獎品或紀念品更適合拉近這些使用者與你之間的距離。
與兄弟社群的互動
一個社群如果過小,需要到隔壁的社群中釋出一些資訊讓大家知曉。如果可以,無論國內還是國外的的兄弟社群的協助推廣,將會對社群運作有很大的幫助。友情連結是一個典型的方式。
模組開發者的自我修煉
模組自身的優秀加上社群的打造可以保證模組擁有不錯質量和口碑。但是決定模組能否走得遠,模組開發者的自身素質也十分重要,這其實模組的另一個軟素質。經歷了開發階段和社群運作階段後,越發展到後期,開發者的自身修煉的影響越會凸顯。
忍得住寂寞&持續堅持
典型的例子是老趙對於Wind.js的堅持。在對Wind.js的開發和推廣上,可謂是寂寞的。略呈偏門的非同步同步化、eval、編譯等工序,被誤解和排斥的多次。這是需要忍受的,如果沒有持續堅持和忍住寂寞,模組就沒有明天。作者的熱情一旦消散,使用者的熱情也必然消散。
簡單專注
前文的願景部分提及到了簡單專注。簡單專注,不僅僅是在專案初期保持,在長久發展中,也應當如此,只有簡單專注方能保證小教堂的服務質量是最頂尖的。
奉獻精神
模組開發和推廣事實上是沒有直接的經濟收入的,而且還會耗費大量的時間和精力。但是開源事業的收益,實際上是無法用金錢進行衡量的。並且這個過程也是自願自發的,沒有人會主動來推動你。
如果確實對經濟造成影響,可以在頁面上加上donate的連結。優秀的模組不會讓這個donate連結的功能白費的。
幸運的是開源社群中不會缺乏具有奉獻精神的人,是他們在推動社群和技術發展。
演講能力
前文提到線下分享,這對於開發者的演講能力有更多的要求。演講能力的高低,是在另一個層面上提升模組的表現力,儘管這種能力不需要執行在CPU中。
文筆
模組開發者的文筆在文件的影響上是能夠直觀反映的。除此之外在社群推廣中,文案的品質也有一定的影響。如果開發者文筆能夠好到用優美的文章去傳遞模組的思想,這是令人愉悅和容易接受的。
人格魅力
模組的開發者應當具備良好的人格魅力,這包括人際關係、交流能力等。一個具備人格魅力和一個並不為人所知需要進一步瞭解的開發者,他們展現在大家面前的收效是並不相同的。後者更容易吸引他人,為模組帶來更多的使用者,這些人是你的使用者,也是你的合作者。他們的湧入,會幫助改進模組。 關於人格魅力這個軟素質,這裡不再多說,相信都瞭解他的重要性的。
總結
通過對最佳實踐的羅列,我自己相當於重溫了一遍JavaScript開源的一系列文化。而這些最佳實踐部分其實都是必要條件,通過這些最佳實踐,未必保證會有優秀的JavaScript模組產出。但是觀察如今的那些優秀模組,他們基本上都具備這些特徵。最後,JavaScript社群雖然活躍,佼佼者不在少數,但是整體水平的提升,還需時日,希望此文能夠幫助到一些開發者並歡迎討論。
關於作者
田永強,新浪微博@樸靈,前端工程師,曾就職於SAP,現就職於淘寶,花名樸靈,致力於NodeJS和Mobile Web App方面的研發工作。雙修前後端JavaScript,寄望將NodeJS引薦給更多的工程師。興趣:讀萬卷書,行萬里路。個人Github地址:http://github.com/JacksonTian。