Nuxt.js に MarkDown を読み込む
ブログをHexo
からNuxt.js
に移行するに当たり、過去記事のMarkdown
ファイルは捨てたくありません。
.vue
へのコンバートも面倒です。
なので、引き続き記事はMarkdown
で書きつつ、Nuxt.js
で Vue テンプレートにロードする方式にします。
Nuxt のジェネレート時にMarkdown
ファイルを取り込む方式です。
frontmatter 対応で記事に属性をもたせたい
frontmatter
とは、md ファイルの先頭に yaml 形式で記事に属性を持たせる方法です。
---
title: Nuxt.js に MarkDown を読み込む
tags: [Blog Nuxt化, Nuxt.js, Markdown]
date: 2019-11-28
parent: nuxt-blog-index
---
ブログを`Hexo`から`Nuxt.js`に移行するに当たり、過去記事の`Markdown`ファイルは捨てたくありません。
`.vue`へのコンバートも面倒です。...
↑ md ファイルの頭に ---
で囲まれた部分が記事属性になります。
この記事にはtitle
、tags
、date
、parent
の属性が設定されています。
これをvue
に読み込ませたい!
nuxt.config.js で md ファイルのロードに対応する
.md
ファイルのローダーを設定して、JavaScript
で扱いやすくします。
frontmatter
を扱えるローダーがnpm
パッケージに公開されていたので、ありがたく利用させていただきます。
→ frontmatter-markdown-loader
ライブラリのインストール
yarn add -D frontmatter-markdown-loader
nuxt.config.js に登録する
.md
ファイルのローダーとしてfrontmatter-markdown-loader
を登録します。
これで.md
ファイルをimport
するとJavaScript
オブジェクトになります。
ソースコードのハイライト表示もしたいので、highlight.js
とも連携しています。
import hljs from 'highlight.js'
export default {
build: {
extend(config, _ctx) {
config.module.rules.push({
test: /\.md$/,
loader: 'frontmatter-markdown-loader',
options: {
markdownIt: {
html: true,
linkify: true,
breaks: true,
// ソースハイライトするためにhighlight.jsと連携
highlight(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value
} catch (e) {
console.error(e)
}
}
return '' // use external default escaping
}
}
}
})
}
}
}
md ファイルをロードしてみる
test.md
を作成して読み込ませてみる。
md ファイルの作成
---
title: テストタイトル
tags: [tag1, tag2, tag3]
date: 2019-11-28
---
# 本文タイトル
本文のテスト1
本文のテスト2
md ファイルのロード
import md from './test.md'
console.log(JSON.stringify(md))
ログにこんなのが出る。
{"attributes":{"title":"テストタイトル","tags":["tag1","tag2","tag3"],"date":"2019-11-28T00:00:00.000Z"},"html":"<h1>本文タイトル</h1>\n<p>本文のテスト1<br>\n本文のテスト2</p>\n"}
おお、できてる!
見やすく整形したのがこちら。
{
"attributes": {
"title": "テストタイトル",
"tags": ["tag1", "tag2", "tag3"],
"date": "2019-11-28T00:00:00.000Z"
},
"html": "<h1>本文タイトル</h1>\n<p>本文のテスト1<br>\n本文のテスト2</p>\n"
}
vue ファイルに流し込む
結果の JSON を見るに、
attributes
属性にfrontmatter
で記述された属性html
属性にHTML
形式に変換された本文
が登録されているようです。
HTML
形式になっているので、このまま流し込めばいいですね。
<template lang="pug">
.posts-contents
.title.is-1 {{md.attributes.title}}
.markdown-body(v-html="md.html")
</template>
<script>
import md from './test.md'
export default {
data() {
return {
md
}
}
}
</script>
ウルトラ上手にできましたー!!
これを応用すればタグや日付表示などにも使えそうです!
frontmatter の記述について補足
hexo
のときにできていたfrontmatter
記法が、frontmatter-markdown-loader
では読めないパターンが有りました。
hexo
のときに書いていた記法、いわゆるハッシュの中に配列を書く書き方です。
tags:
- tag1
- tag2
- tag3
これがfrontmatter-markdown-loader
では読めなかったので、下記のように対応しました。
tags: [tag1, tag2, tag3]
ここだけほぼ全ファイルに修正が入りましたが、重要な本文はノーメンテで持っていけたので良かったです!