JSDocプラグインについて
プラグインの作成と有効化
新しいJSDocプラグインを作成して有効にするには、2つのステップが必要です。
- プラグインコードを含むJavaScriptモジュールを作成します。
- JSDocの設定ファイルの
plugins
配列にそのモジュールを含めます。絶対パスまたは相対パスを指定できます。相対パスを使用する場合、JSDocは、現在の作業ディレクトリ、設定ファイルが置かれているディレクトリ、JSDocディレクトリの順にプラグインを検索します。
たとえば、現在の作業ディレクトリのplugins/shout.js
ファイルにプラグインが定義されている場合、JSDoc設定ファイルのplugins
配列に文字列plugins/shout
を追加します。
{
"plugins": ["plugins/shout"]
}
JSDocは、設定ファイルにリストされている順にプラグインを実行します。
JSDoc 3プラグインの作成
JSDoc 3のプラグインシステムは、解析プロセスを広範囲に制御できます。プラグインは、次のいずれかを実行することにより、解析結果に影響を与える可能性があります。
- イベントハンドラの定義
- タグの定義
- 抽象構文木ノードのビジターの定義
イベントハンドラ
最高レベルでは、プラグインはJSDocが発火する特定の名前付きイベントのハンドラを登録できます。JSDocは、イベントオブジェクトをハンドラに渡します。プラグインモジュールは、次のようにハンドラを含むhandlers
オブジェクトをエクスポートする必要があります。
exports.handlers = {
newDoclet: function(e) {
// Do something when we see a new doclet
}
};
JSDocは、基盤となるコードと同じ順序でイベントを発火します。
イベントハンドラプラグインは、イベントオブジェクトにstopPropagation
プロパティ(e.stopPropagation = true
)を設定することにより、後続のプラグインの実行を停止できます。プラグインは、preventDefault
プロパティ(e.preventDefault = true
)を設定することにより、イベントの発火を停止できます。
イベント: parseBegin
parseBegin
イベントは、JSDocがソースファイルのロードと解析を開始する前に発火します。プラグインは、イベントの内容を変更することにより、JSDocが解析するファイルを制御できます。
注: このイベントは、JSDoc 3.2以降で発火します。
イベントオブジェクトには、次のプロパティが含まれています。
sourcefiles
: 解析されるソースファイルへのパスの配列。
イベント: fileBegin
fileBegin
イベントは、パーサーがファイルを解析しようとするときに発火します。プラグインは、必要に応じてこのイベントを使用してファイルごとの初期化をトリガーできます。
イベントオブジェクトには、次のプロパティが含まれています。
filename
: ファイルの名前。
イベント: beforeParse
beforeParse
イベントは、解析が開始される前に発火します。プラグインは、このメソッドを使用して、解析されるソースコードを変更できます。たとえば、プラグインはJSDocコメントを追加したり、有効なJavaScriptではない前処理タグを削除したりできます。
イベントオブジェクトには、次のプロパティが含まれています。
filename
: ファイルの名前。source
: ファイルの内容。
以下は、関数用の仮想コメントをソースに追加して、ドキュメントに解析および追加されるようにする例です。これは、ユーザーが利用できるが、ドキュメント化されるソースコードには表示されない可能性のあるメソッド(外部スーパークラスによって提供されるメソッドなど)をドキュメント化するために実行される場合があります。
exports.handlers = {
beforeParse: function(e) {
var extraDoc = [
'/**',
' * Function provided by a superclass.',
' * @name superFunc',
' * @memberof ui.mywidget',
' * @function',
' */'
];
e.source += extraDoc.join('\n');
}
};
イベント: jsdocCommentFound
jsdocCommentFound
イベントは、JSDocコメントが見つかるたびに発火します。コメントは、任意のコードに関連付けられている場合と、そうでない場合があります。このイベントを使用して、処理される前にコメントの内容を変更する場合があります。
イベントオブジェクトには、次のプロパティが含まれています。
filename
: ファイルの名前。comment
: JSDocコメントのテキスト。lineno
: コメントが見つかった行番号。columnno
: コメントが見つかった列番号。JSDoc 3.5.0以降で利用可能です。
イベント: symbolFound
symbolFound
イベントは、パーサーがドキュメント化する必要がある可能性のあるコード内のシンボルに遭遇したときに発火します。たとえば、パーサーは、ソースファイル内の各変数、関数、およびオブジェクトリテラルのsymbolFound
イベントを発火します。
イベントオブジェクトには、次のプロパティが含まれています。
filename
: ファイルの名前。comment
: シンボルに関連付けられたコメントのテキスト(存在する場合)。id
: シンボルの一意のID。lineno
: シンボルが見つかった行番号。columnno
: シンボルが見つかった列番号。JSDoc 3.5.0以降で利用可能です。range
: シンボルに関連付けられているソースファイル内の最初と最後の文字の数値インデックスを含む配列。astnode
: 抽象構文木からのシンボルのノード。code
: コードに関する詳細情報を含むオブジェクト。このオブジェクトには通常、name
、type
、およびnode
プロパティが含まれています。オブジェクトには、シンボルに応じてvalue
、paramnames
、またはfuncscope
プロパティも含まれる場合があります。
イベント: newDoclet
newDoclet
イベントは、最高レベルのイベントです。新しいドクレットが作成されたときに発火します。これは、JSDocコメントまたはシンボルが処理され、テンプレートに渡される実際のドクレットが作成されたことを意味します。
イベントオブジェクトには、次のプロパティが含まれています。
doclet
: 作成された新しいドクレット。
ドクレットのプロパティは、ドクレットが表すコメントまたはシンボルによって異なる場合があります。よく見られる一般的なプロパティには、次のものがあります。
comment
: JSDocコメントのテキスト。シンボルがドキュメント化されていない場合は空の文字列。meta
: ドクレットがソースファイルにどのように関連するかを記述するオブジェクト(たとえば、ソースファイル内の場所)。description
: ドキュメント化されているシンボルの説明。kind
: ドキュメント化されているシンボルの種類(たとえば、class
またはfunction
)。name
: シンボルの短い名前(たとえば、myMethod
)。longname
: memberof情報を含む完全修飾名(たとえば、MyClass#myMethod
)。memberof
: このシンボルが属するモジュール、名前空間、またはクラス(たとえば、MyClass
)。シンボルに親がない場合は空の文字列。scope
: 親内のシンボルのスコープ(たとえば、global
、static
、instance
、またはinner
)。undocumented
: シンボルにJSDocコメントがない場合はtrue
に設定されます。defaultvalue
: シンボルのデフォルト値。type
: シンボルのタイプに関する詳細を含むオブジェクト。params
: 関数へのパラメーターのリストを含むオブジェクト。tags
: JSDocが認識しなかったタグのリストを含むオブジェクト。JSDocの設定ファイルでallowUnknownTags
がtrue
に設定されている場合にのみ使用できます。
JSDocがコードに対して生成するドクレットを確認するには、-X
コマンドラインオプションを使用してJSDocを実行します。
以下は、説明を強調するnewDoclet
ハンドラの例です。
exports.handlers = {
newDoclet: function(e) {
// e.doclet will refer to the newly created doclet
// you can read and modify properties of that doclet if you wish
if (typeof e.doclet.description === 'string') {
e.doclet.description = e.doclet.description.toUpperCase();
}
}
};
イベント: fileComplete
fileComplete
イベントは、パーサーがファイルの解析を完了したときに発火します。プラグインは、このイベントを使用してファイルごとのクリーンアップをトリガーできます。
イベントオブジェクトには、次のプロパティが含まれています。
filename
: ファイルの名前。source
: ファイルの内容。
イベント: parseComplete
parseComplete
イベントは、JSDocが指定されたすべてのソースファイルの解析を完了した後に発火します。
注: このイベントは、JSDoc 3.2以降で発火します。
イベントオブジェクトには、次のプロパティが含まれています。
sourcefiles
: 解析されたソースファイルへのパスの配列。doclets
: ドクレットオブジェクトの配列。各ドクレットに含めることができるプロパティの詳細については、newDoclet
イベントを参照してください。JSDoc 3.2.1以降で利用可能です。
イベント: processingComplete
processingComplete
イベントは、JSDocが継承および借用されたシンボルを反映するように解析結果を更新した後に発火します。
注: このイベントは、JSDoc 3.2.1以降で発火します。
イベントオブジェクトには、次のプロパティが含まれています。
doclets
: ドクレットオブジェクトの配列。各ドクレットに含めることができるプロパティの詳細については、newDoclet
イベントを参照してください。
タグの定義
タグをタグ辞書に追加することは、ドキュメントの生成に影響を与える中レベルの方法です。newDoclet
イベントがトリガーされる前に、JSDocコメントブロックが解析されて、説明と存在する可能性のあるJSDocタグが決定されます。タグが見つかった場合、タグ辞書で定義されていると、ドクレットを変更する機会が与えられます。
プラグインは、defineTags
関数をエクスポートすることにより、タグを定義できます。その関数には、次のようにタグを定義するために使用できる辞書が渡されます。
exports.defineTags = function(dictionary) {
// define tags here
};
辞書
辞書は、次のメソッドを提供します。
defineTag(title, opts)
: タグを定義するために使用されます。最初のパラメーターはタグの名前(たとえば、param
またはoverview
)です。2番目のパラメーターは、タグのオプションを含むオブジェクトです。次のオプションのいずれかを含めることができます。各オプションのデフォルト値はfalse
です。canHaveType (boolean)
: タグテキストに型式(@param {string} name - Description
の{string}
など)を含めることができる場合はtrue
に設定します。canHaveName (boolean)
: タグテキストに名前(@param {string} name - Description
のname
など)を含めることができる場合はtrue
に設定します。isNamespace (boolean)
: タグを名前空間としてドクレットのlongnameに適用する場合はtrue
に設定します。たとえば、@module
タグはこのオプションをtrue
に設定し、タグ@module myModuleName
を使用すると、longnameがmodule:myModuleName
になります。mustHaveValue (boolean)
: タグに値(@name TheName
のTheName
など)が必要な場合はtrue
に設定します。mustNotHaveDescription (boolean)
: タグに値を持たせることができるが、説明(@tag {typeExpr} TheDescription
のTheDescription
など)を持たせてはならない場合はtrue
に設定します。mustNotHaveValue (boolean)
: タグに値があってはならない場合はtrue
に設定します。onTagged (function)
: タグが見つかったときに実行されるコールバック関数。この関数には、ドクレットとタグオブジェクトの2つのパラメーターが渡されます。
lookUp(tagName)
: 名前でタグオブジェクトを取得します。オプションを含むタグオブジェクトを返します。タグが定義されていない場合はfalse
を返します。isNamespace(tagName)
: タグが名前空間としてドクレットのlongnameに適用される場合はtrue
を返します。normalise(tagName)
: タグの正規名を返します。たとえば、@const
タグは@constant
の同義語です。その結果、normalise('const')
を呼び出すと、文字列constant
が返されます。normalize(tagName)
:normalise
の同義語。JSDoc 3.3.0以降で利用可能です。
タグのonTagged
コールバックは、ドクレットまたはタグの内容を変更できます。
dictionary.defineTag('instance', {
onTagged: function(doclet, tag) {
doclet.scope = "instance";
}
});
defineTag
メソッドは、タグの同義語を宣言するために使用できるsynonym
メソッドを持つTag
オブジェクトを返します。
dictionary.defineTag('exception', { /* options for exception tag */ })
.synonym('throws');
ノードビジター
最下位レベルでは、プラグイン作成者は、各ノードを訪問するノードビジターを定義することにより、抽象構文木(AST)の各ノードを処理できます。ノードビジタープラグインを使用すると、コメントを変更し、任意のコードに対してパーサーイベントをトリガーできます。
プラグインは、次のようにvisitNode
関数を含むastNodeVisitor
オブジェクトをエクスポートすることにより、ノードビジターを定義できます。
exports.astNodeVisitor = {
visitNode: function(node, e, parser, currentSourceName) {
// do all sorts of crazy things here
}
};
この関数は、次のパラメーターを持つ各ノードで呼び出されます。
node
: ASTノード。ASTノードは、ESTree仕様で定義された形式を使用するJavaScriptオブジェクトです。AST Explorerを使用して、ソースコードに対して作成されるASTを確認できます。バージョン3.5.0の時点で、JSDocは、すべてのプラグインが有効になっているBabylonパーサーの現在のバージョンを使用しています。e
: イベント。ノードがパーサーが処理するものである場合、イベントオブジェクトには、上記のsymbolFound
イベントで説明されているものと同じものが既に入力されます。それ以外の場合は、さまざまなプロパティを設定する空のオブジェクトになります。parser
: JSDocパーサーインスタンス。currentSourceName
: 解析されているファイルの名前。
実行する
ノードビジターを実装する主な理由は、通常はドキュメント化されないもの(クラスを作成する関数呼び出しなど)をドキュメント化したり、ドキュメント化されていないコードのドキュメントを自動生成したりできるようにするためです。たとえば、プラグインは、イベントが発火することを意味する_trigger
メソッドへの呼び出しを探し、そのイベントのドキュメントを生成する可能性があります。
処理を実行するには、visitNode
関数はイベントパラメータのプロパティを変更する必要があります。一般的に、目的はコメントを構築し、イベントを発火させることです。パーサーがすべてのノードビジターにノードを確認させた後、イベントオブジェクトにcomment
プロパティとevent
プロパティがあるかどうかを確認します。両方がある場合、eventプロパティで指定されたイベントが発火します。イベントは通常symbolFound
またはjsdocCommentFound
ですが、理論的には、プラグインは独自のイベントを定義して処理することができます。
イベントハンドラープラグインと同様に、ノードビジタープラグインは、イベントオブジェクトにstopPropagation
プロパティを設定することによって、後続のプラグインの実行を停止できます(e.stopPropagation = true
)。プラグインは、preventDefault
プロパティを設定することでイベントの発火を停止できます(e.preventDefault = true
)。
エラーの報告
プラグインでエラーを報告する必要がある場合は、jsdoc/util/logger
モジュールの次のいずれかのメソッドを使用します。
logger.warn
:ユーザーに起こりうる問題について警告します。logger.error
:プラグインが回復できるエラーを報告します。logger.fatal
:JSDocの実行を停止させる必要があるエラーを報告します。
これらのメソッドを使用すると、単にエラーをスローするよりもユーザーエクスペリエンスが向上します。
注意:エラーの報告にjsdoc/util/error
モジュールを使用しないでください。このモジュールは非推奨であり、将来のバージョンのJSDocで削除されます。
var logger = require('jsdoc/util/logger');
exports.handlers = {
newDoclet: function(e) {
// Your code here.
if (somethingBadHappened) {
logger.error('Oh, no, something bad happened!');
}
}
};