Nuxt.jsで作ったアプリでMarkdownをレンダリングしてみる

Nuxt.jsでSPAを作っていて「ここのテキスト表示領域、Markdownで書けるとイイなー」というようなリクエストがあったので@nuxtjs/markdownitを使ってMarkdownのレンダリングを試してみました。
2020.01.31

こんにちは。
プロダクトグループのshoitoです。

Nuxt.jsでSPAを作っていて「ここのテキスト表示領域、Markdownで書けるとイイなー」というようなリクエストがあったので、@nuxtjs/markdownitを使ってMarkdownのレンダリングを試してみました。

@nuxtjs/markdownitとは

markdown-itというMarkdownパーサーライブラリのNuxt.jsモジュール提供版です。

markdown-itについては、GitHubのREADME.mdにもリンクがありますが、 デモページを見ると、Markdownをどのようにレンダリングするか分かります。

create-nuxt-appでベースとなるNuxt.jsアプリを作る

ここではcreate-nuxt-appコマンドで、try-markdownitという名前のアプリを作ります。
yarn dev まで実行すると http://localhost:3000/ でアプリケーションが起動します。

$ create-nuxt-app try-markdownit
$ cd try-markdownit
$ yarn dev

@nuxtjs/markdownitを組み込む

まずはyarnやnpmでライブラリをプロジェクトの依存関係に追加します。

$ yarn add @nuxtjs/markdownit

次にNuxt.jsアプリに組み込むために nuxt.config.jsmodules セクションに @nuxtjs/markdownit の設定を追加します。
今回は $md を使って、 <div v-html="$md.render(markdown)"></div> のようにmarkdown変数に格納したMarkdownテキストをレンダリングしたいので、 markdownitinjected オプションを true で指定します。

nuxt.config.js

export default {
  ...
  modules: [
    '@nuxtjs/markdownit'
  ],
  markdownit: {
    injected: true
  },
  ...
}

ではトップページ(pages/index.vue)でMarkdownをレンダリングしてみます。
なお @nuxtjs/markdownit のトライアルのためにコードは簡略化しています。

pages/index.vue

<template>
  <div v-html="$md.render(markdown)"></div>
</template>

<script>
export default {
  data() {
    return {
      markdown: `
# h1 Heading
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading

## Emphasis

**This is bold text**

__This is bold text__

*This is italic text*

_This is italic text_

~~Strikethrough~~

## Blockquotes


> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.

## Lists

Unordered

+ Create a list by starting a line with '+', '-', or '*'
+ Sub-lists are made by indenting 2 spaces:
  - Marker character change forces new list start:
    * Ac tristique libero volutpat at
    + Facilisis in pretium nisl aliquet
    - Nulla volutpat aliquam velit
+ Very easy!

Ordered

1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa


1. You can use sequential numbers...
1. ...or keep all the numbers as '1.'

Start numbering with offset:

57. foo
1. bar
      `
    }
  }
}
</script>

これでコードは準備できたので、プロセスを立ち上げて http://localhost:3000 でレンダリング結果を確認します。

$ yarn dev

pages/index.vuemarkdown 変数に設定したMarkdownが確かにレンダリングされていますね。

markdown-itをプラグインで拡張してみる

markdown-itではプラグインによる拡張の仕組みが提供されています。
npmjsで確認すると308パッケージあるようです。2020-01-31時点。
https://www.npmjs.com/search?q=keywords:markdown-it-plugin

今回はMarkdownにPlantUMLの図をレンダリングするテキストを埋め込めるmarkdown-it-plantumlを導入してみます。

まず markdown-it-plantuml ライブラリを依存関係に追加します。

$ yarn add markdown-it-plantuml

次に、 nuxt.config.jsmarkdownuse オプションに markdown-it-plantuml を追加します。

nuxt.config.js

export default {
  ...
  modules: [
    '@nuxtjs/markdownit'
  ],
  markdownit: {
    injected: true,
    use: ['markdown-it-plantuml']
  },
  ...
}

設定が終わったので、PlantUMLのレンダリングを試します。
pages/uml.vue ファイルを以下のように作り、レンダリング結果を確認します。

pages/uml.vue

<template>
  <div v-html="$md.render(markdown)"></div>
</template>

<script>
export default {
  data() {
    return {
      markdown: `
# PlantUMLのお試し

@startuml

node UFS {
  interface AutoScaling
  interface Compute
  interface ELB
}
node CLC {
  database DB
}
AutoScaling ..> Compute
AutoScaling ..> ELB
AutoScaling --> DB
@enduml
      `
    }
  }
}
</script>

※PlantUMLのテキストはReal World PlantUMLの例を利用

さいごに

@nuxtjs/markdownit(markdown-it) を使って、容易にMarkdownをレンダリングできること、またプラグインで拡張できることを確認できました。 要求を満たせそうか各種オプション設定やプラグインなど、さらに試してみようと思います。