VuePress 1.xでブログを作ってみる


## vuepressを使うまでに至った理由
発端は、自分のブログを作りたいと言うところです。Qiitaは技術的な情報を発信するのに適していますが、組織のことや仕事の中での学びを発信したいと言う時にQiitaに投稿するのは少しずれているように感じます。よくエンジニアの人は、はてなブログなんかで、その辺りのことを書いていて、自分も技術以外のところを発信する場が欲しいというのが始まりです。(これがおよそ1年前)
僕はエンジニアなのですが、デザインやフロントのところにも興味があり、はてなブログやnoteやMediumと言うサービスを使うのではなく、自分で自由に作れるものを探していました。
WordPressが1番主流なのでしょうが、そんな中見つけたのが、静的サイトジェネレーターと言うものでした。
有名なところだと、hugoやGatsbyなどがあります。実はどちらも手をつけてThemeを使ってサイトを作るところまでやりました。
でもやはり、普段触らない言語でThemeのちょっとした機能がゴリゴリ書かれていたりすると、改修するのに苦労しそうだなと思い、ネット上に公開すると言うところまでは至りませんでした。

次に触ったのが、Nuxt.jsです。こちらはVueで書けるので作りやすかったのですが、ブログにある機能として、タグやカテゴリーと言う必須の機能を作るのでさえ、きちんと設計して、作らないといけないですし、見た目の部分も作るまでに時間がかかるため、スピード感に欠け完成させるのに労力を要しました。

僕の求めていたのは、

- 自由にデザインを組める。機能を追加できる。
- あまり時間をかけずにブログを作りたい。改修したい。

と言う、一見相反するものでした。

そんな中、見つけたのが、vuepressでした。vuepress0系でもブログを作ることができたのですが、ブログの機能はデフォルト機能としてなく、自分で実装する必要がありましたが、今年になって出た[vuepress1.x](https://v1.vuepress.vuejs.org/)からは、プラグインを入れ、手軽にブログを作ることが出来るようになりました。

**Vueで簡単に処理を書ける + ブログのベース機能はプラグインで入れるだけ**
と言うのは自分のニーズを満たしていたので、実際にvuepressを使ってブログを作ることに決めました。

ちなみに全ては紹介できませんが、以下の技術を用いて、今回ブログを作ってみました

- VuePress1.0.0-alpha.47
- Netlify(ホスティング)
- [Tailwind CSS(CSSフレームワーク)](https://tailwindcss.com/docs/what-is-tailwind/)

(ミーハーなので、Tailwindも使ってみました。こちらはまた時間があれば、記事としてまとめます)


作成し始めて、リリースさせるまで、おそらく半日あれば完成させることができるかと思います。



## vuepress導入

まずは、vuepressをyarnでインストールするところから。

`yarn add -D vuepress@next`

インストールするとnode_modules、package.json、yarn.lockが生成されます。

これでvuepressの環境自体はできているのですが、ページやvueコンポーネントは初期の段階では作成されず、自分でこれから作成して行くことになります。

ということで、まずはディレクトリを作っていきましょう！(公式では、docsとなっているのですが、なんかsrcの方が個人的にはしっくりくるので、srcにしちゃいました)

`mkdir src`

package.jsonのscriptをいじります。

```json
{
  "scripts": {
    "dev": "vuepress dev src",
    "build": "vuepress build src"
  }
}
```

これで、```yarn dev```でsrc配下のファイルをビルドしてサイトのコンテンツを作ってくれるようになります。

ここで試しに、トップページを作ってみましょう。

`echo '# Hello VuePress' > src/README.md`

```yarn dev```

http://0.0.0.0:8080/
にアクセスすると、Hello VuePressの文字が出ているはずです。



## 設定ファイルをいじってカスタムする

ここからは設定ファイルをいじりながら、vuepressを個人仕様にカスタマイズしていきましょう。下記のディレクトリ構造のように、.vuepressディレクトリを作り、その下にconfig.jsファイルを作りましょう。

```:ディレクトリ構成
blog
├─ src
│  ├─ README.md
│  └─ .vuepress
│     └─ config.js
└─ package.json
```

詳しくは、[ドキュメント](https://v1.vuepress.vuejs.org/guide/basic-config.html#config-file)を見れば、どんなことを書けばいいのか、わかると思います。


最初はこんな感じでしょうか。

```js:.vuepress/config.js
module.exports = {
  title: "blog",
  themeConfig: {
    description: "ここにはディスクリプションを入れます。",
    nav: [
      { text: "About", link: "/about/" } // ここはnav barのメニュー表示/aboutページは後ほど
    ]
  }
};
```

## トップページの設定
トップページに出ている内容は、まだ、Hello, VuePressだけで味気ないので、ここもカスタマイズしましょう。
vuepressでは先ほど作ったmdファイルにfrontmatterを設定すると、各ページごとのメタ情報などの設定をすることができます。
またhome:trueとすると、vuepressのトップページテーマを使うことができます。

```:src/README.md
---
home: true
heroText: Yudium
description: ここにはディスクリプションを入れます。
footer: Copyright © 2019-present Youdai
---

```

## Aboutページを作ってみる
`/about/`のリンクがメニューに出ていると思うので、/about/にアクセスした際にページが表示されるようにaboutページを作ってみましょう。と言っても簡単です。下記のように、aboutディレクトリを作り、その下にmarkdown形式のファイルを置くだけです。

```:ディレクトリ構成
blog
├─ src
│  ├─ README.md
│  │─ about
│  │└─ index.md
│  │
│  └─ .vuepress
│     └─ config.js
│
└─ package.json

```

```about/index.md
## About
```

このようにすれば、`/about/`にアクセスした際に、ページの内容が表示されます。

## ブログ機能作成(@vuepress/plugin-blog)
ここからが本題。Vuepress0.xでは、ブログ投稿については自分で実装しなければならなかったのですが、Vuepress1.xからプラグインを入れて、簡単に機能を実装することができるようになりました。他にも、analyticsを入れるプラグインなど、まだまだ量は少ないですが、これは使い勝手が良さそう。
[詳しいプラグインについてはこちら](https://v1.vuepress.vuejs.org/plugin/)

今回は、公式にも乗っている、[@vuepress/plugin-blog](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-blog)を用いて、ブログ機能を作っていきます。

まずは、yarnでプラグインを入れます。
`yarn add -D @vuepress/plugin-blog@next`


そしたら、config.jsにpluginsを記述してください。これで設定はできましたが、まだブログ機能はできていません。

```:.vuepress/config.js
module.exports = {
  plugins: [
    "@vuepress/blog",
  ],
  // 中略 // 
}
```

ここからは実際にブログの投稿、そして、ブログのカテゴリーやタグの一覧機能を作っていきます。
まず最初に、ブログ機能を完成させた時のディレクトリ構造は以下のようになります。
ブログの投稿については、.vuepress/_posts配下にmdファイルを作成して行く形で、markdown形式で記事を投稿することができます。

```
blog
├─ src
│  ├─ README.md
│  │─ about
│  │└─ index.md
│  │─ tag
│  │└─ index.md
│  │─ category
│  │└─ index.md
|  |─ _posts
|  |└─ 1.md(_posts配下にファイルを置いて行くと、ブログ記事として見なされます。)
|  |
│  └─ .vuepress
│     └─ config.js
│     └─ components
│      │─ Tags.vue
│      │─ Tag.vue
|      │─ Category.vue
│      │─ Categories.vue
│      │─ Blogs.vue 
│
└─ package.json

```

投稿する際の、ブログのメタ情報は、Front Matterで設定できます。

```:1.md
---
title: ブログ始めました！
description: ディスクリプション
date: 2019-04-27
img: ./img/post_1.jpg
sidebar: auto
category: 雑記
tags:
  - 日記
  - 独り言
---

```

vuepressはmd形式で作成したページが`$page`の中に格納されています。
また、_posts配下にあるブログ記事は`id`が`post`になっているので、下記のように、`id == 'post'`になっているページををループすれば、ブログページ一覧ができます。

### ブログ一覧を作るコンポーネント

```Blogs.vue
<template>
    <div>
        <p v-for="post in posts">
            <a :href="post.path">{{post.title}}</a>
        </p>
    </div>
</template>

<script>
    export default {
        computed: {
            posts() {
                return this.$site.pages
                    .filter(page => page.id === 'post');
            }
        }
    }
</script>
```

作成したタグは`$tag`に、カテゴリーは`$category`に格納されるので、こちらも同じ感じで、ループさせれば一覧ページを作るコンポーネントが出来上がります。

### タグ一覧を作るコンポーネント

```vue:Tags.vue
<template>
  <div>
      <a v-for="tag in Object.keys($tags._metaMap)":href="tag">{{tag}}</a>
  </div>
</template>
```

### カテゴリー一覧を作るコンポーネント

```vue:Categories.js
<template>
  <div>
    <ul v-for="category in Object.keys($categories._metaMap)">
      <h3><a :href="$categories._metaMap[category].path">{{ category }}</a></h3>
      <li v-for="post in $categories._metaMap[category].posts">
          <a :href="post.path">{{post.title}}</a>
      </li>
    </ul>
  </div>
</template>
```

ここまで作ったコンポーネントは、mdファイルの中で、コンポーネントとして呼び出すことができるので、例えばタグ一覧だったら、
下のような感じで呼び出すことができます。

```:src/tag/index.md
----
title:タグ一覧です
----
<Tags />
```

## まとめ

割と、駆け足で書いてしまいましたが、こんな感じになります。
まだまだプラグインが足りなかったり、ドキュメントも薄かったりして、苦戦するとは思うのですが、Vue.jsで書かれているので、コンポーネントを作ったりするのは、すごく楽です。

またWordpressと同じように、すぐ使えるテーマみたいなものもあるので、こちらを使ってもいいかもしれません。

[Theme Guide \| vuepress-theme-meteorlxy](https://vuepress-theme-meteorlxy.meteorlxy.cn/posts/2019/02/27/theme-guide-en.html)
[VuePressにテーマを適用させる その2 \| web系のメモ](https://taku-ando.github.io/posts/vuepress/20180710_vuepress_theme.html)



今後vuepressがどのように進化していくのか期待大ですね。

------
参考
[Getting Started \| VuePress 1.x](https://v1.vuepress.vuejs.org/guide/getting-started.html#global-installation)

https://to-hutohu.com/2018/12/30/vuepress-blog/#%E8%A8%98%E4%BA%8B%E3%82%92%E6%9B%B8%E3%81%8F

[Information on blog and pagination plugin missing from website · Issue #1091 · vuejs/vuepress · GitHub](https://github.com/vuejs/vuepress/issues/1091)