首页 > 其他分享 >适用于 VitePress 的公告插件开发实记

适用于 VitePress 的公告插件开发实记

时间:2024-09-21 18:12:16浏览次数:7  
标签:插件 vue const VitePress 实记 vitepress 组件

前言

笔者维护的 VitePress 博客主题在近1年多的时间里集成了非常多功能,不少用户希望将里面的部分功能分离出来,方便在其它 VitePress 站点也可以独立使用。

其中分离的第一个组件类型的就是呼声较高的 公告插件

最终效果如下:

接下来将介绍一下用法,讲解一下实现原理,提供一个插件模板供大家快速开发同类型插件。

如何使用

只需要 2 步:

  1. 安装插件

pnpm/npm/yarn 均可,笔者比较偏好 pnpm

pnpm add vitepress-plugin-announcement
  1. 配置插件

引入插件在 .vitepress/config.ts VitePress 配置文件中

import { defineConfig } from 'vitepress'
import { AnnouncementPlugin } from 'vitepress-plugin-announcement'

export default defineConfig({
  vite: {
    // ↓↓↓↓↓
    plugins: [
      AnnouncementPlugin({
        title: '标题',
        body: [
          { type: 'text', content: '文本内容' },
          {
            type: 'image',
            src: '图片'
          }
        ],
        footer: [
          {
            type: 'button',
            content: '按钮',
            link: 'https://sugarat.top'
          },
        ],
      })
    ]
    // ↑↑↑↑↑
  }
})

目前支持 文本/图片/按钮 三种类型。

实现原理

这里只阐述关键点,详细部分将计划单独拆一篇文章进行讲解(完整的搭配插件模板 0 - 1 实现)

注入自定义组件

VitePress 官方文档自定义板块 中可以了解到,

VitePress 入口的组件是在 .vitepress/theme/index 中导出的 Layout.vue 组件。

同时 VitePress 默认主题的 Layout 已经提供了许多可以直接使用的插槽,于是乎,咱们可以把组件直接放入这些位置即可。

VitePress 是由 Vite 驱动,所以按照 Vite 插件的思路去拓展即可。

这里利用插件的 transform 钩子 去处理。

const pluginOps = {
  name: 'vitepress-plugin-announcement',
  transform(code, id) {
    // 具体处理逻辑
  }
}

将我们的组件插入到默认主题的 Layout.vue 里即可。

期望插入后的代码如下

<script setup lang="ts">
import Announcement from './Announcement.vue' // [!code ++]
</script>

<template>
  <div>
    <slot name="layout-top" />
    <Announcement /> // [!code ++]
  </div>
</template>

下面是具体的处理逻辑,简单字符串替换插入我们需要的内容即可

const pluginOps = {
  name: 'vitepress-plugin-announcement',
  enforce: 'pre',
  transform(code, id) {
    // 筛选出 Layout 文件
    if (id.endsWith('vitepress/dist/client/theme-default/Layout.vue')) {
      // 插入自定义组件调用代码
      const slotPosition = '<slot name="layout-top" />'
      let transformResult = code.replace(slotPosition, `${slotPosition}<Announcement/>`)

      // 导入自定义组件导入代码
      const setupPosition = '<script setup lang="ts">'
      transformResult = transformResult.replace(setupPosition, `${setupPosition}\nimport Announcement from './Announcement.vue'`)
      return transformResult
    }
  }
}

同时通过 enforce 参数控制插件顺序,这里需要尽可能的提前执行,处理源代码。

接下来就是处理 import 的导入,如果不做处理,Layout.vue 里是找不到这些组件,就一定会报错。

import Announcement from './Announcement.vue' // [!code ++]

于是这里,再利用 config 钩子,传入 resolve.alias 配置 即可。

// 构造插件里实际组件的路径
const aliasComponentFile = `${getDirname()}/components/Announcement.vue`

const pluginOps = {
  config() {
    return {
      resolve: {
        alias: {
          './Announcement.vue': aliasComponentFile
        }
      }
    }
  }
}

至此自定义组件的注入就算是完成了,接下来介绍如何将外部的参数传入到组件里。

插件配置传递

方式有很多种,笔者这里采用改动最小,使用较为广泛的一种 虚拟模块

官方示例里已经介绍了如何使用,这里不做赘述。

组件中导入配置代码

<script lang="ts" setup>
import announcementOptions from 'virtual:announcement-options'
</script>

插件中处理虚拟模块逻辑。

import { stringify } from 'javascript-stringify'

function AnnouncementPlugin(options) {
  const virtualModuleId = 'virtual:announcement-options'
  const resolvedVirtualModuleId = `\0${virtualModuleId}`

  const pluginOps = {
    name: 'vitepress-plugin-announcement',
    enforce: 'pre',
    resolveId(id) {
      if (id === virtualModuleId) {
        return resolvedVirtualModuleId
      }
    },
    load(this, id) {
      if (id === resolvedVirtualModuleId) {
        // 虚拟模块处理
        return `export default ${stringify(options)}`
      }
    },
  }
  return pluginOps
}

tips:由于 JSON.stringify 默认不会处理函数,这里就偷懒用一下社区的库 javascript-stringify 进行处理。

如果要用 JSON.stringify 处理,需要传入第二个 replacer 参数,对函数做特殊处理。

至此,关键的两步就算搞定了,剩余的工作就是具体组件的样式和交互实现开发了,按常规 Vue 组件开发即可。

插件模板介绍

在开发插件的过程中,笔者把此类基于 slot 位置注入的插件分离了一个模板 vitepress-plugin-slot-inject-template

目录结构

├── scripts # 构建相关脚本,无特殊需求可以不用修改
|  ├── copyComponents.mjs
|  └── watchAndCopy.mjs
├── src
|  ├── components # 组件实现
|  ├── index.ts # 插件入口
|  ├── type.ts # 插件配置参数类型定义
|  └── util.ts # 插件使用的工具函数
├── README.md
├── package.json
└── tsconfig.json

参考了 VitePress 默认主题中部分实现。

使用步骤

  1. 插件入口 src/index.ts,修改一下插件&组件命名信息和组件插入位置。
  2. 按照实际需求编写组件实现。
  3. 完善 README.md 使用文档后发布 npm 包即可。

最后

样式实现参考了 reco-1.x 主题 中的 @vuepress-reco/vuepress-plugin-bulletin-popover 插件

后续继续按照 vitepress 插件开发计划 推进,将开发过程内容整理成教程与插件模板。

插件完整源码 vitepress-plugin-announcement

标签:插件,vue,const,VitePress,实记,vitepress,组件
From: https://www.cnblogs.com/roseAT/p/18424345

相关文章

  • 使用`xlsx-js-style`插件导出表格,并添加样式导出
    安装npminstallxlsx-js-style--save使用引入importXLSXfrom'xlsx-js-style'//1.创建一个工作簿constwb=XLSX.utils.book_new()//表格标题//这里设置标题是怕数据没有,返回空表,连标题都没有//这里的权重,没有数据tableData里的高,果如ta......
  • 视频号直播自动循环发评论-自动回复评论 - 浏览器插件
    功能介绍浏览器插件源码开放,可以随意二次开发,无时间限制,无账号限制,无电脑限制实现原理,纯浏览器插件实现,监控浏览器界面元素变动,获取直播间或者直播中控后台的评论文本,匹配回复关键词或调用AI接口,再利用js模拟输入和点击等操作支持以下中控台或直播间地址,获取评论与回复评论抖......
  • WordPress 迁移插件终极指南
    迁移WordPress网站就像收拾房子搬到新房子一样。确保所有内容(内容、主题、插件、媒体文件甚至数据库)完美移动且没有任何损坏的挑战似乎令人畏惧。但就像搬家公司让搬家变得更容易一样,WordPress迁移插件简化了将网站从一台主机移动到另一台主机的复杂过程。无论您是切换主机、从......
  • Android插件化(三)基础之Android应用程序资源的编译和打包过程分析
    Android插件化(三)基础之Android应用程序资源的编译和打包过程分析Android资源加载常规思路getResourcesForApplication//首先,通过包名获取该包名的Resources对象Resourcesres=pm.getResourcesForApplication(packageName);//根据约定好的名字,去取资源id;intid=res.......
  • AI无人直播插件常用功能的代码分享!
    在当前的AI技术浪潮中,AI无人直播插件已经成为许多商家和内容创作者提升直播效率、降低成本的得力助手。这类插件通过集成先进的AI技术,实现了直播内容的自动化生成、智能互动、数据分析等功能,以下,我将分享五个AI无人直播插件的常用功能及其简化后的代码示例。1、自动内容生成自动内......
  • Nuxt Kit 中的插件:创建与使用
    title:NuxtKit中的插件:创建与使用date:2024/9/19updated:2024/9/19author:cmdragonexcerpt:摘要:本文介绍了在Nuxt3框架中使用NuxtKit创建和管理插件的方法,包括使用addPlugin注册插件、创建插件文件、在Vue组件中使用插件,以及使用addPluginTemplate创建......
  • WordPress中最佳播客插件:入门级指南
    近年来,播客在全球范围内迅速普及,成为人们获取信息和娱乐的重要途径。对于想在WordPress网站上添加播客功能的用户来说,选择合适的插件非常重要。本文将为大家介绍几款适合用户入门级WordPress播客插件,让你轻松实现播客功能。1.PodcastPlayer简介PodcastPlayer是一款简单易用的插......
  • 解决帝国CMS插件404的10种方法,轻松修复网站错误!
    解决帝国CMS插件404错误可以通过多种方法来实现,以下是根据提供的信息整理出的十种方法,帮助你轻松修复网站错误:1.检查插件文件是否存在问题描述:插件文件可能由于某种原因丢失或未正确安装。解决方法:确认插件文件存在于帝国CMS的指定目录中。如果文件丢失,重新下载或安装插件。......
  • 从零开始开发AI无人直播插件!
    AI无人直播插件应运而生,它利用人工智能技术,实现了直播内容的自动化生成与播放,极大地降低了直播的人力成本和时间成本,本文将带你从零开始,探索如何制作一个AI无人直播插件,并分享五段关键的源代码。AI无人直播插件的核心在于利用机器学习算法对大量数据进行训练,以生成符合特定需求的直......
  • 富文本编辑器CKEDITOR支持从WORD复制粘贴保留格式和图片的插件
    编辑器:ckeditor前端:vue2,vue3.vue-cli后端:asp,jsp,php,asp.net,.netcore功能:复制粘贴word内容图片该说不说最近这个需求挻火的,今天早上又有网友加我QQ,实际上之前QQ号码就已经在网上公开了,但是还是有很多网友找不到,这个说实话就真没办法了,除了公布QQ号码以外我还公开了微信号码......