JSDoc是一個根據(jù)js文件中的注釋信息自動生成相關(guān)文檔的工具。生成的文檔都是html文件,你可以將其放到web server上,其內(nèi)建了各個API條目之間的跳轉(zhuǎn),非常方便。和JavaDoc和PhpDoc類似。
詳細(xì)的用法可以去jsdoc的官網(wǎng)查閱相關(guān)文檔,官網(wǎng)的文檔做的也比較詳細(xì),并配有相關(guān)示例,應(yīng)該能夠比較容易的上手。
寫這篇文章的目的是這樣的。我讀過不少前端大神在github上的源碼,竊以為TJ大神的代碼質(zhì)量最高。那么他的代碼究竟質(zhì)量高在哪里呢?這里我就說兩點(diǎn),第一是條理清晰,第二是注釋完備。個人覺得,想去看源碼的應(yīng)該都不會是新手,如果代碼具備了條理清晰和注釋完備這兩點(diǎn),那么基本上源碼閱讀應(yīng)該不是一個痛苦的事情。
當(dāng)然,TJ大神的代碼質(zhì)量高可能不止是我說的這兩點(diǎn),比如他寫的東西一般都會有完備的單元測試,等等。
所以,一個想致力提升自身水平的前端人員,都應(yīng)該盡力讓自己產(chǎn)出的代碼走高質(zhì)路線,特別是在團(tuán)隊合作中。拋開其他不談,代碼的注釋其實(shí)是非常powerful的一點(diǎn)。
下面先來一段commander.js中的代碼段,來看下具有完備注釋的js代碼究竟有怎樣的魅力,
/**
* Add command `name`.
*
* The `.action()` callback is invoked when the
* command `name` is specified via __ARGV__,
* and the remaining arguments are applied to the
* function for access.
*
* When the `name` is "*" an un-matched command
* will be passed as the first arg, followed by
* the rest of __ARGV__ remaining.
*
* Examples:
*
* program
* .version('0.0.1')
* .option('-C, --chdir <path>', 'change the working directory')
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
* .option('-T, --no-tests', 'ignore test hook')
*
* program
* .command('setup')
* .description('run remote setup commands')
* .action(function() {
* console.log('setup');
* });
*
* program
* .command('exec <cmd>')
* .description('run the given remote command')
* .action(function(cmd) {
* console.log('exec "%s"', cmd);
* });
*
* program
* .command('teardown <dir> [otherDirs...]')
* .description('run teardown commands')
* .action(function(dir, otherDirs) {
* console.log('dir "%s"', dir);
* if (otherDirs) {
* otherDirs.forEach(function (oDir) {
* console.log('dir "%s"', oDir);
* });
* }
* });
*
* program
* .command('*')
* .description('deploy the given env')
* .action(function(env) {
* console.log('deploying "%s"', env);
* });
*
* program.parse(process.argv);
*
* @param {String} name
* @param {String} [desc] for git-style sub-commands
* @return {Command} the new command
* @api public
*/
Command.prototype.command = function(name, desc) {
var args = name.split(/ +/);
var cmd = new Command(args.shift());
if (desc) {
cmd.description(desc);
this.executables = true;
this._execs[cmd._name] = true;
}
this.commands.push(cmd);
cmd.parseExpectedArgs(args);
cmd.parent = this;
if (desc) return this;
return cmd;
};
看到了沒有,代碼就20來行,但是代碼前的注釋非常詳盡,包括基本描述、使用示例、參數(shù)說明等等。
當(dāng)然,我們在實(shí)際寫代碼時并沒有必要對每一塊的代碼的注釋都寫得如此詳盡。具體如何取舍,那就得看情況了。
除此之外,個人覺得完備的代碼注釋在多人團(tuán)隊合作中還有另外一個好處。在團(tuán)隊開發(fā)中,自己需要去看別人的代碼實(shí)現(xiàn)是一件比較經(jīng)常的事情,但是很多時候你去看別人的代碼的目的其實(shí)僅僅是為了知道如何使用別人寫的代碼,別人代碼的具體實(shí)現(xiàn)細(xì)節(jié)你可能是不太關(guān)心的。那么此時如果有這樣的完備注釋,那么基本上你僅僅需要看下注釋就行了,不太需要去研究別人的實(shí)現(xiàn)細(xì)節(jié)了(除非你看別人的代碼是review code),大大減少了生產(chǎn)者和消費(fèi)者之間的溝通成本。
個人覺得(最起碼我自己打算這么做),我們使用jsdoc可能有時候并不是要真正的生成一些html文檔頁面(當(dāng)然這個也是可以做的),而是在自己以后或者其他人閱讀代碼時提供幫助。
/** 你的注釋 */
如上面的代碼段,jsdoc會從js文件中以/**
開頭的注釋文本抽取需要的信息。所以/*
、/***
等等之類開頭的注釋jsdoc都是不承認(rèn)的。
jsdoc中,以@
開頭的部分字段(關(guān)鍵字)都有特定含義,比如下面這段代碼,
/**
* @param {string} somebody - Somebody's name
*/
function sayHello(somebody) {
alert('Hello ' + somebody);
}
@param
,用于申明參數(shù),參數(shù)名為somebody
{string}
,表示參數(shù)的類型- xxxxxx
,對應(yīng)參數(shù)的描述好了,基本上jsdoc中所有的@xxx
標(biāo)簽都遵循這一標(biāo)準(zhǔn)格式。下面描述一些常用的標(biāo)簽
方法參數(shù)的相關(guān)聲明。Usage,
@param {類型} 參數(shù)名 - 參數(shù)描述
[參數(shù)名]
標(biāo)識,則表示此參數(shù)為可選參數(shù)名=默認(rèn)值
,表示參數(shù)的默認(rèn)值{類型1|類型2}
,表示此參數(shù)可接受多個數(shù)據(jù)類型方法返回值的相關(guān)聲明。Usage,
@returns {類型} 返回值描述
額外信息的描述標(biāo)簽。Usage,
@author
,作者描述@todo
,待做事項描述@file
,文件描述,@deprecated
,不推薦使用(廢棄)標(biāo)識@description(@desc)
,描述標(biāo)識
其他更多標(biāo)簽的說明請參閱官方文檔。
jsdoc還可以用在前端工程構(gòu)建系統(tǒng)中,這樣可以在項目release時一并生成代碼的API文檔。
在目前有兩種比較常用的構(gòu)建系統(tǒng)中都有相應(yīng)的插件(gulp-jsdoc、grunt-doc)進(jìn)行支持。兩者的使用都非常簡單,
gulp中,
var jsdoc = require('gulp-jsdoc');
gulp.src('./src/*.js')
.pipe(jsdoc('./doc'));
grunt中,
grunt.initConfig({
jsdoc : {
dist : {
src: ['src/*.js'],
options: {
destination: 'doc'
}
}
}
});
最后貼一個上周寫的小玩兒意,很簡單的一個js文件,主要是觀摩一下使用jsdoc給js代碼添加注釋的那種美感。
更多建議: