Vueを使ってMarkdownファイルを表示する

記事
IT・テクノロジー

Vueを使ってMarkdownファイルを表示する

前回は、Firebase ストレージに保存したファイルを Vue を使って表示する方法を紹介しました。これで簡単なブログなどのサービスを実現できます。今回は、HTML ではなく、Firebase のストレージに保存した Markdown のファイルを Vue で表示する方法を紹介します。こちらの方が、原稿を書く際書きやすく、そのままの形でも読みやすいというメリットがあって便利です!

Markdown とは?

Markdown は以前にもこの連載で取り上げていますが、マークアップ言語です。 そのままの形でも、比較的読みやすく HTML などに比べると初心者でも書き方を簡単に覚えられるので便利です。 便利なのは、この形式で書かれたファイルを公開されているモジュールで簡単に HTML に変換する事が可能になっている点です。 ブログなどの記事は、ある程度文章の形が決まっていて、特別な HTML を書く必要はあまりありません。そう考えると、原稿を Markdown で書いておいて、表示する際にプログラムで HTML に変換して表示するという方法はブログサイトを運用するには都合の良い仕組みです。

プログラムの履歴を管理するのに、Git がよく利用されますが、Git をベースにオンラインでプログラム開発のプロジェクトを保存して、共有したり公開するのに広く利用されている GitHub のドキュメントも Markdown を採用しています。

この記事では、これまで学習してきた Vue を使って、Firebase に保存した Markdown を表示する方法を紹介します。

Markdown の基本

最初に Markdown の基本を紹介します。 まずは、簡単な Markdown の記述です。一般的な記事では、幾つかの見出しがあって本文を書くような形で、場合によっては箇条書きなどがありますが、簡単にその構成を Markdown で記述すると以下のようになります。

# 見出し1

「見出し1」の本文です

## 見出し2

「見出し2」の本文です

### 見出し3

「見出し3」の本文です

- 箇条書きの項目1
- 箇条書きの項目2
- 箇条書きの項目3
シンプルなテキストファイルでこのままでもある程度読み易い形になっています。

この記述を今回紹介する方法で HTML に変換すると下のようになります。

<h1 id="見出し1">見出し1</h1>
<p>「見出し1」の本文です</p>
<h2 id="見出し2">見出し2</h2>
<p>「見出し2」の本文です</p>
<h3 id="見出し3">見出し3</h3>
<p>「見出し3」の本文です</p>
<ul>
  <li>箇条書きの項目1</li>
  <li>箇条書きの項目2</li>
  <li>箇条書きの項目3</li>
</ul>
同じ記述でも、HTML 特有のタグで囲む必要があるので、慣れてしまえば余り問題はありませんが、読みやすさという点では断然 Markdown に軍配が上がります。

HTML の記述やプログラムのコードの引用が簡単

ところで、この連載では良く利用していますが、プログラムのコードや HTML の記述を記事の本文で引用するような場合には、Markdown が圧倒的に有利です。

理由は簡単で、HTML の記述では HTML の記述で利用されている特殊な記号を本文で使用する際には、特別な書き方をする必要があります。

例えば、HTML でタグに利用される文字「<」を本文で使うには「& l t」のように書く必要があります。実際に、こうしたプログラムの引用をこのような「特殊文字」を使って書くのは面倒です。また、そのようにして書いた HTML の記述は読み難くなリます。

Markdown で書く場合は簡単で引用の部分を「```」で囲んでおけばそのまま引用できます。

    ```
    <h1>HTMLの引用</h1>
    ```
の様な感じです。プログラムや HTML のコードを引用しない場合は、HTML でも問題ないという場合でも、プログラムや HTML のコードを引用する場合には、Markdown で書いておいた方がそのままでも見易い記述ができて、簡単に記事を書けます。

Vue で Markdown の記述を表示させるには?

では、本題の Vue で Markdown の記述を表示させるにはどうすれば良いかです。 Markdown を Vue で表示させるためのモジュールはインターネット上で色々公開されています。その中から今回は以下の二つのモジュールを利用する例を紹介します。

* gray-matter
* markd 
という二つのモジュールです。
詳しい事は次回の記事で紹介する予定ですが、Markdown には便利な仕組みがあって、ファイルの簡単なデータ(メタデータ)を本文とは別に書く事ができます。例えば、記事を書いた日付や、タイトルなどを本文とは別に保存する事ができます。

その場合、実際に表示させるのは、本文の部分になリます。表示する際には、このメタデータの部分と本文を分ける必要がありますが、その処理をやってくれるのがgray-matterです。 その後で、Markdown の記述を HTML に変換する処理をするのがmarkdになります。

この機能を使うにはまずこの二つのモジュールを既存のプロジェクトで利用できるようにインストールする必要があります。まずは、プロジェクトのトップフォルダで、以下のコマンドを実行します。

% npm install gray-matter
% npm install markd
これで、Vue のプログラムでこの二つのモジュールが利用できる様になります。

まずは、Markdown の記述を HTML に変換する関数を作ります。 今回は、テキスト処理をする Javascript の関数として、 src/lib/text.jsというファイルに以下のような関数を作りました。

// src/lib/src/text.js
import matter from "gray-matter";
import { marked } from "marked";

export function getHTML(text) {
  const processed = matter(text);
  const html = marked(processed.content);
  return html;
}
Vue の部品側は前回作った、HTML を表示する部分を少し書き換えれば完了です。 前回の記述は以下の様になっています。

methods: {
    selectedEvent(selectedFile) {
      /*
      const id = event.target.id;
      const selectedFile = this.list.files.find((item) => {
        return id === item.name;
      });
      */
      this.selectedFile = selectedFile;
      if (selectedFile) {
        getURL(selectedFile).then((url) => {
          fetch(url).then((res) => {
            res.text().then((raw_text) => {
              this.htmlText = raw_text;
            });
          });
        });
      }
    },
},
この部分を以下の様に、作成した関数を呼び出します。

methods: {
    selectedEvent(event) {
      const id = event.target.id;
      const selectedFile = this.list.files.find((item) => {
        return id === item.name;
      });
      this.selectedFile = selectedFile;
      if (selectedFile) {
        getURL(selectedFile).then((url) => {
          fetch(url).then((res) => {
            res.text().then((raw_text) => {
              this.htmlText = getHTML(raw_text);
            });
          });
        });
      }
    },
},

読み込んだファイルの中身をそのままでも使う代わりに、「getHTML()」で Markdown を HTML に変換したものを利用するようにします。

最後に、この変更だけの場合、Vite を利用してプロジェクトを作成した場合エラーが発生します。「Buffer is not defined」というエラーが発生します。

この対策には、「src/vite.config.js」を書き換えます。

import { fileURLToPath, URL } from "url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: "globalThis",
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true,
        }),
      ],
    },
  },
});
これでエラーが起きなくなります。

従来の「vue cli」などを利用してプロジェクトを作成している場合はこの問題は発生しません。

まとめ
この記事では、ブログなどの記事を書く際に、HTML で記述するよりは「Markdown を利用する方が便利」という事を紹介してみました。Vue で Markdown で書かれた記事を表示する方法も、公開されているモジュールを利用すれば、前回紹介した、HTML を表示に埋め込む方法に、簡単な変更を加えるだけで表示する事ができます。

特に、プログラムや HTML の記述を記事内で引用したりする場合には、HTML で直接記述するより効率的に書く事ができます。

Vite を利用した場合には、エラーが発生しますが、src/vite.conifg.jsを修正すればエラーの回避ができます。

次回は、 Markdown のメタデータに関して紹介する予定です。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す