JSDoc 中文网

关于 JSDoc 插件

创建并启用插件

🌐 Creating and Enabling a Plugin

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

🌐 There are two steps required to create and enable a new JSDoc plugin:

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

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

🌐 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:

向 JSDoc 的配置文件添加插件
{
    "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:

事件处理程序

🌐 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:

'newDoclet' 事件的事件处理插件
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).

事件:解析开始

🌐 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 及更高版本中触发。

事件对象包含以下属性:

🌐 The event object contains the following properties:

事件:文件开始

🌐 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:

事件: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:

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

🌐 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');
    }
};

事件:发现 jsdoc 注释

🌐 Event: jsdocCommentFound

jsdocCommentFound 事件在每次发现 JSDoc 注释时触发。该注释可能与任何代码相关,也可能无关。你可以使用此事件在注释被处理之前修改其内容。

🌐 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:

事件:符号已找到

🌐 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:

事件:newDoclet

🌐 Event: newDoclet

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

🌐 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 所代表的注释或符号而有所不同。一些你可能会看到的常见属性包括:

🌐 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:

要查看 JSDoc 为你的代码生成的文档片段,请使用 -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();
        }
    }
};

事件:文件完成

🌐 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:

事件:解析完成

🌐 Event: parseComplete

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

🌐 The parseComplete event is fired after JSDoc has parsed all of the specified source files.

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

事件对象包含以下属性:

🌐 The event object contains the following properties:

事件:处理完成

🌐 Event: processingComplete

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

🌐 The processingComplete event is fired after JSDoc updates the parse results to reflect inherited and borrowed symbols.

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

事件对象包含以下属性:

🌐 The event object contains the following properties:

标签定义

🌐 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:

标签的 onTagged 回调可以修改文档对象或标签的内容。

🌐 A tag's onTagged callback can modify the contents of the doclet or tag.

定义 onTagged 回调
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:

让事情发生

🌐 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 属性。如果两者都有,就会触发事件属性中命名的事件。这个事件通常是 symbolFoundjsdocCommentFound,但理论上,插件可以定义自己的事件并处理它们。

🌐 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:

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

🌐 Using these methods creates a better user experience than simply throwing an error.

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