最近隨着寫Node以及獨立的CommonJS模塊愈來愈多,我發現有一份好的文檔不只能夠幫助本身在應用這些接口的時候不至於迷糊,並且對於共同開發的狀況下,可以省去大量團隊的交流和Debug的時間。html
本文比較了5種較爲主流的Javascript註釋文檔生成工具。須要指出的一點是,Javascript是一個極爲靈活的語言,文檔生成並不像Java那樣具備絕對統一的規範,還要根據使用場景肯定哪一個工具更加適合。git
對沒有興趣瞭解細節比較的你,能夠快速瀏覽下面的總結來了解這些工具。程序員
YUIDoc是YUI的附屬項目。YUI團隊但願這個文檔工具不只僅能夠支持Javascript,而是更多的腳本語言,所以它並不考慮實際的代碼實施細節,而只是對註釋部分進行了掃描。從好的一面來講,若是你同時使用了Ruby/PHP/Python等等,YUI或許是一個比較適合的工具。從反面來講,由於它沒有考慮實施細節,你須要額外的變量聲明、同時生成的文檔有可能會和實際的實施細節不吻合。github
JSDoc 3的前身是JSDoc Toolkit。它會對代碼的具體實施進行掃描,所以你若是不按照符合JSDoc的註釋語法來進行註釋的話,可能生成的文檔一個字也沒有。雖然它的學習曲線很高,可是一旦掌握了以後,因爲它提供了完整的模版開發,事件觸發等等接口,其靈活性也是不容小覷的。設計模式
Dox是一個很是輕量級和能夠定製化的工具,它使用和JSDoc 3兼容的註釋語法標準,並將其轉化成JSON格式。所以在呈現方式上具備比JSDoc 3更強的可定製性,固然也意味着你初期的麻煩會比較多。函數
Docco是一種行間註釋的方式。比起API註釋,它更適合於註釋代碼的實施邏輯,以便於後期程序員可以快速捕捉到原做者在此處的實施意圖。應該說是很是適合開源項目、多個做者共同維護的一個文檔工具。好比最經典的Backbone Annotated Source就是使用Docco進行註釋的。工具
JSDuck由Sencha開發,所以對於自家extJS具備很是強大的支持功能,包括使人咋舌的實時代碼修改。但即便你不是使用extJS進行開發,JSDuck仍然是一個很是強大的工具,一方面它的語法很是靈活,描述支持Markdown語法,上手難度遠遠低於JSDoc 3;另外一方面它生成的文檔可讀性堪比YUIDoc,同時支持源碼的對照,學習起來也很是的容易。要說JSDuck有什麼很差的地方,估計就是它把一切都Handle太完美了以至於沒有給你提供什麼能夠本身定製的餘地。學習
最後我選擇了JSDuck做爲文檔生成的工具。從目的上說,我須要生成的是提供給Q&A和其餘團隊成員參考的API文檔,考慮到畢竟寫代碼纔是咱們的主要工做,註釋和文檔越簡單可以表達意思越好用,而JSDuck剛好十分符合個人需求。可是你選擇使用哪一種工具還須要根據使用場景來具體考慮,還請參考下面的細節比較測試
YUIDoc
YUIDoc提供了很是清晰的文檔格式。不只對象內部的內容很是清晰,並且相互引用的link也工做的很是好。同時YUIDoc提供了全局搜索的功能,你能夠容易根據關鍵詞找到對應的內容。
ui
JSDuck
JSDuck生成的文檔絕對不輸給YUIDoc。構造方法參數、屬性、方法都很是清晰的列在文檔之中。它的link也很是的好用,可以準確的定位到不一樣模塊中的內容。JSDuck一樣提供了全局搜索的方法,並且還在你敲下關鍵詞的同時給你相關的提示。除了這些之外,JSDuck還提供了對於依賴(dependency)、以及查看源碼(View source)的方法。
JSDoc 3
JSDoc生成的文檔使用了Bootstrap樣式。默認的樣式很是很是的糟糕,不過JSDoc 3在本身的介紹頁面裏推薦了一個第三方開發的模版系統「Docstrap」。這個模版雖然比JSDoc 3的默認模版好上不少,可是與YUIDoc和JSDuck生成的內容相比就差強人意了。其中的link的錨點也會偶爾不能正常工做。此外,它並不支持全局對於變量的搜索,你能夠在Docstrap Github的issue中找到他們相關的開發計劃。
除了Docstrap之外,它還有一些推薦的模版系統,例如Jaguar,你也能夠在這個基礎上開發本身的模版。
YUIDoc
因爲YUIDoc是Yahoo下屬YUI項目的一個部分,它並不像JSDoc 3提供了那麼多可定製的功能。可以修改的大概就只有Logo,基本的CSS樣式而已。
JSDuck
JSDuck和YUIDoc的狀況很是類似,屬於Sencha下屬的項目。樣式上可以修改的也只有Logo而已。不過JSDuck靈活的地方在於,你能夠定製文檔頂部的Tag:你能夠除了文檔之外進一步包含視頻、教程等等多種內容。
JSDoc 3
JSDoc 3屬於徹底開源的項目,所以若是你等不及社區的更新,你徹底能夠本身對JSDoc進行深度的開發。JSDoc對外提供的開發接口有3個:
更加詳細的內容則能夠在JSDoc的使用說明上找到詳細的講解。
最先這一票是投給JSDoc的,可是通過實際的測試以後發現JSDoc的語法標準很是嚴格,稍微不符合它的解析規則JSDoc便不可以正確的生成文檔,其中最讓我不能接受的事情是它對於馬上執行函數IIFE的支持實在是%……&*&*……%(裏面定義的內容大多被認爲是不暴露在全局中的,很是不方便)
下面的說明中我給出了註釋一個函數的詳細示例。
function exampleName(config, extra){ extra = !!extra; //set the default value of extra to false this.callback = config.callback; return this; }
從這個簡單的例子上幾乎不太能看出來三者實現的差異,可是當你要註釋命名空間、AMD或者CommonJS模塊的時候,三者的差異就會凸顯出來了。此外要聲明的一點是,三者的語法幾乎是不能通用的。我曾經試着將用YUIDoc註釋的文件使用JSDoc解析,結果很是悲劇,反之亦然。
YUIDoc
YUIDoc爲了支持多種語言,它僅對註釋塊內部的內容進行解析。這意味着你須要對於函數、類、命名空間等的名稱和更多的內容進行顯性的聲明。此外,就像前文提到的,它可能會形成文檔和代碼實現的不一致,甚至對於接口的使用形成很差的影響。
YUIDoc對於註釋內容要求嚴格的兩層結構:Primary Tag和Secondary Tag
詳細的YUIDoc支持的語法標籤能夠參考這裏
/** * My method description. Like other pieces of your comment blocks, * this can span multiple lines. * * @method exampleName 此處必須顯性聲明method名稱 * @param {Object} config A config object * @param {Function} config.callback A callback function on the config object * @param {Boolean} [extra=false] Do extra, optional work * @example * new exampleName(function(){console.log("Hello World")}) * @return {Object} Returns the constructed target object */
JSDuck
JSDuck在這點上剛好處在YUIDoc和JSDoc 3之間。它既對代碼的實現進行了最基本的解析,從中獲取對應的名稱、變量,有效的減小了Tag的使用。同時又不像JSDoc 3那樣嚴格,我嘗試了CommonJS、AMD和IIFE都可以很是天然的生成對應的文檔。
詳細的JSDuck支持的語法標籤能夠參考這裏
/** * My method description. Like other pieces of your comment blocks, * this can span multiple lines. * * new exampleName(function(){console.log("Hello World")}) JSDuck支持Markdown格式,插入代碼示例很是簡單 * * @param {Object} config A config object * @param {Function} config.callback A callback function on the config object * @param {Boolean} [extra=false] Do extra, optional work * * @return {Object} The constructed target object * @return {Function} return.callback the callback function of the object JSDuck能夠支持返回對象的詳細結構註釋 */
JSDoc 3
JSDoc 3很大程度上參考了Javadoc的實現。它有很是詳細的語法規則,而且你只有當和代碼實現徹底一致的時候,它才能正確的生成文檔。可是對於Javascript這樣一門靈活的語言而言,這彷佛並非最適合的方式。雖然代碼有推薦的最佳實踐,可是爲了讓文檔生成工具可以正確識別而要對本來的代碼進行修改就有點僭越本份的意味了。
/** * My method description. Like other pieces of your comment blocks, * this can span multiple lines. * * @param {Object} config A config object * @param {Function} config.callback A callback function on the config object * @param {Boolean} [extra=false] Do extra, optional work * @example * new exampleName(function(){console.log("Hello World")}) * @returns {Object} The constructed target object */
YUIDoc並不是針對Javascript量身定製,所以它有一些用法會讓你使用的時候感到比較彆扭。好比最明顯的一個例子就是,YUIDoc並無一個專門的方法用來註釋namespace,而是必須使用@class來對namespace進行註釋。 相比之下JSDoc 3和JSDuck都是針對Javascript而設計的,雖然支持的標籤略有差異,可是二者都可以很好的支持常見的設計模式。另外,JSDoc 3因爲是從JSDoc Toolkit發展而來的,悠久的歷史讓它在Stackoverflow上有不少不錯的例子能夠參考。