关于 JSDoc 插件
创建并启用插件
¥Creating and Enabling a Plugin
创建并启用新的 JSDoc 插件需要两个步骤:
¥There are two steps required to create and enable a new JSDoc plugin:
-
创建一个 JavaScript 模块来包含你的插件代码。
¥Create a JavaScript module to contain your plugin code.
-
将该模块包含在 JSDoc 的配置文件 的
plugins
数组中。你可以指定绝对或相对路径。如果使用相对路径,JSDoc 会在当前工作目录中搜索插件;配置文件所在目录;和 JSDoc 目录,按此顺序。¥Include that module in the
plugins
array of JSDoc's configuration file. You can specify an absolute or relative path. If you use a relative path, JSDoc searches for the plugin in the current working directory; the directory where the configuration file is located; and the JSDoc directory, in that order.
例如,如果你的插件是在当前工作目录中的 plugins/shout.js
文件中定义的,则你可以将字符串 plugins/shout
添加到 JSDoc 配置文件中的 plugins
数组中:
¥For example, if your plugin is defined in the plugins/shout.js
file in the current working
directory, you would add the string plugins/shout
to the plugins
array in your JSDoc
configuration file:
{
"plugins": ["plugins/shout"]
}
JSDoc 按照插件在配置文件中列出的顺序执行插件。
¥JSDoc executes plugins in the order that they are listed in the configuration file.
编写 JSDoc 3 插件
¥Authoring JSDoc 3 Plugins
JSDoc 3 的插件系统提供了对解析过程的广泛控制。插件可以通过执行以下任意操作来影响解析结果:
¥JSDoc 3's plugin system offers extensive control over the parsing process. A plugin can affect the parse results by doing any of the following:
-
定义事件处理程序
¥Defining event handlers
-
定义标签
¥Defining tags
-
定义抽象语法树节点的访问者
¥Defining a visitor for abstract syntax tree nodes
事件处理程序
¥Event Handlers
在最高级别,插件可以为 JSDoc 触发的特定命名事件注册处理程序。JSDoc 会将事件对象传递给处理程序。你的插件模块应该导出一个包含你的处理程序的 handlers
对象,如下所示:
¥At the highest level, a plugin may register handlers for specific named events that JSDoc fires.
JSDoc will pass an event object to the handler. Your plugin module should export a handlers
object
that contains your handler, like so:
exports.handlers = {
newDoclet: function(e) {
// Do something when we see a new doclet
}
};
JSDoc 以与底层代码相同的顺序触发事件。
¥JSDoc fires events in the same order as the underlying code.
事件处理程序插件可以通过在事件对象 (e.stopPropagation = true
) 上设置 stopPropagation
属性来阻止以后的插件运行。插件可以通过设置 preventDefault
属性 (e.preventDefault = true
) 来阻止事件触发。
¥An event-handler plugin can stop later plugins from running by setting a stopPropagation
property
on the event object (e.stopPropagation = true
). A plugin can stop the event from firing by setting
a preventDefault
property (e.preventDefault = true
).
事件:parseBegin
¥Event: parseBegin
parseBegin
事件在 JSDoc 开始加载和解析源文件之前触发。你的插件可以通过修改事件的内容来控制 JSDoc 将解析哪些文件。
¥The parseBegin
event is fired before JSDoc starts loading and parsing the source files. Your
plugin can control which files JSDoc will parse by modifying the event's contents.
注意:该事件在 JSDoc 3.2 及更高版本中触发。
¥Note: This event is fired in JSDoc 3.2 and later.
事件对象包含以下属性:
¥The event object contains the following properties:
-
sourcefiles
:将被解析的源文件的路径数组。¥
sourcefiles
: An array of paths to source files that will be parsed.
事件:fileBegin
¥Event: fileBegin
当解析器即将解析文件时会触发 fileBegin
事件。如果需要,你的插件可以使用此事件来触发每个文件的初始化。
¥The fileBegin
event is fired when the parser is about to parse a file. Your plugin can use this
event to trigger per-file initialization if necessary.
事件对象包含以下属性:
¥The event object contains the following properties:
-
filename
:文件的名称。¥
filename
: The name of the file.
事件:beforeParse
¥Event: beforeParse
beforeParse
事件在解析开始之前被触发。插件可以使用此方法修改将要解析的源代码。例如,你的插件可以添加 JSDoc 注释,或者可以删除不是有效 JavaScript 的预处理标记。
¥The beforeParse
event is fired before parsing has begun. Plugins can use this method to modify the
source code that will be parsed. For instance, your plugin could add a JSDoc comment, or it could
remove preprocessing tags that are not valid JavaScript.
事件对象包含以下属性:
¥The event object contains the following properties:
-
filename
:文件的名称。¥
filename
: The name of the file. -
source
:文件的内容。¥
source
: The contents of the file.
下面是一个示例,它将函数的虚拟注释添加到源代码中,以便对其进行解析并添加到文档中。这样做可能是为了记录用户可用的方法,但可能不会出现在正在记录的源代码中,例如外部超类提供的方法:
¥Below is an example that adds a virtual comment for a function to the source so that it will get parsed and added to the documentation. This might be done to document methods that will be available to users, but might not appear in the source code being documented, such as methods provided by an external superclass:
exports.handlers = {
beforeParse: function(e) {
var extraDoc = [
'/**',
' * Function provided by a superclass.',
' * @name superFunc',
' * @memberof ui.mywidget',
' * @function',
' */'
];
e.source += extraDoc.join('\n');
}
};
事件:jsdocCommentFound
¥Event: jsdocCommentFound
只要找到 JSDoc 注释,就会触发 jsdocCommentFound
事件。该注释可能与任何代码相关联,也可能不相关联。你可以使用此事件在处理评论之前修改评论的内容。
¥The jsdocCommentFound
event is fired whenever a JSDoc comment is found. The comment may or may not
be associated with any code. You might use this event to modify the contents of a comment before it
is processed.
事件对象包含以下属性:
¥The event object contains the following properties:
-
filename
:文件的名称。¥
filename
: The name of the file. -
comment
:JSDoc 注释的文本。¥
comment
: The text of the JSDoc comment. -
lineno
:找到评论的行号。¥
lineno
: The line number on which the comment was found. -
columnno
:找到评论的列号。在 JSDoc 3.5.0 及更高版本中可用。¥
columnno
: The column number on which the comment was found. Available in JSDoc 3.5.0 and later.
事件:symbolFound
¥Event: symbolFound
当解析器在代码中遇到可能需要记录的符号时,会触发 symbolFound
事件。例如,解析器为源文件中的每个变量、函数和对象字面量触发 symbolFound
事件。
¥The symbolFound
event is fired when the parser comes across a symbol in the code that may need to
be documented. For example, the parser fires a symbolFound
event for each variable, function, and
object literal in a source file.
事件对象包含以下属性:
¥The event object contains the following properties:
-
filename
:文件的名称。¥
filename
: The name of the file. -
comment
:与符号关联的注释文本(如果有)。¥
comment
: The text of the comment associated with the symbol, if any. -
id
:符号的唯一 ID。¥
id
: The unique ID of the symbol. -
lineno
:找到该符号的行号。¥
lineno
: The line number on which the symbol was found. -
columnno
:找到符号的列号。在 JSDoc 3.5.0 及更高版本中可用。¥
columnno
: The column number on which the symbol was found. Available in JSDoc 3.5.0 and later. -
range
:包含源文件中与符号关联的第一个和最后一个字符的数字索引的数组。¥
range
: An array containing the numeric index of the first and last characters in the source file that are associated with the symbol. -
astnode
:抽象语法树中符号的节点。¥
astnode
: The symbol's node from the abstract syntax tree. -
code
:包含有关代码的详细信息的对象。该对象通常包含name
、type
和node
属性。该对象还可能具有value
、paramnames
或funcscope
属性,具体取决于符号。¥
code
: Object with detailed information about the code. This object usually containsname
,type
, andnode
properties. The object might also havevalue
,paramnames
, orfuncscope
properties depending on the symbol.
事件:newDoclet
¥Event: newDoclet
newDoclet
赛事是最高级别的赛事。当创建新的 doclet 时会触发它。这意味着 JSDoc 注释或符号已被处理,并且已创建将传递给模板的实际 doclet。
¥The newDoclet
event is the highest-level event. It is fired when a new doclet has been created.
This means that a JSDoc comment or a symbol has been processed, and the actual doclet that will be
passed to the template has been created.
事件对象包含以下属性:
¥The event object contains the following properties:
-
doclet
:创建的新 doclet。¥
doclet
: The new doclet that was created.
doclet 的属性可能会根据 doclet 表示的注释或符号而变化。你可能会看到的一些常见属性包括:
¥The doclet's properties can vary depending on the comment or symbol that the doclet represents. Some common properties you're likely to see include:
-
comment
:JSDoc 注释的文本,如果符号未记录,则为空字符串。¥
comment
: The text of the JSDoc comment, or an empty string if the symbol is undocumented. -
meta
:描述 doclet 如何与源文件相关的对象(例如,源文件中的位置)。¥
meta
: Object that describes how the doclet relates to the source file (for example, the location within the source file). -
description
:对正在记录的符号的描述。¥
description
: A description of the symbol being documented. -
kind
:记录的符号类型(例如,class
或function
)。¥
kind
: The kind of symbol being documented (for example,class
orfunction
). -
name
:符号的简称(例如,myMethod
)。¥
name
: The short name for the symbol (for example,myMethod
). -
longname
:完全限定名称,包括成员信息(例如,MyClass#myMethod
)。¥
longname
: The fully qualified name, including memberof info (for example,MyClass#myMethod
). -
memberof
:该符号所属的模块、命名空间或类(例如,MyClass
),如果该符号没有父级,则为空字符串。¥
memberof
: The module, namespace, or class that this symbol belongs to (for example,MyClass
), or an empty string if the symbol does not have a parent. -
scope
:符号在其父级中的范围(例如,global
、static
、instance
或inner
)。¥
scope
: The scope of the symbol within its parent (for example,global
,static
,instance
, orinner
). -
undocumented
:如果符号没有 JSDoc 注释,则设置为true
。¥
undocumented
: Set totrue
if the symbol did not have a JSDoc comment. -
defaultvalue
:符号的默认值。¥
defaultvalue
: The default value for a symbol. -
type
:包含有关符号类型的详细信息的对象。¥
type
: Object containing details about the symbol's type. -
params
:包含函数参数列表的对象。¥
params
: Object containing the list of parameters to a function. -
tags
:包含 JSDoc 无法识别的标签列表的对象。仅当 JSDoc 的配置文件中allowUnknownTags
设置为true
时才可用。¥
tags
: Object containing a list of tags that JSDoc did not recognize. Only available ifallowUnknownTags
is set totrue
in JSDoc's configuration file.
要查看 JSDoc 为你的代码生成的 doclet,请使用 -X
命令行选项 运行 JSDoc。
¥To see the doclets that JSDoc generates for your code, run JSDoc with the -X
command-line
option.
下面是一个 newDoclet
处理程序的示例,它会喊出描述:
¥Below is an example of a newDoclet
handler that shouts the descriptions:
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
¥Event: fileComplete
当解析器完成解析文件时会触发 fileComplete
事件。你的插件可以使用此事件来触发每个文件的清理。
¥The fileComplete
event is fired when the parser has finished parsing a file. Your plugin could use
this event to trigger per-file cleanup.
事件对象包含以下属性:
¥The event object contains the following properties:
-
filename
:文件的名称。¥
filename
: The name of the file. -
source
:文件的内容。¥
source
: The contents of the file.
事件:parseComplete
¥Event: parseComplete
JSDoc 解析完所有指定的源文件后,会触发 parseComplete
事件。
¥The parseComplete
event is fired after JSDoc has parsed all of the specified source files.
注意:该事件在 JSDoc 3.2 及更高版本中触发。
¥Note: This event is fired in JSDoc 3.2 and later.
事件对象包含以下属性:
¥The event object contains the following properties:
-
sourcefiles
:已解析的源文件的路径数组。¥
sourcefiles
: An array of paths to source files that were parsed. -
doclets
:doclet 对象的数组。有关每个 doclet 可以包含的属性的详细信息,请参阅newDoclet
事件。在 JSDoc 3.2.1 及更高版本中可用。¥
doclets
: An array of doclet objects. See thenewDoclet
event for details about the properties that each doclet can contain. Available in JSDoc 3.2.1 and later.
事件:processingComplete
¥Event: processingComplete
JSDoc 更新解析结果以反映继承和借用的符号后,会触发 processingComplete
事件。
¥The processingComplete
event is fired after JSDoc updates the parse results to reflect inherited
and borrowed symbols.
注意:该事件在 JSDoc 3.2.1 及更高版本中触发。
¥Note: This event is fired in JSDoc 3.2.1 and later.
事件对象包含以下属性:
¥The event object contains the following properties:
-
doclets
:doclet 对象的数组。有关每个 doclet 可以包含的属性的详细信息,请参阅newDoclet
事件。¥
doclets
: An array of doclet objects. See thenewDoclet
event for details about the properties that each doclet can contain.
标签定义
¥Tag Definitions
将标签添加到标签字典是影响文档生成的中级方法。在触发 newDoclet
事件之前,将解析 JSDoc 注释块以确定描述和可能存在的任何 JSDoc 标签。当找到标签时,如果它已在标签字典中定义,则有机会修改 doclet。
¥Adding tags to the tag dictionary is a mid-level way to affect documentation generation. Before a
newDoclet
event is triggered, JSDoc comment blocks are parsed to determine the description and any
JSDoc tags that may be present. When a tag is found, if it has been defined in the tag dictionary,
it is given a chance to modify the doclet.
插件可以通过导出 defineTags
函数来定义标签。该函数将传递一个可用于定义标签的字典,如下所示:
¥Plugins can define tags by exporting a defineTags
function. That function will be passed a
dictionary that can be used to define tags, like so:
exports.defineTags = function(dictionary) {
// define tags here
};
词典
¥The Dictionary
字典提供了以下方法:
¥The dictionary provides the following methods:
-
defineTag(title, opts)
:用于定义标签。第一个参数是标签的名称(例如param
或overview
)。第二个是包含标签选项的对象。你可以包含以下任何选项;每个选项的默认值为false
:¥
defineTag(title, opts)
: Used to define tags. The first parameter is the name of the tag (for example,param
oroverview
). The second is an object containing options for the tag. You can include any of the following options; the default value for each option isfalse
:-
canHaveType (boolean)
:如果标签文本可以包含类型表达式(例如@param {string} name - Description
中的{string}
),则设置为true
。¥
canHaveType (boolean)
: Set totrue
if the tag text can include a type expression (such as{string}
in@param {string} name - Description
). -
canHaveName (boolean)
:如果标签文本可以包含名称(例如@param {string} name - Description
中的name
),则设置为true
。¥
canHaveName (boolean)
: Set totrue
if the tag text can include a name (such asname
in@param {string} name - Description
). -
isNamespace (boolean)
:如果标签应作为名称空间应用于 doclet 的长名称,则设置为true
。例如,@module
标记将此选项设置为true
,使用标记@module myModuleName
会生成长名称module:myModuleName
。¥
isNamespace (boolean)
: Set totrue
if the tag should be applied to the doclet's longname as a namespace. For example, the@module
tag sets this option totrue
, and using the tag@module myModuleName
results in the longnamemodule:myModuleName
. -
mustHaveValue (boolean)
:如果标签必须有值(例如@name TheName
中的TheName
),则设置为true
。¥
mustHaveValue (boolean)
: Set totrue
if the tag must have a value (such asTheName
in@name TheName
). -
mustNotHaveDescription (boolean)
:如果标签可以有值但不能有描述(例如@tag {typeExpr} TheDescription
中的TheDescription
),则设置为true
。¥
mustNotHaveDescription (boolean)
: Set totrue
if the tag may have a value but must not have a description (such asTheDescription
in@tag {typeExpr} TheDescription
). -
mustNotHaveValue (boolean)
:如果标签不能有值,则设置为true
。¥
mustNotHaveValue (boolean)
: Set totrue
if the tag must not have a value. -
onTagged (function)
:找到标签时执行的回调函数。该函数传递两个参数:doclet 和标签对象。¥
onTagged (function)
: A callback function executed when the tag is found. The function is passed two parameters: the doclet and the tag object.
-
-
lookUp(tagName)
:按名称检索标签对象。返回标签对象,包括其选项;如果未定义标签,则返回false
。¥
lookUp(tagName)
: Retrieve a tag object by name. Returns the tag object, including its options, orfalse
if the tag is not defined. -
isNamespace(tagName)
:如果标记作为命名空间应用于 doclet 的长名称,则返回true
。¥
isNamespace(tagName)
: Returnstrue
if the tag is applied to a doclet's longname as a namespace. -
normalise(tagName)
:返回标签的规范名称。例如,@const
标签是@constant
的同义词;因此,如果调用normalise('const')
,它会返回字符串constant
。¥
normalise(tagName)
: Returns the canonical name of a tag. For example, the@const
tag is a synonym for@constant
; as a result, if you callnormalise('const')
, it returns the stringconstant
. -
normalize(tagName)
:normalise
的同义词。在 JSDoc 3.3.0 及更高版本中可用。¥
normalize(tagName)
: Synonym fornormalise
. Available in JSDoc 3.3.0 and later.
标签的 onTagged
回调可以修改 doclet 或标签的内容。
¥A tag's onTagged
callback can modify the contents of the doclet or tag.
dictionary.defineTag('instance', {
onTagged: function(doclet, tag) {
doclet.scope = "instance";
}
});
defineTag
方法返回一个 Tag
对象,该对象有一个 synonym
方法,可用于声明标记的同义词。
¥The defineTag
method returns a Tag
object, which has a synonym
method that can be used to
declare a synonym for the tag.
dictionary.defineTag('exception', { /* options for exception tag */ })
.synonym('throws');
节点访问者
¥Node Visitors
在最低级别,插件作者可以通过定义将访问每个节点的节点访问者来处理抽象语法树(AST)中的每个节点。通过使用节点访问者插件,你可以修改任意代码段的注释并触发解析器事件。
¥At the lowest level, plugin authors can process each node in the abstract syntax tree (AST) by defining a node visitor that will visit each node. By using a node-visitor plugin, you can modify comments and trigger parser events for any arbitrary piece of code.
插件可以通过导出包含 visitNode
函数的 astNodeVisitor
对象来定义节点访问者,如下所示:
¥Plugins can define a node visitor by exporting an astNodeVisitor
object that contains a
visitNode
function, like so:
exports.astNodeVisitor = {
visitNode: function(node, e, parser, currentSourceName) {
// do all sorts of crazy things here
}
};
该函数在每个节点上调用,参数如下:
¥The function is called on each node with the following parameters:
-
node
:AST 节点。AST 节点是使用 ESTree 规范 定义的格式的 JavaScript 对象。你可以使用 AST 探索者 查看将为你的源代码创建的 AST。从版本 3.5.0 开始,JSDoc 使用当前版本的 巴比伦 解析器并启用所有插件。¥
node
: The AST node. AST nodes are JavaScript objects that use the format defined by the ESTree spec. You can use AST Explorer to see the AST that will be created for your source code. As of version 3.5.0, JSDoc uses the current version of the Babylon parser with all plugins enabled. -
e
:事件。如果该节点是解析器处理的节点,则事件对象将已经填充有上面symbolFound
事件中描述的相同内容。否则,它将是一个空对象,可以在其上设置各种属性。¥
e
: The event. If the node is one that the parser handles, the event object will already be populated with the same things described in thesymbolFound
event above. Otherwise, it will be an empty object on which to set various properties. -
parser
:JSDoc 解析器实例。¥
parser
: The JSDoc parser instance. -
currentSourceName
:正在解析的文件的名称。¥
currentSourceName
: The name of the file being parsed.
让事情发生
¥Making things happen
实现节点访问者的主要原因是能够记录通常未记录的内容(例如创建类的函数调用)或自动为未记录的代码生成文档。例如,插件可能会查找对 _trigger
方法的调用,因为它知道这意味着事件被触发,然后生成该事件的文档。
¥The primary reasons to implement a node visitor are to be able to document things that aren't
normally documented (like function calls that create classes) or to auto generate documentation for
code that isn't documented. For instance, a plugin might look for calls to a _trigger
method since
it knows that means an event is fired and then generate documentation for the event.
为了使事情发生,visitNode
函数应该修改事件参数的属性。一般来说,目标是构建评论,然后触发事件。在解析器让所有节点访问者查看该节点后,它会查看事件对象是否具有 comment
属性和 event
属性。如果两者都有,则触发事件属性中指定的事件。事件通常是 symbolFound
或 jsdocCommentFound
,但理论上,插件可以定义自己的事件并处理它们。
¥To make things happen, the visitNode
function should modify properties of the event parameter. In
general the goal is to construct a comment and then get an event to fire. After the parser lets all
of the node visitors have a look at the node, it looks to see if the event object has a comment
property and an event
property. If it has both, the event named in the event property is fired.
The event is usually symbolFound
or jsdocCommentFound
, but theoretically, a plugin could define
its own events and handle them.
与事件处理程序插件一样,节点访问者插件可以通过在事件对象 (e.stopPropagation = true
) 上设置 stopPropagation
属性来阻止以后的插件运行。插件可以通过设置 preventDefault
属性 (e.preventDefault = true
) 来阻止事件触发。
¥As with event-handler plugins, a node-visitor plugin can stop later plugins from running by setting
a stopPropagation
property on the event object (e.stopPropagation = true
). A plugin can stop the
event from firing by setting a preventDefault
property (e.preventDefault = true
).
报告错误
¥Reporting Errors
如果你的插件需要报告错误,请在 jsdoc/util/logger
模块中使用以下方法之一:
¥If your plugin needs to report an error, use one of the following methods in the jsdoc/util/logger
module:
-
logger.warn
:警告用户可能出现的问题。¥
logger.warn
: Warn the user about a possible problem. -
logger.error
:报告插件可以恢复的错误。¥
logger.error
: Report an error from which the plugin can recover. -
logger.fatal
:报告会导致 JSDoc 停止运行的错误。¥
logger.fatal
: Report an error that should cause JSDoc to stop running.
使用这些方法可以比简单地抛出错误创造更好的用户体验。
¥Using these methods creates a better user experience than simply throwing an error.
注意:不要使用 jsdoc/util/error
模块报告错误。该模块已弃用,并将在 JSDoc 的未来版本中删除。
¥Note: Do not use the jsdoc/util/error
module to report errors. This module is deprecated and
will be removed in a future version of JSDoc.
var logger = require('jsdoc/util/logger');
exports.handlers = {
newDoclet: function(e) {
// Your code here.
if (somethingBadHappened) {
logger.error('Oh, no, something bad happened!');
}
}
};