vite-plugin-vue-markedを使ってVueのSFC内でMarkdownを扱う

Jun 19, 2022

はじめに

vite-plugin-vue-markedというViteプラグインを作ってみたので使い方を紹介します。

これはVue3アプリ用のSFC内でMarkdownを扱えるというプラグインになります。

これによりロジックが絡まないコンテンツとtemplateタグ内のHTML部分を分離することができ、比較的人間が扱いやすいMarkdownでコンテンツを書くことができるというメリットがあります。

インストール

まずはインストールから。

npm install -D @7nohe/vite-plugin-vue-marked

プラグイン追加

次にvite.config.tsにインストールしたプラグインを追加します。

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueMarked from "@7nohe/vite-plugin-vue-marked";

export default defineConfig({
  plugins: [vue(), vueMarked()],
});

使い方

使い方は簡単で、<markdown>というカスタムブロック内にMarkdownを書いて、scriptタグ内でimportしてあげると、コンポーネントとして変換された内容が使えるようになります。

<!-- Example.vue -->
<script setup lang="ts">
import VMarked from 'vmarked';
</script>

<template>
  <VMarked />
</template>

<markdown>
- text1
  - text2
- text3
  -text4
</markdown>

内部でmarkedを使っているので、そのオプションを渡すことができ、カスタマイズが可能です。

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueMarked from "@7nohe/vite-plugin-vue-marked";
import hljs from "highlight.js";

const renderer = {
  heading(text, level) {
    const escapedText = text.toLowerCase().replace(/[^\w]+/g, "-");

    return `
            <h${level}>
              <a name="${escapedText}" class="anchor" href="#${escapedText}">
                <span class="header-link"></span>
              </a>
              ${text}
            </h${level}>`;
  },
};

export default defineConfig({
  plugins: [
    vue(),
    vueMarked({
      options: {
        highlight: function (code, lang) {
          const language = hljs.getLanguage(lang) ? lang : "plaintext";
          return hljs.highlight(code, { language }).value;
        },
      },
      extensions: [{ renderer }],
    }),
  ],
});

おわりに

完全な例はvite-plugin-vue-markedのリポジトリに置いてありますので、是非参考にしてみてください。