The goal of this article is to achieve vite plug-in, vUE oriented code implementation, so the code is all in the FORM of VUE API display, but no matter what framework implementation ideas are basically the same.

preface

When we’re developing a library or documentation system, we want to be able to write markdown directly as a component, and most blogs offer solutions that do two things

  1. Parse md into HTML content using Markdown’s parsing library
  2. Write a component in your business that takes the HTML text parsed in the previous step as the value of the V-HTML attribute

The problem is that the markdown component simply provides a container to insert HTML text into. You need to write it in business, and even if you bring it into the component library, you need to import it and use it.

So we want to be able to write md files and import them directly into usable components, such as:

<template>
  <Start />
</template>
<script>
import { defineComponent } from 'vue';
import Start from 'docs/start.md';
export default defineComponent({  
    name: 'App'.components: { Start },
})
</script>
Copy the code

The plug-in needs to do both of those things and output a VUE component.

implementation

Sort out your requirements

When encountering a Markdown file, the content is parsed into HTML, the API of vue rendering function is used to write the code, the HTML content is inserted, and finally the whole code is output

Parse the Markdown file

We used the marked library to parse the Markdown file, so install it first

yarn add marked
Copy the code

Vite plug-in

The use of vite plug-in and basic API can be directly read Chinese documentation, here do not do redundant, directly see the implementation.

To intercept markdown files, we use transform, which means transform. The basic structure code is as follows:

// /plugins/vite-plugin-md2vue.js

const marked = require('marked')

export default function (options) {
  return {
    name: 'vitePluginMd2Vue'.transform(src, id) {
      /** * id is the path of the imported file. * SRC is the content of the imported file
      if (id.endsWith(".md")) { // Determine the end string to determine whether it is a Markdown file
        return {
          code: ` `.// code is the final output of the converted code
          map: null // Whether to provide source map is not considered here
        }
      }
    }
  }
}
Copy the code

We need to write component code in code, but we cannot write it in the form of SFC, that is, single file component, because Vite will specifically intercept the file at the end of. Vue for parsing. If we directly export the code in THE form of SFC, we will not go through the parsing process in Vite to cause errors, so we directly write the rendering function. The code is as follows:

import {h, defineComponent} from "vue";
const _sfc_md = defineComponent({
    name: "Markdown"});const _sfc_render =() = > {
    return h("div", {
      // Marked is the parser library imported in the previous code
      // SRC is also the import content of the md file in the previous code, which is parsed into a string
      innerHTML: ${JSON.stringify(marked(src))}, 
    })
};

_sfc_md.render = _sfc_render
export default _sfc_md
Copy the code

The final composite code is as follows:

// /plugins/vite-plugin-md2vue.js

const marked = require('marked')

export default function (options) {
  return {
    name: 'vitePluginMd2Vue'.transform(src, id) {
      if (id.endsWith(".md")) {
        return {
          code: `import {h, defineComponent} from "vue";
                const _sfc_md = defineComponent({
                    name: "Markdown",
                });

                const _sfc_render =() => {
                    return h("div", {
                      innerHTML: The ${JSON.stringify(marked(src))},})}; _sfc_md.render = _sfc_render export default _sfc_md`.map: null
        }
      }
    }
  }
}
Copy the code

The use of plug-in

To use the plugin in viet.config.js, the code is as follows:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vitePluginMd2Vue from "./plugins/vite-plugin-md2vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vitePluginMd2Vue()],
  ...
});
Copy the code

The final implementation of the code in vite-plugin-md2vue