關於 JSDoc 外掛程式
建立並啟用外掛程式
建立並啟用新的 JSDoc 外掛程式需要兩個步驟
- 建立一個 JavaScript 模組來包含外掛程式程式碼。
- 在 JSDoc 設定檔 的
plugins
陣列中包含該模組。您可以指定絕對或相對路徑。如果您使用相對路徑,JSDoc 會依序在目前的工作目錄、設定檔所在目錄和 JSDoc 目錄中搜尋外掛程式。
例如,如果您的外掛程式定義在目前工作目錄的 plugins/shout.js
檔案中,您會將字串 plugins/shout
新增到 JSDoc 設定檔中的 plugins
陣列
{
"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
事件。您的外掛程式可以使用此事件在必要時觸發每個檔案的初始化。
事件物件包含下列屬性
檔案名稱
:檔案名稱。
事件: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
jsdocCommentFound
事件在找到 JSDoc 註解時觸發。此註解可能與程式碼相關,也可能不相關。您可以在處理註解之前使用此事件來修改註解內容。
事件物件包含下列屬性
檔案名稱
:檔案名稱。註解
:JSDoc 註解文字。行號
:找到註解的行號。欄位號
:找到註解的欄位號。在 JSDoc 3.5.0 及後續版本中提供。
事件:symbolFound
當剖析器在程式碼中遇到可能需要記錄的符號時,會觸發 symbolFound
事件。例如,剖析器會為原始檔中的每個變數、函式和物件文字觸發 symbolFound
事件。
事件物件包含下列屬性
檔案名稱
:檔案名稱。註解
:與符號相關的註解文字(如果有的話)。識別碼
:符號的唯一識別碼。行號
:找到符號的行號。欄位號
:找到符號的欄位號。在 JSDoc 3.5.0 及後續版本中提供。範圍
:包含與符號相關的原始檔中第一個和最後一個字元的數字索引的陣列。astnode
:符號在抽象語法樹中的節點。程式碼
:包含程式碼詳細資訊的物件。此物件通常包含名稱
、類型
和節點
屬性。此物件也可能具有值
、參數名稱
或函式範圍
屬性,具體取決於符號。
事件: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
處理常式的範例
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 及後續版本中觸發。
事件物件包含下列屬性
sourcefiles
:已解析的原始檔路徑陣列。doclets
:doclet 物件陣列。有關每個 doclet 可包含之屬性的詳細資料,請參閱newDoclet
事件。JSDoc 3.2.1 及後續版本適用。
事件:processingComplete
processingComplete
事件會在 JSDoc 更新剖析結果以反映繼承和借用符號後觸發。
注意:此事件會在 JSDoc 3.2.1 及後續版本中觸發。
事件物件包含下列屬性
doclets
:doclet 物件陣列。有關每個 doclet 可包含之屬性的詳細資料,請參閱newDoclet
事件。
標籤定義
將標籤新增至標籤字典是影響文件產生中階的方式。在觸發 newDoclet
事件之前,會剖析 JSDoc 註解區塊以確定說明和可能存在的任何 JSDoc 標籤。當找到標籤時,如果已在標籤字典中定義,則會讓它修改 doclet。
外掛程式可以透過匯出 defineTags
函數來定義標籤。該函數會傳遞一個可用於定義標籤的字典,如下所示
exports.defineTags = function(dictionary) {
// define tags here
};
字典
字典提供下列方法
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)
:如果標籤套用在文件說明的 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
方法會傳回一個 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
}
};
函式會呼叫每個節點,並帶有以下參數
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 的未來版本中移除。
var logger = require('jsdoc/util/logger');
exports.handlers = {
newDoclet: function(e) {
// Your code here.
if (somethingBadHappened) {
logger.error('Oh, no, something bad happened!');
}
}
};