Skip to content

Toilal/vite-plugin-render

 
 

Repository files navigation

vite-plugin-render

Vite plugin to render any file to a component

  • Render any file as Vue components
  • Use Vue components inside those template files

This is a fork of @antfu vite-plugin-md that extracts the Markdown parts to an external render function. Many thanks for his work !

NPM version

Install

Install

npm i vite-plugin-render -D # yarn add vite-plugin-render -D

Add it to vite.config.js, and configure the render function and file patterns includes you need.

Here's an example for Markdown using markdown-it as the renderer on *.md files, but you can adjust to any template engine.

// vite.config.js
import Render from 'vite-plugin-render'
const MarkdownIt = require('markdown-it')

const markdown = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true
})

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/], // <--
    }),
    Render({
      include: [/\.md$/],
      render: (content: string) => {
          return markdown.render(content)
      }
    }),
  ],
}

And import it as a normal Vue component

Import any file as Vue components

<template>
  <HelloWorld />
</template>

<script>
import HelloWorld from './README.md'

export default {
  components: {
    HelloWorld,
  },
}
</script>

Use Vue Components inside source file

You can even use Vue components inside your source file, for example

<Counter :init='5'/>

Note you can either register the components globally, or use the <script setup> tag to register them locally.

import { createApp } from 'vue'
import App from './App.vue'
import Counter from './Counter.vue'

const app = createApp(App)

// register global
app.component('Counter', Counter) // <--

app.mount()
<script setup>
import { Counter } from './Counter.vue
</script>

<Counter :init='5'/>

Or you can use vite-plugin-components for auto components registration.

Frontmatter

Frontmatter will be parsed and inject into Vue's instance data frontmatter field.

For example:

---
name: My Cool App
---

# Hello World

This is {{frontmatter.name}}

Will be rendered as

<h1>Hello World</h1>
<p>This is My Cool App</p>

It will also be passed to the wrapper component's props if you have set wrapperComponent option.

Document head and meta

To manage document head and meta, you would need to install @vueuse/head and do some setup.

npm i @vueuse/head
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import Render from 'vite-plugin-render'

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/],
    }),
    Render({
      headEnabled: true // <--
    })
  ]
}
// src/main.js
import { createApp } from 'vue'
import { createHead } from '@vueuse/head' // <--

const app = createApp(App)

const head = createHead() // <--
app.use(head) // <--

Then you can use frontmatter to control the head. For example:

---
title: My Cool App
meta:
  - name: description
    content: Hello World
---

For more options available, please refer to @vueuse/head's docs.

Options

// vite.config.js
import Render from 'vite-plugin-render'
const MarkdownIt = require('markdown-it')

const markdown = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true
})

export default {
  plugins: [
    Vue({
      include: [/\.vue$/, /\.md$/], // <--
    }),
    Render({
      include: [/\.md$/],
      render: (content: string) => {
          return markdown.render(content)
      },
      // Class names for the wrapper div
      wrapperClasses: 'markdown-body'
    }),
  ],
}

See the tsdoc for more advanced options

Example

See the /example.

Or the pre-configured starter template Vitesse.

Integrations

// vite.config.js
import Render from 'vite-plugin-render'
import Voie from 'vite-plugin-voie'
const MarkdownIt = require('markdown-it')

const markdown = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true
})

export default {
  plugins: [
    Voie({
      extensions: ['vue', 'md'],
    }),
    Render({
      include: [/\.md$/],
      render: (content: string) => {
          return markdown.render(content)
      },
      // Class names for the wrapper div
      wrapperClasses: 'markdown-body'
    }),
  ],
}

Put your markdown under ./src/pages/xx.md, then you can access the page via route /xx.

vite-plugin-components allows you to do on-demand components auto importing without worrying about registration.

// vite.config.js
import Render from 'vite-plugin-render'
import ViteComponents from 'vite-plugin-components'
const MarkdownIt = require('markdown-it')

const markdown = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true
})

export default {
  plugins: [
    Render({
      include: [/\.md$/],
      render: (content: string) => {
          return markdown.render(content)
      }
    }),
    // should be placed after `Markdown()`
    ViteComponents({
      // allow auto load markdown components under `./src/components/`
      extensions: ['vue', 'md'],

      // allow auto import and register components used in markdown
      customLoaderMatcher: path => path.endsWith('.md'),
    })
  ],
}

Components under ./src/components can be directly used in markdown components, and markdown components can also be put under ./src/components to be auto imported.

TypeScript Shim

declare module '*.vue' {
  import { ComponentOptions } from 'vue'
  const Component: ComponentOptions
  export default Component
}

declare module '*.md' {
  import { ComponentOptions } from 'vue'
  const Component: ComponentOptions
  export default Component
}

License

MIT License © 2020 Anthony Fu

About

Markdown for Vite

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 82.7%
  • Vue 11.3%
  • HTML 6.0%