第29章 JSDoc: APIドキュメントの生成
目次
書籍を購入する
(広告です。ブロックしないでください。)

第29章 JSDoc: APIドキュメントの生成

これは一般的な開発上の問題です。他の人が使用するJavaScriptコードを記述し、そのAPIの見た目も美しいHTMLドキュメントが必要になります。JavaScriptの世界でAPIドキュメントを生成するためのデファクトスタンダードツールはJSDocです。[23] これはJavaの類似ツールであるJavaDocをモデルにしています。

JSDocは/** */コメント(アスタリスクで始まる通常のブロックコメント)を含むJavaScriptコードを受け取り、HTMLドキュメントを生成します。たとえば、次のコードが与えられた場合:

/** @namespace */
var util = {
    /**
     * Repeat <tt>str</tt> several times.
     * @param {string} str The string to repeat.
     * @param {number} [times=1] How many times to repeat the string.
     * @returns {string}
     */
    repeat: function(str, times) {
        if (times === undefined || times < 1) {
            times = 1;
        }
        return new Array(times+1).join(str);
    }
};

生成されたHTMLは、Webブラウザで図29-1のように表示されます。

JSDocウェブサイトのReadmeには、このツールのインストール方法と呼び出し方法が説明されています。

JSDocの基本

JSDocは、エンティティ(関数、メソッド、コンストラクタなど)のドキュメント化を目的としています。これは、エンティティの前に記述され、/**で始まるコメントによって実現されます。

構文

冒頭に示したコメントを確認してみましょう。

/**
 * Repeat <tt>str</tt> several times.
 * @param {string} str The string to repeat.
 * @param {number} [times=1] How many times to repeat the string.
 * @returns {string}
 */

これは、JSDoc構文の一部を示しています。JSDoc構文は、次の要素で構成されています。

JSDocコメント
これは、最初の文字がアスタリスクであるJavaScriptブロックコメントです。これにより、/**トークンがそのようなコメントを開始するという錯覚が生まれます。
タグ
行頭にタグ(@記号が付いたキーワード)を付けることで、コメントを構造化します。@paramは、上記のコードの例です。
HTML
JSDocコメントでは、HTMLを自由に使用できます。たとえば、<tt>は単語を等幅フォントで表示します。
型注釈

波括弧で囲んだ型名を使用して、エンティティの型をドキュメント化できます。バリエーションには以下が含まれます。

  • 単一の型: @param {string} name
  • 複数の型: @param {string|number} idCode
  • 型の配列: @param {string[]} names
名前パス

JSDocコメント内では、いわゆる名前パスを使用してエンティティを参照します。このようなパスの構文は次のとおりです。

myFunction
MyClass
MyClass.staticMember
MyClass#instanceMember

クラスは通常、(によって実装される)コンストラクタです。静的メンバーは、たとえばコンストラクタのプロパティです。JSDocでは、インスタンスメンバーを広く定義しています。これは、インスタンスを介してアクセスできるすべてのものを意味します。したがって、インスタンスメンバーには、インスタンスプロパティとプロトタイププロパティが含まれます。

基本タグ

以下は、基本的なメタデータタグです。

@fileOverview 説明

ファイル全体を説明するJSDocコメントをマークします。例えば

/**
 * @fileOverview Various tool functions.
 * @author <a href="mailto:jd@example.com">John Doe</a>
 * @version 3.1.2
 */
@author
ドキュメント化されているエンティティの作成者を参照します。
@deprecated
エンティティがもはやサポートされていないことを示します。代わりに何を使用するかを文書化することをお勧めします。
@example

指定されたエンティティの使用方法を示すコード例が含まれています。

/**
 * @example
 * var str = 'abc';
 * console.log(repeat(str, 3)); // abcabcabc
 */

リンクの基本タグは次のとおりです。

@see

関連リソースを指します。

/**
 * @see MyConstructor#myMethod
 * @see The <a href="http://example.com">Example Project</a>.
 */
{@link ...}
@seeと同様に機能しますが、他のタグ内で使用できます。
@requires リソースの説明
ドキュメント化されたエンティティが必要とするリソースを示します。リソースの説明は、名前パスまたは自然言語による説明のいずれかです。

バージョン管理タグには、以下が含まれます。

@version バージョン番号

ドキュメント化されたエンティティのバージョンを示します。例えば

@version 10.3.1
@since バージョン番号

ドキュメント化されたエンティティが利用可能になったバージョンを示します。例えば

@since 10.2.0

関数とメソッドのドキュメント化

関数とメソッドの場合、パラメータ、戻り値、およびスローされる可能性のある例外をドキュメント化できます。

@param {paramType} paramName 説明

名前がparamNameであるパラメータについて説明します。型と説明はオプションです。次に例を示します。

@param str The string to repeat.
@param {string} str
@param {string} str The string to repeat.

高度な機能

  • オプションパラメータ

    @param {number} [times] The number of times is optional.
  • デフォルト値を持つオプションパラメータ

    @param {number} [times=1] The number of times is optional.
@returns {returnType} 説明
関数またはメソッドの戻り値について説明します。型または説明のいずれかを省略できます。
@throws {exceptionType} 説明
関数またはメソッドの実行中にスローされる可能性のある例外について説明します。型または説明のいずれかを省略できます。

インライン型情報(「インラインドキュメントコメント」)

パラメータと戻り値の型情報を提供するには、2つの方法があります。1つ目は、@param@returnsに型注釈を追加する方法です。

/**
 * @param {String} name
 * @returns {Object}
 */
function getPerson(name) {
}

2つ目は、型情報をインライン化する方法です。

function getPerson(/**String*/ name) /**Object*/ {
}

変数、パラメータ、およびインスタンスプロパティのドキュメント化

次のタグは、変数、パラメータ、およびインスタンスプロパティのドキュメント化に使用されます。

@type {typeName}

ドキュメント化された変数はどのような型ですか?例えば:

/** @type {number} */
var carCounter = 0;

このタグは、関数の戻り値の型をドキュメント化するためにも使用できますが、この場合は@returnsの方が適しています。

@constant

ドキュメント化された変数の値が定数であることを示すフラグ。

/** @constant */
var FORD = 'Ford';
@property {propType} propKey 説明

コンストラクタコメントでインスタンスプロパティをドキュメント化します。例えば:

/**
 * @constructor
 * @property {string} name The name of the person.
 */
function Person(name) {
    this.name = name;
}

あるいは、インスタンスプロパティは次のようにドキュメント化できます。

/**
 * @class
 */
function Person(name) {
    /**
     * The name of the person.
     * @type {string}
     */
    this.name = name;
}

どちらのスタイルを使用するかは、個人の好みによります。

@default デフォルト値

パラメータまたはインスタンスプロパティのデフォルト値は何ですか?例えば:

/** @constructor */
function Page(title) {
    /**
     * @default 'Untitled'
     */
     this.title = title || 'Untitled';
}

クラスのドキュメント化

JSDocは、クラスとコンストラクタを区別します。前者の概念はどちらかというと型のようなもので、コンストラクタはクラスを実装する1つの方法です。JavaScriptのクラス定義の組み込み手段は限られているため、このタスクを支援する多くのAPIが存在します。これらのAPIは、多くの場合根本的に異なるため、JSDocが何が起こっているかを理解するのを助ける必要があります。次のタグを使用すると、それができます。

@constructor
関数をコンストラクタとしてマークします。
@class
変数または関数をクラスとしてマークします。後者の場合、@class@constructorの同義語です。
@constructs
メソッドがインスタンスデータを設定することを記録します。そのようなメソッドが存在する場合、クラスはそこでドキュメント化されます。
@lends 名前パス

次のオブジェクトリテラルがどのクラスに寄与するかを指定します。寄与するには2つの方法があります。

  • @lends Person#: オブジェクトリテラルはインスタンスメンバーをPersonに寄与します。
  • @lends Person: オブジェクトリテラルは静的メンバーをPersonに寄与します。
@memberof 親名前パス
ドキュメント化されたエンティティは、指定されたオブジェクトのメンバーです。オブジェクトリテラルに適用される@lends MyClass#は、そのリテラルの各プロパティに@memberof MyClass#をマークするのと同じ効果があります。

クラスを定義する最も一般的な方法は、コンストラクタ関数、オブジェクトリテラル、および@constructsメソッドを持つオブジェクトリテラルを使用することです。

コンストラクタ関数によるクラスの定義

コンストラクタ関数を使用してクラスを定義するには、コンストラクタ関数をマークする必要があります。そうしないと、クラスとしてドキュメント化されません。大文字化だけでは、関数がコンストラクタとしてマークされません。

/**
 * A class for managing persons.
 * @constructor
 */
function Person(name) {
}

@constructsメソッドを持つオブジェクトリテラルによるクラスの定義

オブジェクトリテラルに@constructsメソッドがある場合、JSDocにそのことを知らせる必要があります。そうすることで、インスタンスプロパティのドキュメントを見つけることができます。クラスのドキュメントはそのメソッドに移動します。

var Person = makeClass(
    /** @lends Person# */
    {
        /**
         * A class for managing persons.
         * @constructs
         */
        initialize: function(name) {
            this.name = name;
        },
        say: function(message) {
            return this.name + ' says: ' + message;
        }
    }
);

@lendsを省略した場合、メソッドが属するクラスを指定する必要があります。

var Person = makeClass({
        /**
         * A class for managing persons.
         * @constructs Person
         */
        initialize: function(name) {
            this.name = name;
        },
        /** @memberof Person# */
        say: function(message) {
            return this.name + ' says: ' + message;
        }
    }
);

サブクラス化

JavaScriptには、サブクラス化の組み込みサポートがありません。コードでサブクラス化する場合(手動で行うか、ライブラリを介して行うかにかかわらず)、JSDocに何が起こっているかを伝える必要があります。

@extends 名前パス

ドキュメント化されたクラスが別のクラスのサブクラスであることを示します。例えば

/**
 * @constructor
 * @extends Person
 */
function Programmer(name) {
    Person.call(this, name);
    ...
}
// Remaining code for subclassing omitted

その他の便利なタグ

これらのタグはすべて、JSDocウェブサイトに記載されています。

  • モジュール性: @module@exports@namespace
  • カスタム型(コールバックなどの仮想エンティティ、シグネチャをドキュメント化できます): @typedef@callback
  • 法的事項: @copyright@license
  • 様々な種類のオブジェクト: @mixin@enum


[23] この章の主な情報源はJSDocのウェブサイトです。一部の例はそこから借用しています。

次: 30. ライブラリ