关于 JSDoc 插件
创建和启用插件
创建并启用新的 JSDoc 插件需要两个步骤
- 创建一个 JavaScript 模块来包含插件代码。
- 将该模块包含在 JSDoc 配置文件 的
plugins
数组中。您可以指定绝对或相对路径。如果您使用相对路径,JSDoc 将按以下顺序在当前工作目录、配置文件所在目录和 JSDoc 目录中搜索插件。
例如,如果您的插件在当前工作目录中的 plugins/shout.js
文件中定义,则需要将字符串 plugins/shout
添加到 JSDoc 配置文件中的 plugins
数组中
JSDoc 按在配置文件中列出的顺序执行插件。
编写 JSDoc 3 插件
JSDoc 3 的插件系统提供对解析过程的广泛控制。插件可以通过执行以下任何操作来影响解析结果
- 定义事件处理程序
- 定义标签
- 定义抽象语法树节点的访问器
事件处理程序
在最高级别,插件可以为 JSDoc 引发的特定命名事件注册处理程序。JSDoc 会将事件对象传递给处理程序。您的插件模块应导出一个包含处理程序的 handlers
对象,如下所示
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
:文件内容。
以下示例为源代码添加了一个函数的虚拟注释,以便解析该注释并将其添加到文档中。这可能是为了记录对用户可用的方法,但可能不会出现在要记录的源代码中,例如外部超类提供的方法
事件:jsdocCommentFound
每当找到 JSDoc 注释时,都会触发 jsdocCommentFound
事件。该注释可能与代码相关,也可能不相关。您可以在处理注释之前使用此事件来修改注释的内容。
事件对象包含以下属性
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
:完全限定名称,包括成员信息(例如,MyClass#myMethod
)。memberof
:此符号所属的模块、命名空间或类(例如,MyClass
),如果符号没有父级,则为空字符串。scope
:符号在其父级内的范围(例如,global
、static
、instance
或inner
)。undocumented
:如果符号没有 JSDoc 注释,则设置为true
。defaultvalue
:符号的默认值。type
:包含有关符号类型的详细信息的对象。params
:包含函数参数列表的对象。tags
:包含 JSDoc 未识别的标签列表的对象。仅当在 JSDoc 的配置文件中将allowUnknownTags
设置为true
时才可用。
要查看 JSDoc 为您的代码生成的文档,请使用 -X
命令行选项 运行 JSDoc。
以下是 newDoclet
处理程序的示例,它会大声说出描述
事件:fileComplete
当解析器完成解析文件时,将触发 fileComplete
事件。您的插件可以使用此事件触发每个文件的清理。
事件对象包含以下属性
filename
:文件名。source
:文件内容。
事件:parseComplete
在 JSDoc 解析所有指定的源文件后,将触发 parseComplete
事件。
注意:此事件在 JSDoc 3.2 及更高版本中触发。
事件对象包含以下属性
sourcefiles
:已解析的源文件路径数组。doclets
:文档对象数组。有关每个文档可以包含的属性的详细信息,请参阅newDoclet
事件。在 JSDoc 3.2.1 及更高版本中可用。
事件:processingComplete
在 JSDoc 更新解析结果以反映继承和借用的符号后,将触发 processingComplete
事件。
注意:此事件在 JSDoc 3.2.1 及更高版本中触发。
事件对象包含以下属性
doclets
:doclet 对象数组。有关每个 doclet 可能包含的属性的详细信息,请参阅newDoclet
事件。
标签定义
向标签词典中添加标签是影响文档生成的中级方法。在触发 newDoclet
事件之前,将解析 JSDoc 注释块以确定描述和可能存在的任何 JSDoc 标签。当找到标签时,如果已在标签词典中定义该标签,则会给它一个修改 doclet 的机会。
插件可以通过导出 defineTags
函数来定义标签。该函数将传递一个词典,该词典可用于定义标签,如下所示
词典
词典提供以下方法
defineTag(title, opts)
:用于定义标签。第一个参数是标签的名称(例如,param
或overview
)。第二个参数是包含标签选项的对象。你可以包含以下任何选项;每个选项的默认值为false
canHaveType (boolean)
:如果标签文本可以包含类型表达式(例如@param {string} name - Description
中的{string}
),则设置为true
。canHaveName (boolean)
:如果标签文本可以包含名称(例如@param {string} name - Description
中的name
),则设置为true
。isNamespace (boolean)
:如果应将标签作为命名空间应用于 doclet 的 longname,则设置为true
。例如,@module
标签将此选项设置为true
,并且使用标签@module myModuleName
会生成 longnamemodule:myModuleName
。mustHaveValue (boolean)
:如果标签必须具有值(例如@name TheName
中的TheName
),则设置为true
。mustNotHaveDescription (boolean)
:如果标签可以具有值但不能具有描述(例如@tag {typeExpr} TheDescription
中的TheDescription
),则设置为true
。mustNotHaveValue (boolean)
:如果标签不能具有值,则设置为true
。onTagged (function)
:找到标签时执行的回调函数。该函数传递两个参数:doclet 和标签对象。
lookUp(tagName)
:按名称检索标签对象。返回标签对象(包括其选项),如果未定义标签,则返回false
。isNamespace(tagName)
:如果将标签作为命名空间应用于 doclet 的 longname,则返回true
。normalise(tagName)
:返回标签的规范名称。例如,@const
标签是@constant
的同义词;因此,如果你调用normalise('const')
,它会返回字符串constant
。normalize(tagName)
:normalise
的同义词。在 JSDoc 3.3.0 及更高版本中可用。
标签的 onTagged
回调可以修改 doclet 或标签的内容。
defineTag
方法返回一个 Tag
对象,该对象具有一个 synonym
方法,可用于声明标签的同义词。
节点访问器
在最低级别,插件作者可以通过定义将访问每个节点的节点访问器来处理抽象语法树 (AST) 中的每个节点。通过使用节点访问器插件,你可以修改注释并为任何任意代码片段触发解析器事件。
插件可以通过导出包含 visitNode
函数的 astNodeVisitor
对象来定义节点访问器,如下所示
该函数使用以下参数调用每个节点
node
:AST 节点。AST 节点是使用 ESTree 规范 定义的格式的 JavaScript 对象。你可以使用 AST Explorer 查看将为你的源代码创建的 AST。从 3.5.0 版本开始,JSDoc 使用启用了所有插件的 Babylon 解析器的当前版本。e
:事件。如果节点是解析器处理的节点,则事件对象将已填充与上面symbolFound
事件中描述的相同内容。否则,它将是一个空对象,用于设置各种属性。parser
:JSDoc 解析器实例。currentSourceName
:正在解析的文件的名称。
实现
实现节点访问器的主要原因是能够记录通常不会记录的内容(例如创建类的函数调用)或为未记录的代码自动生成文档。例如,插件可能会查找对 _trigger
方法的调用,因为它知道这意味着触发了一个事件,然后为该事件生成文档。
要实现,visitNode
函数应修改事件参数的属性。通常目标是构造注释,然后触发事件。在解析器让所有节点访问器查看节点后,它会查看事件对象是否具有 comment
属性和 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 的未来版本中删除。