@use JSDoc

关于 JSDoc 插件

创建和启用插件

创建并启用新的 JSDoc 插件需要两个步骤

  1. 创建一个 JavaScript 模块来包含插件代码。
  2. 将该模块包含在 JSDoc 配置文件plugins 数组中。您可以指定绝对或相对路径。如果您使用相对路径,JSDoc 将按以下顺序在当前工作目录、配置文件所在目录和 JSDoc 目录中搜索插件。

例如,如果您的插件在当前工作目录中的 plugins/shout.js 文件中定义,则需要将字符串 plugins/shout 添加到 JSDoc 配置文件中的 plugins 数组中

将插件添加到 JSDoc 配置文件
{
    "plugins": ["plugins/shout"]
}

JSDoc 按在配置文件中列出的顺序执行插件。

编写 JSDoc 3 插件

JSDoc 3 的插件系统提供对解析过程的广泛控制。插件可以通过执行以下任何操作来影响解析结果

事件处理程序

在最高级别,插件可以为 JSDoc 引发的特定命名事件注册处理程序。JSDoc 会将事件对象传递给处理程序。您的插件模块应导出一个包含处理程序的 handlers 对象,如下所示

“newDoclet”事件的事件处理程序插件
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 及更高版本中触发。

事件对象包含以下属性

事件:fileBegin

当解析器准备解析文件时,将触发 fileBegin 事件。如果需要,您的插件可以使用此事件触发按文件进行初始化。

事件对象包含以下属性

事件:beforeParse

beforeParse 事件在开始解析之前触发。插件可以使用此方法来修改将要解析的源代码。例如,您的插件可以添加 JSDoc 注释,也可以删除无效 JavaScript 的预处理标签。

事件对象包含以下属性

以下示例为源代码添加了一个函数的虚拟注释,以便解析该注释并将其添加到文档中。这可能是为了记录对用户可用的方法,但可能不会出现在要记录的源代码中,例如外部超类提供的方法

示例
exports.handlers = {
    beforeParse: function(e) {
        var extraDoc = [
            '/**',
            ' * Function provided by a superclass.',
            ' * @name superFunc',
            ' * @memberof ui.mywidget',
            ' * @function',
            ' */'
        ];
        e.source += extraDoc.join('\n');
    }
};

事件:jsdocCommentFound

每当找到 JSDoc 注释时,都会触发 jsdocCommentFound 事件。该注释可能与代码相关,也可能不相关。您可以在处理注释之前使用此事件来修改注释的内容。

事件对象包含以下属性

事件:symbolFound

当解析器在代码中遇到可能需要记录的符号时,将触发 symbolFound 事件。例如,解析器会为源文件中的每个变量、函数和对象字面量触发一个 symbolFound 事件。

事件对象包含以下属性

事件:newDoclet

newDoclet 事件是最高级别的事件。当创建新文档时触发此事件。这意味着已处理 JSDoc 注释或符号,并且已创建将传递给模板的实际文档。

事件对象包含以下属性

文档的属性可能因文档表示的注释或符号而异。您可能会看到的一些常见属性包括

要查看 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 事件。您的插件可以使用此事件触发每个文件的清理。

事件对象包含以下属性

事件:parseComplete

在 JSDoc 解析所有指定的源文件后,将触发 parseComplete 事件。

注意:此事件在 JSDoc 3.2 及更高版本中触发。

事件对象包含以下属性

事件:processingComplete

在 JSDoc 更新解析结果以反映继承和借用的符号后,将触发 processingComplete 事件。

注意:此事件在 JSDoc 3.2.1 及更高版本中触发。

事件对象包含以下属性

标签定义

向标签词典中添加标签是影响文档生成的中级方法。在触发 newDoclet 事件之前,将解析 JSDoc 注释块以确定描述和可能存在的任何 JSDoc 标签。当找到标签时,如果已在标签词典中定义该标签,则会给它一个修改 doclet 的机会。

插件可以通过导出 defineTags 函数来定义标签。该函数将传递一个词典,该词典可用于定义标签,如下所示

示例
exports.defineTags = function(dictionary) {
    // define tags here
};

词典

词典提供以下方法

标签的 onTagged 回调可以修改 doclet 或标签的内容。

定义 onTagged 回调
dictionary.defineTag('instance', {
    onTagged: function(doclet, tag) {
        doclet.scope = "instance";
    }
});

defineTag 方法返回一个 Tag 对象,该对象具有一个 synonym 方法,可用于声明标签的同义词。

定义标签同义词
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
    }
};

该函数使用以下参数调用每个节点

实现

实现节点访问器的主要原因是能够记录通常不会记录的内容(例如创建类的函数调用)或为未记录的代码自动生成文档。例如,插件可能会查找对 _trigger 方法的调用,因为它知道这意味着触发了一个事件,然后为该事件生成文档。

要实现,visitNode 函数应修改事件参数的属性。通常目标是构造注释,然后触发事件。在解析器让所有节点访问器查看节点后,它会查看事件对象是否具有 comment 属性和 event 属性。如果它同时具有这两个属性,则会触发事件属性中命名的事件。该事件通常是 symbolFoundjsdocCommentFound,但从理论上讲,插件可以定义自己的事件并处理它们。

与事件处理程序插件一样,节点访问器插件可以通过在事件对象上设置 stopPropagation 属性(e.stopPropagation = true)来阻止后续插件运行。插件可以通过设置 preventDefault 属性(e.preventDefault = true)来阻止事件触发。

报告错误

如果插件需要报告错误,请使用 jsdoc/util/logger 模块中的以下方法之一

使用这些方法可以创建比简单抛出错误更好的用户体验。

注意:不要使用 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!');
        }
    }
};