VuePress TemplateVuePress Template
指南
参考
GitHub
GitHub
指南
参考
GitHub
GitHub
  • 参考

    • 参考
    • 插件一览
    • 如何编写 VuePress 插件

如何编写 VuePress 插件

VuePress 2 的插件本质上是一个返回插件对象的函数。本页通过示例讲解插件的常见写法与生命周期钩子,帮助你在模板基础上扩展自己的功能。

本模板的所有插件都在 .vuepress/configs/plugins.ts 中集中注册。写好插件后,在该文件的 getPlugins() 数组里加一行即可。

1. 插件的基本形态

一个插件就是一个函数,接收 options 与 app,返回一个插件对象:

import type { Plugin } from 'vuepress/core'

export interface MyPluginOptions {
  foo?: string
}

// 推荐用 definePlugin 获得更好的类型提示
import { definePlugin } from 'vuepress/core'

export default definePlugin<MyPluginOptions>((options = {}, app) => {
  return {
    name: 'vuepress-plugin-my',

    // 插件逻辑写在下面这些钩子里
  }
})
  • name:插件名(建议以 vuepress-plugin- 或 @org/vuepress-plugin- 开头)。
  • multiple:是否允许同时注册多次(默认 false)。
  • 其余字段都是可选的钩子,按需使用。

2. 常用钩子一览

钩子触发时机典型用途
extendsMarkdown(md)Markdown 解析器初始化时扩展 Markdown 语法(自定义规则、容器)
extendsPageData(page)每篇页面数据生成时给页面附加自定义数据(如阅读时长)
onPrepared(app)站点数据准备完成后写入临时文件、修改 head
onGenerated(app)整个站点渲染完成后后处理 dist/ 产物、生成额外文件
alias打包解析阶段覆盖/替换某个组件路径
define打包解析阶段向客户端注入全局常量
clientConfigFile客户端初始化注册全局组件、全局 UI、路由钩子
globalUIComponents客户端初始化注册全局 UI 组件(如悬浮按钮)
extendsBundlerOptions打包器配置阶段修改 Vite 配置、排除依赖

3. 示例一:给每页附加「阅读时长」

利用 extendsPageData 给每篇页面计算阅读时长,结果会出现在 page.data.readingTime:

import { definePlugin } from 'vuepress/core'

interface ReadingTimeOptions {
  wordsPerMinute?: number
}

export const readingTimePlugin = definePlugin<ReadingTimeOptions>((options = {}, app) => {
  const wpm = options.wordsPerMinute ?? 200

  return {
    name: 'vuepress-plugin-reading-time',

    extendsPageData(page) {
      const words = page.content.split(/\s+/).filter(Boolean).length
      const minutes = Math.max(1, Math.ceil(words / wpm))
      return { readingTime: { words, minutes } }
    },
  }
})

在 Markdown 或组件中即可读取:

<template>
  <span>预计阅读 {{ $frontmatter.readingTime?.minutes }} 分钟</span>
</template>

4. 示例二:注入客户端全局组件 + UI

通过 clientConfigFile 注册一个全局组件,并用 globalUIComponents 把它挂为全局 UI:

// my-plugin/index.ts
import { getDirname, path } from 'vuepress/utils'
import { definePlugin } from 'vuepress/core'
import type { Plugin } from 'vuepress/core'

const __dirname = getDirname(import.meta.url)

export const myUiPlugin = definePlugin((options = {}, app): Plugin => ({
  name: 'vuepress-plugin-my-ui',

  // 向客户端注入配置常量(客户端代码可直接引用 __MY_OPTION__)
  define: {
    __MY_OPTION__: options,
  },

  // 客户端增强文件
  clientConfigFile: path.resolve(__dirname, './client.js'),

  // 注册为全局 UI 组件(始终渲染,如回到顶部按钮、公告栏)
  globalUIComponents: ['MyGlobalComp'],
}))
// my-plugin/client.js
import { defineClientConfig } from 'vuepress/client'
import MyComp from './components/MyGlobalComp.vue'

export default defineClientConfig({
  enhance({ app }) {
    // 注册为可复用的全局组件
    app.component('MyComp', MyComp)
  },
  // 作为全局 UI 挂载(与上面的 globalUIComponents 二选一即可)
  rootComponents: [MyComp],
})

5. 示例三:扩展 Markdown 语法

extendsMarkdown 可以拿到 markdown-it 实例,自定义渲染规则:

import { definePlugin } from 'vuepress/core'

export const upperStrongPlugin = definePlugin((options, app) => ({
  name: 'vuepress-plugin-upper-strong',

  extendsMarkdown(md) {
    // 让 **加粗** 渲染为带 class 的 <strong>
    md.renderer.rules.strong_open = (tokens, idx, options, env, self) =>
      self.renderToken(tokens, idx, options).replace('<strong>', '<strong class="custom-strong">')
  },
}))

6. 示例四:生成额外产物(onGenerated)

站点渲染完成后,可以在 dist/ 里生成额外文件,例如写入一份构建信息:

import { definePlugin } from 'vuepress/core'

export const buildInfoPlugin = definePlugin((options, app) => ({
  name: 'vuepress-plugin-build-info',

  async onGenerated(app) {
    const fs = await import('node:fs/promises')
    const outDir = app.dir.dest()
    const info = {
      pages: app.pages.length,
      base: app.siteData.base,
      generatedAt: new Date().toISOString(),
    }
    await fs.writeFile(path.resolve(outDir, 'build-info.json'), JSON.stringify(info, null, 2))
  },
}))

7. 在模板里注册你的插件

把你写好的插件放进项目(例如 .vuepress/plugins/my-plugin.ts),然后在 .vuepress/configs/plugins.ts 引入并加入数组:

import { myUiPlugin } from '../plugins/my-plugin'

export const getPlugins = (isProd: boolean): unknown[] => {
  return [
    // ……已有插件
    myUiPlugin({/* options */}),
  ].filter(Boolean)
}

参考

  • VuePress 官方:插件开发指南
  • VuePress 官方:插件 API 参考
  • markdown-it 文档(extendsMarkdown 底层)
在 GitHub 上编辑此页
最后更新于: 2026/7/18 15:46
文档贡献者: chenzw, WorkBuddy
Prev
插件一览

该应用可以安装在你的 PC 或移动设备上。这将使该 Web 应用程序外观和行为与其他应用程序相同。它将在出现在应用程序列表中,并可以固定到主屏幕,开始菜单或任务栏。此 Web 应用程序还将能够与其他应用程序和你的操作系统安全地进行交互。

详情