TypeDoc 插件扩展 #
插件系统概述 #
TypeDoc 拥有强大的插件系统,允许开发者扩展和定制文档生成功能。
text
┌─────────────────────────────────────────────────────────────┐
│ TypeDoc 插件架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ TypeDoc Core │ │
│ └───────────────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Plugin Manager │ │
│ └───────────────────────┬─────────────────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 输出插件 │ │ 主题插件 │ │ 解析插件 │ │
│ │ Markdown │ │ Hierarchy │ │ External │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
常用插件介绍 #
typedoc-plugin-markdown #
将文档输出为 Markdown 格式:
bash
npm install --save-dev typedoc-plugin-markdown
配置:
json
{
"plugin": ["typedoc-plugin-markdown"],
"theme": "markdown",
"out": "docs/markdown"
}
高级配置:
json
{
"plugin": ["typedoc-plugin-markdown"],
"theme": "markdown",
"out": "docs/markdown",
"entryDocument": "README.md",
"hideInPageTOC": true,
"hideBreadcrumbs": true,
"hidePageHeader": false,
"indexFormat": "table",
"memberFormat": "list",
"textContentMappings": {
"title.indexPage": "API Reference",
"header.readme": "Getting Started"
}
}
typedoc-theme-hierarchy #
层级结构主题:
bash
npm install --save-dev typedoc-theme-hierarchy
配置:
json
{
"plugin": ["typedoc-theme-hierarchy"],
"theme": "hierarchy"
}
typedoc-plugin-merge-modules #
合并模块输出:
bash
npm install --save-dev typedoc-plugin-merge-modules
配置:
json
{
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "module"
}
typedoc-plugin-external-module-name #
自定义模块名称:
bash
npm install --save-dev typedoc-plugin-external-module-name
配置:
json
{
"plugin": ["typedoc-plugin-external-module-name"],
"externalModulemap": ".*\\/src\\/([^\\/]+)\\/.*"
}
typedoc-plugin-pages #
添加自定义页面:
bash
npm install --save-dev typedoc-plugin-pages
配置:
json
{
"plugin": ["typedoc-plugin-pages"],
"pages": [
{
"title": "Getting Started",
"source": "./docs/getting-started.md"
},
{
"title": "Guide",
"source": "./docs/guide.md",
"children": [
{
"title": "Installation",
"source": "./docs/installation.md"
},
{
"title": "Configuration",
"source": "./docs/configuration.md"
}
]
}
]
}
typedoc-plugin-coverage #
生成文档覆盖率报告:
bash
npm install --save-dev typedoc-plugin-coverage
配置:
json
{
"plugin": ["typedoc-plugin-coverage"],
"coverageOutput": "coverage.json"
}
typedoc-plugin-rename-defaults #
重命名默认导出:
bash
npm install --save-dev typedoc-plugin-rename-defaults
配置:
json
{
"plugin": ["typedoc-plugin-rename-defaults"]
}
typedoc-plugin-reference-excluder #
排除特定引用:
bash
npm install --save-dev typedoc-plugin-reference-excluder
配置:
json
{
"plugin": ["typedoc-plugin-reference-excluder"],
"excludeReferences": ["React", "Vue"]
}
插件配置方法 #
命令行配置 #
bash
npx typedoc --plugin typedoc-plugin-markdown --theme markdown
配置文件 #
json
// typedoc.json
{
"plugin": [
"typedoc-plugin-markdown",
"typedoc-plugin-coverage"
],
"theme": "markdown"
}
多插件配置 #
json
{
"plugin": [
"typedoc-plugin-markdown",
"typedoc-plugin-pages",
"typedoc-plugin-coverage"
],
"theme": "markdown",
"pages": [
{
"title": "Guide",
"source": "./docs/guide.md"
}
],
"coverageOutput": "coverage.json"
}
禁用插件 #
json
{
"plugin": []
}
开发自定义插件 #
插件项目结构 #
text
my-typedoc-plugin/
├── src/
│ ├── index.ts # 插件入口
│ ├── plugin.ts # 插件逻辑
│ └── types.ts # 类型定义
├── package.json
├── tsconfig.json
└── README.md
基本插件模板 #
typescript
// src/index.ts
import { Application } from 'typedoc';
import { MyPlugin } from './plugin';
export function load(app: Application) {
new MyPlugin(app);
}
export { MyPlugin };
插件类实现 #
typescript
// src/plugin.ts
import {
Application,
Context,
Converter,
Reflection,
ReflectionKind,
DeclarationReflection
} from 'typedoc';
export class MyPlugin {
private app: Application;
constructor(app: Application) {
this.app = app;
this.initialize();
}
private initialize() {
// 监听转换事件
this.app.converter.on(
Converter.EVENT_CREATE_DECLARATION,
this.onDeclaration.bind(this)
);
// 监听解析完成事件
this.app.converter.on(
Converter.EVENT_RESOLVE_END,
this.onResolveEnd.bind(this)
);
}
private onDeclaration(context: Context, reflection: DeclarationReflection) {
// 处理声明
if (reflection.kind === ReflectionKind.Function) {
this.processFunction(reflection);
}
}
private onResolveEnd(context: Context) {
// 解析完成后的处理
console.log('Documentation resolved');
}
private processFunction(reflection: DeclarationReflection) {
// 自定义处理逻辑
reflection.comment?.addTag('custom', 'processed');
}
}
添加配置选项 #
typescript
// src/plugin.ts
import {
Application,
BindOption,
DeclarationOption,
StringDeclarationOption
} from 'typedoc';
const myOption: StringDeclarationOption = {
name: 'myCustomOption',
type: DeclarationOption.String,
defaultValue: 'default-value',
help: 'A custom option for my plugin'
};
export class MyPlugin {
@BindOption('myCustomOption')
private myCustomOption!: string;
constructor(app: Application) {
// 注册选项
app.options.addDeclaration(myOption);
}
private useOption() {
console.log('Custom option value:', this.myCustomOption);
}
}
修改反射对象 #
typescript
// src/plugin.ts
import {
Application,
Context,
Converter,
DeclarationReflection,
ReflectionKind,
ReflectionFlag
} from 'typedoc';
export class MyPlugin {
constructor(app: Application) {
app.converter.on(
Converter.EVENT_CREATE_DECLARATION,
this.modifyReflection.bind(this)
);
}
private modifyReflection(
context: Context,
reflection: DeclarationReflection
) {
// 添加自定义标志
if (reflection.name.startsWith('_')) {
reflection.setFlag(ReflectionFlag.Internal);
}
// 修改注释
if (reflection.comment) {
reflection.comment.summary.push({
kind: 'text',
text: '\n\n*Added by custom plugin*'
});
}
// 添加自定义标签
reflection.comment?.addTag('custom', 'value');
}
}
添加自定义渲染 #
typescript
// src/plugin.ts
import {
Application,
Renderer,
Theme,
PageEvent,
Reflection
} from 'typedoc';
export class MyPlugin {
constructor(app: Application) {
// 监听渲染事件
app.renderer.on(
PageEvent.BEGIN,
this.onPageBegin.bind(this)
);
app.renderer.on(
PageEvent.END,
this.onPageEnd.bind(this)
);
}
private onPageBegin(page: PageEvent<Reflection>) {
// 页面渲染前
console.log('Rendering page:', page.url);
}
private onPageEnd(page: PageEvent<Reflection>) {
// 页面渲染后,修改 HTML
if (page.contents) {
page.contents = this.modifyHtml(page.contents);
}
}
private modifyHtml(html: string): string {
// 添加自定义脚本
const customScript = `
<script>
console.log('Custom plugin loaded');
</script>
`;
return html.replace('</body>', `${customScript}</body>`);
}
}
完整插件示例 #
typescript
// src/index.ts
import {
Application,
Context,
Converter,
DeclarationReflection,
ReflectionKind,
ReflectionFlag,
Renderer,
PageEvent,
Reflection,
BindOption,
DeclarationOption,
BooleanDeclarationOption
} from 'typedoc';
// 定义选项
const addInternalTag: BooleanDeclarationOption = {
name: 'markPrivateAsInternal',
type: DeclarationOption.Boolean,
defaultValue: false,
help: 'Mark private members as @internal'
};
class AutoInternalPlugin {
@BindOption('markPrivateAsInternal')
private markPrivateAsInternal!: boolean;
constructor(private app: Application) {
// 注册选项
this.app.options.addDeclaration(addInternalTag);
// 注册事件监听
this.registerEventListeners();
}
private registerEventListeners() {
// 转换阶段
this.app.converter.on(
Converter.EVENT_CREATE_DECLARATION,
this.onDeclaration.bind(this)
);
// 渲染阶段
this.app.renderer.on(
PageEvent.END,
this.onPageEnd.bind(this)
);
}
private onDeclaration(
context: Context,
reflection: DeclarationReflection
) {
if (!this.markPrivateAsInternal) return;
// 将私有成员标记为内部
if (reflection.flags.hasFlag(ReflectionFlag.Private)) {
reflection.setFlag(ReflectionFlag.Private, false);
reflection.setFlag(ReflectionFlag.Internal, true);
reflection.comment?.addTag('internal', 'Auto-marked from private');
}
}
private onPageEnd(page: PageEvent<Reflection>) {
if (!page.contents) return;
// 添加生成时间戳
const timestamp = `<!-- Generated at ${new Date().toISOString()} -->`;
page.contents = page.contents.replace('</html>', `${timestamp}\n</html>`);
}
}
export function load(app: Application) {
new AutoInternalPlugin(app);
}
发布插件 #
json
// package.json
{
"name": "typedoc-plugin-auto-internal",
"version": "1.0.0",
"description": "Automatically mark private members as internal",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"keywords": [
"typedoc",
"plugin",
"typedoc-plugin"
],
"peerDependencies": {
"typedoc": ">=0.25.0"
},
"devDependencies": {
"typedoc": "^0.25.0",
"typescript": "^5.0.0"
},
"files": [
"dist"
],
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
}
}
json
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
插件 API 参考 #
Application #
TypeDoc 应用实例:
typescript
import { Application } from 'typedoc';
// 访问配置
app.options.getValue('name');
// 访问转换器
app.converter;
// 访问渲染器
app.renderer;
Converter #
文档转换器:
typescript
import { Converter, Context } from 'typedoc';
// 事件
Converter.EVENT_BEGIN // 转换开始
Converter.EVENT_END // 转换结束
Converter.EVENT_CREATE_DECLARATION // 创建声明
Converter.EVENT_CREATE_PARAMETER // 创建参数
Converter.EVENT_CREATE_SIGNATURE // 创建签名
Converter.EVENT_RESOLVE_BEGIN // 解析开始
Converter.EVENT_RESOLVE_END // 解析结束
Renderer #
文档渲染器:
typescript
import { Renderer, PageEvent } from 'typedoc';
// 事件
Renderer.EVENT_BEGIN // 渲染开始
Renderer.EVENT_END // 渲染结束
PageEvent.BEGIN // 页面开始
PageEvent.END // 页面结束
Reflection #
反射对象类型:
typescript
import {
Reflection,
ReflectionKind,
ReflectionFlag,
DeclarationReflection,
SignatureReflection,
ParameterReflection
} from 'typedoc';
// 类型判断
if (reflection.kind === ReflectionKind.Class) {
// 处理类
}
// 标志操作
reflection.setFlag(ReflectionFlag.Internal, true);
reflection.hasFlag(ReflectionFlag.Private);
// 注释操作
reflection.comment?.addTag('custom', 'value');
插件开发最佳实践 #
1. 遵循命名规范 #
text
typedoc-plugin-{功能名称}
typedoc-theme-{主题名称}
2. 声明 peerDependencies #
json
{
"peerDependencies": {
"typedoc": ">=0.25.0"
}
}
3. 导出 load 函数 #
typescript
export function load(app: Application) {
// 插件初始化逻辑
}
4. 提供类型定义 #
typescript
// src/types.ts
export interface MyPluginOptions {
enabled: boolean;
customValue: string;
}
export type MyPluginCallback = (reflection: Reflection) => void;
5. 错误处理 #
typescript
export class MyPlugin {
private handleError(error: Error, context?: string) {
this.app.logger.error(
`[MyPlugin] ${context ? context + ': ' : ''}${error.message}`
);
}
private safeProcess(reflection: Reflection) {
try {
this.processReflection(reflection);
} catch (error) {
this.handleError(error as Error, `Processing ${reflection.name}`);
}
}
}
下一步 #
现在你已经掌握了 TypeDoc 插件的使用和开发方法,接下来学习 高级主题,了解 CI/CD 集成、性能优化等高级技巧!
最后更新:2026-03-29