最近随着写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上有不少不错的例子能够参考。