使用 JSDoc 3 自动生成 JavaScript API 文档

软件并不只是包括可以在计算机上运行的电脑程序,与这些电脑程序相关的文档,一般也被认为是软件的一部分。简单的说软件就是程序加文档的集合体。

随着项目的升级进化,前端产生的 JavaScript 代码越来越多越复杂;同时,也有越来越多的 JavaScript 问题出现,其中 JavaScript 文档的编写和维护成为一个亟待解决的难题。

许多现代编程语言都有自己的集成化文档生成工具,像 Java 有 JavaDoc ,.NET 有 NDoc,PHP 有 PHPDoc,这些自动化文档工具可以根据代码中的注释自动生成代码文档。本文将介绍的 JSDoc 也是这样的工具。

简介

JSDoc 3 是 JsDoc Toolkit 的升级版本,JsDoc Toolkit 是一个自动化文档工具,它是发布在 Google code 上的一个开源项目,和其他语言的文档工具一样,它可以自动从 JavaScript 代码中提取注释生成格式化文档。从 2010年7月27日 开始,JsDoc Toolkit 2 已经停止开发了,因此如果要使用 JSDoc 的话,还是推荐采用 JSDoc 3。现在 JSDoc 3 代码托管在 GitHub 上,项目地址:https://github.com/jsdoc3/jsdoc

安装

JSDoc 3 在本地安装依赖于 Nodejs,因此首先需要下载 Nodejs 进行安装:

http://nodejs.org/
http://nodejs.org/dist/v0.10.25/x64/node-v0.10.25-x64.msi

安装完后,使用以下命令安装 JSDoc 3 即可(:必须使用超级管理员身份安装):

# stable
npm install jsdoc@"<=3.3.0" -g
# dev
npm install git+https://github.com/jsdoc3/jsdoc.git -g

# test
C:\Users\moodpo>jsdoc --help
JSDoc 3.3.0-alpha3 (Wed, 25 Dec 2013 17:07:35 GMT)
......

使用

JSDoc 3 生成 API 文档完全依赖于你的代码注释,因此了解 JSDoc 3 的注释规则是最重要的。首先,注释必须要以 /** 开头,如果使用 /* 将不被识别;其次,每个注释块都应该包含唯一的主标签,和零个或多个副标签。

1. JSDoc 3 标签规范

标签 描述
@abstract/@virtual This member must be implemented (or overridden) by the inheritor.
@access Specify the access level of this member - private, public, or protected.
@alias Treat a member as if it had a different name.
@augments/@extends 标明一个函数继承另一个函数,如 A 继承 B 则可以在 A 的注释中加 `@augments B`
@author Identify the author of an item.
@borrows 参考,如 A 和 B 两个函数意义相同,则可以在 B 的注释中加 `@borrows A as B`,而不需重复添加注释
@callback/@typedef 标明此方法是一个回调函数
@classdesc 对一个类的描述
@constant/@const 常量标识
@constructor/@class 标明是构造器函数,可使用 `new` 关键字实例化
@constructs 当使用对象字面量形式定义类时,可使用此标签标明其构造函数
@copyright 描述版权信息
@default 默认值
@deprecated 弃用
@desc/@description 如果在注释开始描述可省略此标签
@enum 一个类中属性的类型相同时,使用此标签标明
@event 标明一个可触发的事件函数,一个典型的事件是由对象定义的一组属性来表示。
@example 示例,代码可自动高亮
@exports 标识此对象将会被导出到外部调用
@external/@host 标识此类、命名空间或模块来自外部
@file 描述文件功能
@fires/@emits 标明当一个方法被调用时将出发一个特殊类型的事件
@global 全局变量标识
@ignore 忽略此注释块
@inner 标明此代码是父类的内部变量
@instance 标明此代码是父类的实例
@kind 标明代码在其文档中的类型,如Class、Modual等
@license 采用的开源协议版本
@link 内联标签,创建一个链接,如 `{@link http://github.com Github}`
@member/@var 记录一个基本数据类型的成员变量
@memberof 指定一个变量所属的父类
@method/@function/@func 标记一个方法或函数
@mixes 标记一个对象混合了另一个对象的所有成员
@mixin 一个 `mixin` 提供了旨在将方法添加到对象上的功能
@module 标明当前文件模块,在这个文件中的所有成员将被默认为属于此模块,除非另外标明
@name 指定一段代码的名称,强制 JSDoc 使用此名称,而不是代码里的名称
@namespace 指定一个变量为命名空间变量
@param 标记方法参数及参数类型
@private/@protected/@public 标明变量访问等级
@property 标明一个对象的属性
@readonly 只读
@requires 标明运行代码所需模块
@returns/@return 标明返回值、类型及描述
@see 链接到一个参考位置
@since 描述此功能来自哪一版本
@static 描述一个不需实例即可使用的变量
@summary 对描述信息的短的概述
@this 说明 `this` 关键字所代表的意义
@throws 描述方法将会出现的错误和异常
@todo 描述函数的功能或任务
@tutorial 插入一个指向向导教程的链接
@type 描述代码变量的类型
@version 版本信息

更多内容请查看官方文档

2. 使用 conf.json 文件

安装完 JSDoc 3 后默认使用的配置文件为 conf.json.EXAMPLE,内容如下:

{
    "tags": {
        "allowUnknownTags": true
    },
    "source": {
        "includePattern": ".+\\.js(doc)?$",
        "excludePattern": "(^|\\/|\\\\)_"
    },
    "plugins": [],
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    }
}

我们可以定义自己的 conf.json 文件,使用此文件可以指定 JSDoc 输出目录、命令行操作参数、使用的插件、输出模版以及读取的文件等,以下是完整的文件内容:

// 使用时请删除所有注释
{
    "tags": {
        "allowUnknownTags": true //允许输出位置标签
    },
    "source": { // 指定读取的源文件
        "include": [], // 包含文件列表
        "exclude": [], // 不包含文件列表
        "includePattern": ".+\\.js(doc)?$", // 正则方式
        "excludePattern": "(^|\\/|\\\\)_"
    },
    "plugins": [], // 启用插件列表,可在 JSDoc 目录下找到所有的插件
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    },
    "opts": { // 命令行操作参数配置,详细内容请查看 http://usejsdoc.org/about-commandline.html
        "template": "templates/default",  // same as -t templates/default
        "encoding": "utf8",               // same as -e utf8
        "destination": "./out/",          // same as -d ./out/
        "recurse": true,                  // same as -r
        "tutorials": "path/to/tutorials", // same as -u path/to/tutorials, default "" (no tutorials)
        "query": "value",                 // same as -q value, default "" (no query)
        "private": true,                  // same as -p
        "lenient": true,                  // same as -l
        // these can also be included, though you probably wouldn't bother
        // putting these in conf.json rather than the command line as they cause
        // JSDoc not to produce documentation. 
        "version": true,                  // same as --version or -v
        "explain": true,                  // same as -X
        "test": true,                     // same as -T
        "help": true,                     // same as --help or -h
        "verbose": true,                  // same as --verbose, only relevant to tests.
        "match": "value",                 // same as --match value, only relevant to tests.
        "nocolor": true                   // same as --nocolor, only relevant to tests
    }
}

就让这时光奔腾如流水

二零一三年已渐渐远去,在不知不觉中一四年的第一个月也快要逝去了。坦然者谓之:就让这时光奔腾如流水……而对于我来说,一三年却是一个不折不扣的曲折离奇,悲喜交加的一年,很多积压的事情在这一年爆发,很多逃避的事情在这一年不得不去面对了。

小年的时候我曾经发布过我的《2013年年终总结》,但是后来我把它删掉了,我觉得用工作、生活和展望,如一二年年终总结那样的形式已经无法描述我的二零一三了。我只想凭我对一三年的记忆去写,仅当是对过去那些日子的纪念吧。

大事记

  • 一月相识两年多后和豆豆完婚
  • 四月辞职并加入神州泰岳
  • 六月我的女儿盈珊出生
  • 九月善意的谎言破灭,隐瞒的事情人尽皆知
  • 十月搬家到帝都的一个小村公寓里,从此“过上”了朝九晚五的生活
  • 十月在广州出差,浴血奋战终奇迹完成任务
  • 十二月喜获公司企业文化奖之勇士奖

琐碎

  • 博客迁移到 Hostigation 的洛杉矶主机
  • 毕业三年后会母校拿毕业证 ^_^
  • 注册 GitHub 并开源了自己的第一个项目
  • 读完 《Struts 2 in Action》
  • 基于百姓网前端模版格式归纳总结出 IAM 3.0 产品的前端模版
  • 加入泰岳后开始专攻前端,并开始逐步积累自己的 CSS、JavaScript 知识
  • 读完 《JavaScript 语言精粹》
  • 发布两款 Typecho 皮肤:Moodpo、RedSexy
  • 博客经历了从 Typecho 0.8 -> Liquidluck -> Hexo -> Typecho 0.9 后趋于稳定
  • ......

感想

一三年经历了许许多多,最令我深刻的还是自翔的“超脱”,其实还不够超脱。这也难怪,有且只有我的家人或者说我爱的人能令我失控吧;最令我懊恼的是我一直以来懊恼的,没有“毅力”,不懂得坚持,这没什么好说的了,我不想再这样懊恼下去了;最令我苦闷的,当然还是豆豆和我妈两个人的结,似乎已变成一个死结,再也解不开一样,但我仍相信“世上没有解不开的结”这句话;最令我高兴的,哈,那当然是我的宝贝女儿盈珊的出生了,出生过程顺利,但后来有黄疸肺炎什么的,不过总算过来了,纳,以后当然一定快乐的成长吧!最令我难忘的要数广州之行,那一个个日夜将在我记忆里长存......

2014

人生不过两万天,过去一年我又离那个三更近了许多。想想现在,想想自己,再想想未来,些许后怕。是时候去做自己喜欢的事情了,是时候为自己做一些事情了。

人生短暂不只因时间短暂,而是因人事纷繁!

随便记录下吧先:

  • 坚持每周两篇博文
  • 完成 d.moodpo.com
  • 继续学习 JavaScript,读完《JavaScript 权威指南》等书
  • 回归霸气...
  • 工作继续...

2014-02-08 12 59 22.png

一个快速、简洁和强大的新博客框架

新的博客已经使用了很长时间,回头一想,竟然未记录下任何东西,以至于当间隔两个月回来写篇文章要提交时出现了波折,甚至生成命令也忘的差不多了。果然是好记性不如烂笔头!

基于静态文件的博客引擎已经有很多了,譬如一开始我使用的 Liquidluck 。Liquidluck 提供了静态博客生成,提交 Github ,而且还提供了 Webhook 方式的接口,使生成的静态文件自动同步到 Github上。然而其最大的缺点是,未支持 Windows 系统。以前我只能 SSH 到 VPS 上进行各种操作,直接将静态文件生成到 Nginx 下,而与 Github 的同步功能则显得多余。

这一切直到遇到了 Hexo 框架才改变,而她却是一个台湾大学生使用 Node.js 编写的,心中不免产生无限敬意。

Hexo 框架使用 Github 的 page 服务,但是却并不像 Octopress 那样复杂,既需要懂得一些 Ruby 的知识,又需要一些繁琐的配置。使用 Hexo 框架你只需知道 Github 的 Page 服务,以及几个命令即可。下面就是本博客的创建过程,仅当自己以后方便,更详细的内容还是去查看官方文档吧。

1. 安装前的必备工作

Hexo 使用 node.js ,所以 安装 node.js 是必须的,此外还要有 Git 工具。

1.1 安装 Git

  • Linux (Ubuntu, Debian): sudo apt-get install git-core
  • Linux (Fedora, Red Hat, CentOS): sudo yum install git-core

1.2 安装 Node.js

$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh

或者

$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh

最后安装 Node.js

$ nvm install 0.10

2. 安装 Hexo

$ npm install -g hexo

3. 配置 Hexo

使用以下命令生成静态博客所使用的所有文件:

$ hexo init <folder>

目录结构说明:

.
├── _config.yml // 全局配置文件
├── package.json  // 
├── scaffolds // 生成文件时的头格式
├── scripts
├── source 
|   ├── _drafts
|   └── _posts // Makedown文章
└── themes 

全局配置文件中提供了多种参数配置,包括站点信息,作者,个性化静态地址,标签,分类,高亮,甚至 Disqus 的评论,谷歌统计等。

4. 开始写文章

$ hexo new [layout] <title>
// [layout] 是指 scaffolds 中定义的格式
// <title> 是指文件名称

$ hexo generate
// 生成静态文件

$ hexo deploy
// 将静态文件上传到 Github 中

广州之行

广州小蛮腰

从广州回来已经快一个月了,我才想起要总结一下的。

是的,很需要总结一下。不必说我们团队一起度过的无眠的夜晚,也不比说广州的现场环境的千奇百怪的复杂,单单只说上线晚上我紧急发布的补丁个数,就与别的省份的情况不可同日而语了。当然,我只去过广州,别的省份没有切身的体会,但从各种道听途说的消息来判断,也可见一斑。

十月八号到达广州,而月底是我们的上线时间,一开始我们不说信心满满,至少心里有底,因为我们在公司这边已经进行了三轮测试,虽然还存在Bug,但都不是什么严重问题。然而,事情并不是我想象的那样简单。首先的就是数据迁移这座大山挡在了我们面前——广东的数据在所有省份中是最多的,也是最为复杂的。经过千辛万苦,ESA的数据迁移过来了,然而LDAP的数据却成了难题,尤其是authorizations那个节点下的授权关系数据,UDI迁移工具跑了一个晚上,到第二天一不小心由于网络断开,一晚上的时间就白搭上了。就这样一次次的虐心,一次次失败。测试部的人因为没有测试环境只能在那尴尬的闲着,而我们开发的同样如此,那段时间真是让人“难忘”。于是第一周,我们的进度几乎为零。然而万幸的是最后终于在LDAP上添加了vlv索引,并修改UDI同步工具,总算把第一个测试环境的数据整了出来。

本以为测试的数据整出来我们可以轻松一把,没想到他们的WAS打包的那么不靠谱。测试的人测完了第一轮,晚上,我检查测试环境的更新情况时却发现之前给的补丁包并没有打上去。于是,第一轮的测试以“白测”而告终。不得已,我直接接手了他们的测试环境,什么事情还是自己来才放心。这得多亏了我以前对于WAS以及Linux的学习和了解,这下终于派上了用场,在输入命令轻敲回车的瞬间,心中充满了惬意。渐渐的,测试环境终于在我手中变的非常顺滑,各种问题可以很快定位原因并解决。

第二轮测试的时候,时间已飞快的来到了月底。测试紧张的进行,Bug数很多,但是测出的Bug质量却不高,很多重复的,很多边缘但并不严重的。看着那些Bug单,然后回想主线代码的杂乱无章,各种功能代码的交叉提交,心中无限忐忑。前路总是艰难,迷茫,既然走在了这条路上,我们唯有勇往直前,脚踏实地的走下去。改Bug,上传代码,打补丁包,更新,测试,回归,一步一个脚印。有句话叫你为什么要爬那座山,因为山在那里!而我那时最想说的是,为什么要熬夜去改Bug,因为问题在那里!

上线前几天,经过几次的上线演练,我们信心倍增,特别是我,对于UDI工具的使用,Radis的配置,已经达到了得心应手的程度。而亚坤他们的升级脚本,ESA数据以及刷数据工具,都已成熟起来,没有什么问题了。把几次演练的过程,汇聚起来,我写了份升级手册,在十一月四号晚上终于迎来了上线的时间。晚上九点,我们开始了升级。执行数据库脚本,同步ESA数据,运行UDI迁移工具,执行刷数据脚本...这些如期的顺利执行完后,开始测试。当晚即测出多个问题,有的甚至非常严重几乎要导致回退的地步,比如casp导致的单点登录失败,iam因工单窗口无反应而无法进行操作授权等,上线当晚即提交了7个补丁,不得不感叹计划不如变化快。在不知不觉中,天亮了,当最后看到领导发出的邮件了,那个不算很大的红色的上线成功四个字时,即使熬夜心中悠然