Help us understand the problem. What is going on with this article?

VurePress プラグイン開発に挑戦 (ローカル編)

この記事は、 North Detail Advent Calendar 2019 の8日目の記事です。

前置き

昨年に VuePress を知ってから、ちょっとしたドキュメントをまとめたサイトを作るのによく使っています。

Markdown でファイルをちゃちゃっと書けば、すぐに良い感じのサイトに仕立て上げられるので、すごく便利ですね。

ただ、コンテンツ全体を出すのにサイドバーにメニューを作っていかなきゃいけないんですが、それって結構面倒だなぁ、と思うんですよ。

「じゃぁ、プラグイン作っちゃえばよくね?」
と、思ったので挑戦してみました。

今回は NPM のパッケージではなく、ローカルに配置するパターンです。
また、作成した Markdown ファイルをアルファベット順に表示するだけ、です。
(これだけでも、シンプルなサイトなら十分楽になるので。)

準備

まず、 VuePress のプロジェクトを作りましょう。

$ mkdir sample-project
$ cd sample-project
$ yarn add -D vuepress
$ mkdir docs

できたら、順次下記ファイルを作成していきます。

ビルドなどを手軽にできるように、 package.json"scripts" 追加。

package.json
{
  "devDependencies": {
    "vuepress": "^1.2.0"
  },
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  }
}

サンプル表示用に、いくつか Markdown ファイルを作成。

docs/README.md
# 誰かの冒険

プラグイン作成のための冒険。

## 第1章: 旅立ち

[旅立ちます。](/01-departure)

## 第2章: 帰還

[ただいま。](/02-return)
docs/01-departure.md
# 第1章: 旅立ち

旅立ちます。

## 1.1: お城

王「ひのきの棒を与えよう。」

docs/02-return.md
# 第2章: 帰還

ただいま。

## 2.1: お城

王「死んでしまうとは何ごとだ。」

この状態で、開発サーバを立ち上げて画面を確認します。

$ yarn docs:dev

http://localhost:8080/ をブラウザで表示してみましょう。

20191206_001.png

今の所サイドバーの設定はしていないので、何も表示されていませんね。

プラグイン作成へ

その前にサイドバーの設定をやる場合は

こんな感じで書きますね。

docs/.vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/01-departure',
      '/02-return',
    ]
  }
}

こうやると、当然ブラウザでサイドバーにメニューが表示されますね。

20191206_002.png

表示確認できたら、 sidebar は不要なので消してください。

プラグインを読み込む設定

では、プラグインを作っていきましょう。
今回は、ローカルにあるプラグイン用のJavaScriptを読み込みます。

Using a Plugin | VuePress

docs/.vuepress/config.js
module.exports = {
  plugins: [
    require('./auto-sidebar')
  ]
}

docs/.vuepress/auto-sidebar のディレクトリの中に必要なファイルを作成していきます。

プラグインを書く

そもそも、サイドバーを変更するにはどうすれば良いのか。

実は情報をパッとは見つけられなくて、結構試行錯誤をしました。。。

その中で、 App Level EnhancementssiteData を操作すれば良さそうなことがわかったので、こちらを色々といじっていきます。

作成したページの情報は siteData.pages に入っており、これを使ってメニューに相当する配列を作成します。
作成した配列は siteData.themeConfig.sidebar に格納すればよさそうです。

では、実際にサイドバーにメニューを表示するプラグインを書いてみましょう。

色々な設定内容(API)があるので、詳しくはオフィシャルのドキュメントを確認してみてください。
Writing a Plugin | VuePress

今回はプラグイン内で App Level Enhancements を利用できるような設定を行ないます。
これは enhanceAppFiles というのを設定すれば良いです。

docs/.vuepress/auto-sidebar/index.js
const path = require('path')

module.exports = (option, context) => ({
  enhanceAppFiles: path.resolve(__dirname, 'enhanceAppFile.js')
})

この設定で、実際の処理は同じディレクトリの enhanceAppFile.js でやるよ、というような意味になります。
では、実際の処理を見てみましょう。

docs/.vuepress/auto-sidebar/enhanceAppFile.js
export default ({ Vue, options, router, siteData }) => {
  const sidebar = []

  // regularPath を使うと、ページトップの `#` で宣言した内容をタイトルとして使ってくれる。
  for (const page of siteData.pages) {
    sidebar.push(page.regularPath)
  }

  // regularPath を昇順にソート
  sidebar.sort((page1, page2) => {
    return page1.localeCompare(page2)
  })

  siteData.themeConfig.sidebar = sidebar
}

確認

開発サーバ(yarn docs:dev)を起動していたら一旦終了して、再度立ち上げてください。
そして、再度 http://localhost:8080/ をブラウザで表示してみましょう。

設定を書いた時と同じように表示されましたね!

ここで、 Markdown 内のタイトルを変更したり、ファイルを追加したりすると、リアルタイムに変更・追加されることも確認できると思います。

例えば次のような Markdown を追加すると、

docs/03-legend.md
# 終章: そして伝説へ

お星さまになります。

すぐにブラウザに反映されます。

20191206_003.png

これで目的達成できました!

作成した分は、下記リポジトリに置いています。
https://github.com/tacck/vuepress-plugin-sidebar

今後

もう少し構成の凝ったサイトでも導入できるように、もうちょっと色々とやってみたいですね。

  • オプション対応
    • 固定のメニューを追加するなど 1
  • グルーピング対応
  • マルチ言語対応
  • NPM パッケージ化 1

徐々にチャレンジしていきます。

FAQ

Q. プラグインを修正しても反映されない?
A. ローカルサーバを起動しなおしてみよう。うまいやり方あったら教えて。

Q. どこに設定要素があるかわからん。
A. 自分もわからん。 console.log() で頑張ったので、うまいやり方あったら教えて。。

Q. 順番をもうちょっとコントロールしたい。
A. ファイル名で頑張る想定。ソートしている部分を好きにすれば好きにできるので、プラグインを拡張してね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away