JSDOC的使用

用过 Java 的都很熟悉 Javadoc, 只要在代码的方法上面写上相应的代码说明注解,那么使用一个 javadoc 命令就可以生成一个 API 说明文档。

JavaScript 本身并没有这样的功能,不过也有这样的工具:JSDOC。

基本用法

  1. 安装
1
2
# 全局安装即可
npm install -g jsdoc
  1. 使用
1
2
3
4
5
# 生成文件 `input.js` 的说明文档,并存放在 `docs` 目录
jsdoc input.js -d docs

# 使用配置文件config生成说明文档
jsdoc -c config.js

使用配置

一般来说,最好是使用配置文件去生成,这样,免得总是敲一长串命令。jsdoc支持 json和js文件作为配置示例:

JSON格式样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"tags": {
"allowUnknownTags": true
},
"source": {
"include": [ ],
"exclude": [ ],
"includePattern": ".+\\.js(doc|x)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"plugins": [],
"recurseDepth": 10,
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"default": {
"outputSourceFiles": true
}
}
}

JavaScript格式样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'use strict';
module.exports = {
"tags": {
"allowUnknownTags": true
},
"source": {
"include": [ /* array of paths to files to generate documentation for */ ],
"exclude": [ /* array of paths to exclude */ ],
"includePattern": ".+\\.js(doc|x)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"plugins": [],
"recurseDepth": 10,
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"default": {
"outputSourceFiles": true
}
}
}

个人更喜欢用js,因为json里面不能写注释。写好配置文件后,运行:

1
2
# 这里加个-r 参数,代表遍历文件夹下的子文件夹,配置文件里面 "recurseDepth": 10 代表最多递归10层目录
jsdoc -c config.js -r -d docs

常用配置项说明

类型 示例 说明
plugins Array[String] ["plugins/markdown"] 使用插件,附:支持插件
recurseDepth int 10 文件夹递归深度,只有在命令行加入了 -r 才有用,默认为10
source Object 参考上面的DEMO 通过source可以灵活配置需要生成的文件
type String 支持”module”、”script” module(默认):输入为文件,script:输入为脚本,通常不怎么使用
opts Ojbect {“template”:”templates/default”} 命令行的配置形态,在这里配置一下可以不用在命令行输入了
opts.template string “templates/default” 相当于 -t templates/default
opts.encoding string “utf-8” 相当于 -e utf8
opts.destination string “docs” 相当于 as -d docs
opts.recurse boolean true 相当于 -r
tags Object {“allowUnknownTags”: true} Tag配置
templates Object 参考上面的DEMO 模板配置

Tag说明

Tag 分为两类块Tag行Tag块Tag即是以 @开头的,行Tag是使用大括号{}包起来的, 比如 @param 就是块Tag,{@link}就是行Tag。一般情况下我们使用的都是块Tag

行Tag可以在块Tag中使用,如果行Tag里面的内容不是以@开头,一般可以认为该Tag是一个数据类型比如 {string},{object},{CustomType}等。比如以下代码即定义了一种类型,并可以链接去查看,比如以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @public
* @class
* @classdesc Person的定义
*/
class Person{
/**
* Person 构造器
* @constructs
* @param {string} name
* @param {number} age
*/
constructor(name,age) {
this.name = name;
this.age = age;
}
/**
* 获取姓名
* @return {string} 姓名
*/
getName(){
return this.name;
}
/**
* 返回本人的实体 {@link Person}
* @return {Person}
*/
getSelf(){
return this;
}
}

生成出来后结果如下,可以看到我返回的类型已经是链接的形式,可以点进去查看

JSODC

JSDOC支持60多个Tag,有兴趣的可以去官方网站 看看,我这里把我自己用到常用不常用的Tag整理一下,并按个人的理解排了下,这些Tag一般根据名字都可以看出具体功能,所以不做说明,如果玩过Java的注解之类的基本可以一看就懂。

功能 Tag
修饰 @public @private @property @readonly @static @default @global @abstract
结构1 @param @return @class @constructs @enum @instance @package @function @constant
结构2 @typedef @memberof @module @export @namespace
结构3 @requires @override @implements @external
文档 @version @author @since @see @deprecated @copyright @description @ignore @license @summary

自定义皮肤

说明:官方提供的templates配置只能简单的配置底部是否显示时间,或是导航栏里面显示长名称的配置,虽然提供了templates.default.layoutFile配置项可以让我们自己写个模板文件去替换掉官方的layout.tmpl,但实际上我们一般不会自己去开发一套皮肤。

通常jsdoc可以和gulp,grunt等一起去用,在gulp的插件里面有丰富的jsdoc模板,配置也很简单,除了默认的模板外,官方提供了不少皮肤,可以去参考.

CommonJS模块化

目前官方有ES2015, CommonJS, AMD三种模块化方案的DEMO,都是 使用 @module 对脚本进行模块化,细节略有不同,由于本人使用的是CommonJS,这方面碰到几个坑(也不能算坑,就是不知道如何让文档和代码一样结构和条理保持清晰。这里个人提供一些方案,不分排名,各有用途,仅供参考。

1. 使用全局的命名空间 @namespace

使用一个入口文件定义一些全局的命名空间 @namespace,模块化的目录里面也可以在入口文件里面定义,其它文件都通过@memberof指定成为命名空间的成员

DEMO:在输入范围内建一个xxx.jsdoc文件,编辑

这里在这个文件里面定义了两个@namespace

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
@namespace util
@description ### Utils公用工具,页面上的公用方法,验证等。
1. {@link util.ValidateUtil ValidateUtil} : 验证Util
2. {@link util.CommonUtil CommonUtil} : 公用Util
*/

/**
@namespace comments
@description ### 开发中常用的组件
1. xxx
2. xxx
*/
  1. 在对应的文件里面将对应的对象标记为namespace的成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// ValidateUtil.js
/**
* @name ValidateUtil
* @memberof util
* @description 验证UTIL
*/


// CommonUtil.js
/**
* @name CommonUtil
* @memberof util
* @description 公用UTIL
*/


// xxxxxxx.js
/**
* @name xxxxxxx
* @memberof comments
* @description xxxxxxx组件
*/

2. 使用一个@module,@export 模块化

这两个关键字看上去不一样,但实际上是一样的效果,都是模块化,为什么有两个,主要是我们的代码常常有以下两种:

代码一:都写好了,导出时指定KV,这一种我们使用@module,定义了module后再定义成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @module Ajax
* @description ### 说明:XXX
*/

/**
* @function
* /
var a = function(){

}
/**
* @member
* /
var b = 1;
module.exports = {
a:a,
b:b
};

说明,以上代码并非一定要使用@module,使用@export也可以同样完成,只不过需要把注释写在module.export={...}里面,感觉很不爽。

代码二:直接导出对象,这只使用@export

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @exports X
*/
class X{
/**
* @function
* /
a(){

}
/**
* @function
* /
b(){

}
}
module.exports = new X();

虽然不怎么合理,但通常个人喜欢把一大块的module定义成一个namespace,而静态工具定义成module,生成出来的页面虽然有些对不上,但感觉排的很清晰,当然这和项目代码也有一定关系。

其它

如果使用工具前,代码里面存在 /****/ 这样的注释,会当作文档进行处理,可以选择优化,或使用 // 注释替代。

一般情况下,jsodc都会自动识别代码里面的类型,但是导出一个方法时,我们可以手动定义类型,以及方法的名称,比如

1
2
3
4
5
6
7
/**
* @function methodName
* @memberof namespace
* @description 这是namespace的method
*/
module.exports = function(){
}

JSDOC是一个很容易入门的工具,使用起来也很简单,但如果项目代码较多,结构复杂,生成出漂亮的文档就比较麻烦了,合理使用@namespace@module, @typedef, @memberof 等结构体。

另外也可以通过控制项目的结构,只选择一些核心的文档去生成。

最后,sublime里面的jsodc插件可以在写代码的时候自动插入jsdoc模板,但个人是不推荐去装的,一般情况下没太大必要。