Location>code7788 >text

Notes on the Development of the Announcement Plugin for VitePress

Popularity:203 ℃/2024-09-21 18:23:23

preamble

Maintained by the authorVitePress Blog ThemeIt has been integrated with many functions for more than 1 year, and many users would like to separate some of the functions in it, so that they can be used independently in other VitePress sites as well.

The first of these component types to be separated is the much vauntedAnnouncement Plugin

The final result is as follows:

Next will introduce the usage, explain the principle of implementation, provide a plug-in template for you to quickly develop the same type of plug-ins.

How to use

Only 2 steps are required:

  1. Installation of plug-ins

pnpm/npm/yarn Both can be used, the author preferspnpm

pnpm add vitepress-plugin-announcement
  1. Configuring Plug-ins

Introducing plug-ins in the.vitepress/ In the VitePress configuration file

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

export default defineConfig({
  vite: {
    // ↓↓↓↓↓
    plugins: [
      AnnouncementPlugin({
        title: 'caption',
        body: [
          { type: 'text', content: 'Text content' },
          {
            type: 'image',
            src: 'photograph'
          }
        ],
        footer: [
          {
            type: 'button',
            content: 'buttons',
            link: ''
          },
        ],
      })
    ]
    // ↑↑↑↑↑
  }
})

Current SupportText/Image/Button Three types.

Implementation Principle

Here only elaborate on the key points, the detailed part will plan to split a separate article to explain (complete with plugin templates 0 - 1 implementation)

Injecting custom components

existVitePress Official Documentation Customization Board It can be understood in the

The components of the VitePress entry are in the.vitepress/theme/index derived from Component.

Meanwhile, the Layout of the default VitePress theme already provides a lot ofSlots that can be used directlySo, we can just drop the component into these locations.

VitePress is driven by Vite, so following theVite Plug-inJust expand on the ideas.

Here the plugin is utilized with thetransform hook Go ahead and deal with it.

const pluginOps = {
  name: 'vitepress-plugin-announcement',
  transform(code, id) {
    // Specific processing logic
  }
}

Insert our component into theThe default theme of the Just go inside.

The desired inserted code is as follows

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

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

The following is the specific processing logic, simple string replacement to insert the content we need can be

const pluginOps = {
  name: 'vitepress-plugin-announcement',
  enforce: 'pre',
  transform(code, id) {
    // shortlist Layout file
    if (('vitepress/dist/client/theme-default/')) {
      // Insert custom component calling code
      const slotPosition = '<slot name="layout-top" />'
      let transformResult = (slotPosition, `${slotPosition}<Announcement/>`)

      // Import Custom Component Import Code
      const setupPosition = '<script setup lang="ts">'
      transformResult = (setupPosition, `${setupPosition}\nimport Announcement from './'`)
      return transformResult
    }
  }
}

At the same time, through theenforce Parameters control the order of plug-ins, which here need to be executed as early as possible to handle the source code.

The next step is to deal withimport of the import, if left unprocessed. If you can't find those components in the program, you're bound to get an error.

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

So here, reusing theconfig hookIncoming configure Ready to go.

// Construct the path to the actual components in the plugin
const aliasComponentFile = `${getDirname()}/components/`

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

At this point the injection of custom components is complete, the next step is to introduce how to pass external parameters into the component.

Plugin Configuration Passing

There are a variety of ways, the author here to use the smallest changes, the use of a more extensive onevirtual module

The official example already describes how to use it, so I won't repeat it here.

Importing configuration code in a component

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

Virtual module logic is handled in the plugin.

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) {
        // virtual module processing (VMP)
        return `export default ${stringify(options)}`
      }
    },
  }
  return pluginOps
}

Tips: Since we don't handle functions by default, we'll be lazy and use the community library here.javascript-stringify Processing.

If you want to use processing, you need to pass in a secondreplacer parameter to do something special with the function.

At this point, the two key steps are done, the rest of the work is the specific components of the style and interaction to achieve the development, according to the conventional Vue component development can be.

Plug-in Template Introduction

In the process of developing plug-ins, I separated such plug-ins based on slot location injection into a templatevitepress-plugin-slot-inject-template

directory structure

├── scripts # Build related scripts, no need to change them if you don't have special needs.
| scripts # Build related scripts, no special needs can not be modified.
| ├── scripts # Build related scripts, you don't need to change them if you don't have any special needs.
src
| ├── components # Component implementation
| ├── # Plugin entries
| ├── # Plugin configuration parameter type definitions
| └── # Tool functions used by the plugin
├──
├──
└──

References part of the implementation in the VitePress default theme.

Procedure for use

  1. Plugin Portalsrc/, change the plugin& component naming information and component insertion location.
  2. Write component implementations according to actual requirements.
  3. Just release the npm package after completing the documentation.

ultimate

The style implementation references the thematic hit the nail on the head@vuepress-reco/vuepress-plugin-bulletin-popover plug-in (software component)

Follow-up continues in accordance withvitepress plugin development program Advancement, organizing the content of the development process into tutorials and plugin templates.

Full source code of the pluginvitepress-plugin-announcement