プログラミング

Gridsomeでマークダウンファイルを扱う

Vue製静的サイトジェネレータGridsomeでマークダウンファイルをJavaScriptで扱う方法。


本ブログでもブログ記事データとして使用しているマークダウンファイルをGridsomeで扱う方法について書きます。

Gridsomeでマークダウンを扱う

Gridsomeもそうですが、JavaScriptでマークダウンファイルをそのまま扱うことはできません。

VueやNuxtでマークダウンファイルを扱う場合はマークダウンをHTMLへ変換するmarkdown-itmarkedなどのマークダウンパーサーを使いますが、Gridsomeの場合はマークダウンファイルをGraphQLのコンテンツとして取得できるように変換する以下のライブラリのうちどちらかを使用します。

  • source-filesystem
  • vue-remark

@gridsome/source-filesystemを使う

ひとつめの方法としてsource-filesystemライブラリを使う方法があります。こちらはGridsomeのプラグインとして提供されています。

詳しい使い方は公式ドキュメントに説明がありますが、簡単にセットアップについて紹介したいと思います。
(※マークダウンファイルを使用したブログという前提で説明します)

インストール&セットアップ

yarn add @gridsome/source-filesystem

gridsome.config.jsにプラグインの設定を追記します。

gridsome.config.js
module.exports = {
  plugins: [
    {
      use: "@gridsome/source-filesystem",
      options: {
        typeName: "Post",
        path: "./blog/**/*.md",
      }
    },
  ],
  templates: {
    Post: "/post/:year-:month-:day/:slug",
  }
};

optionsのtypeNameはGraphQLタイプになります。GraphQLのコレクションのノードの単一ページを生成するためにsrc/template配下の.vueファイル名と一致させる必要があります。

後述しますが、template配下のPost.vueはブログの個別記事ページを表示する用途になります。

pathはマークダウンファイルの格納パスを指定します。

マークダウンファイルはプロジェクトルートに/blogフォルダを作り、その下にファイルを格納していきます。configのpathで再帰的にマークダウンファイルを走査するよう指定しているため、/blog配下であれば好きにサブフォルダを作ることができます(例えば年ごとの記事フォルダ等)

マークダウンファイルは以下のような感じで、ブログ記事のパスやタイトルなどのメタ情報を書くFront-matter部と実際の記事本文を表すマークダウン部分に分かれています。

---
slug: /sample-blog-post
title: テスト記事タイトル
date: 2020-03-14T21:21:19
summary: テストサマリー
tags: [タグ1, タグ2]
---

## はじめに

サンプル記事本文・・・

メタ情報は自由に項目を追加できます。ここで設定したメタ情報はGraphQLの記事取得用クエリのフィールドで利用できるようになります。

Vueファイルから利用する

例えば/template/Post.vueでブログ記事の個別記事データを取得するには以下のようなGraphQLを書きます。

/template/Post.vue
<template>
  <Layout>
    <div v-html="$page.post.content" />
  </Layout>
</template>

<page-query>
  query Post($id: ID!) {
    post(id: $id) {
      title
      path
      summary
      date: date(format: "YYYY-MM-DD")
      tags {
        title
        path
      }
      content
    }
  }
</page-query>

contentにHTMLに変換されたマークダウン本文がセットされているので、Vueのv-htmlでマークダウン本文を表示することができます。そのほか、マークダウンファイルで定義したメタ情報も取得できるので$page.post.titleなどでVueのテンプレート部で自由に使うことができます。

@gridsome/vue-remarkを使う

マークダウンファイルを扱うもうひとつの方法として@gridsome/vue-remarkを使う方法があります。こちらもGridsomeのプラグインとして提供されています。

vue-remark自体も内部的にはsource-filesystemが使われているので、マークダウンファイルをGraphQLコンテンツに変換するという点は同じです。

vue-remarkの場合は上記に加えて、マークダウンファイルの中でVueのコンポーネントが使えるようになります。例えば、youtubeなどの埋め込みコンテンツ用のコンポーネントを作っておき、それをマークダウンファイル中で使えるようになります。

マークダウンのみだと複雑なレイアウトを作るのは難しいので、VueのSFCと組み合わせればそれも容易になるということです。

ただし、注意点もあります。マークダウンファイルの中でVueのコンポーネントを使うことで、マークダウンファイルが汎用的なものではなくなってしまいます。
どこででも使えるマークダウンファイルがvue-remark/vue.jsという特定の技術に依存したものになってしまいます。これは、例えばGatsbyへ移行しようと思った時にVueの技術が使われているマークダウンファイルだと移行を困難なものにしてしまいます。

vue-remarkのセットアップや詳しい使い方は公式ドキュメントに詳しい説明があるのでそちらを参照ください。

おわりに

Gridsomeでマークダウンファイルを扱う方法について書きました。

Gridsomeのスタータープロジェクトを見ると現状はほとんどsource-filesystemを使用したものとなっています。マークダウンファイルの変換自体はどちらも同じなので、マークダウンファイル中でVueコンポーネントを使いたい場合はvue-remark、使わない場合はsource-filesystemを使うのが良いかと思います。