Gridsomeでブログを作る

# この記事のターゲット
- Gridsomeって聞いたことある
- ちょっと使ってみたいけど何作ろうか
- とりあえずブログでも作って見るか

# Gridsomeってなにさ
https://gridsome.org/

大枠的にはStatic Site Generator、つまるところ静的なwebページを吐き出すツール。
特徴はなんといってもVueでできていること。
実際に利用する際もコンポーネント指向で開発ができ、.vueファイルのように一つのファイルにHTML, CSS, JavaScriptを記述できる。
ReactでいうところのGatsbyにあたる（らしい。こっちも使ってみたい）。
rubyでいうところのjekyll。

# ブログ作り開始

## インストール
npmでinstall

```
npm install --global @gridsome/cli
```

## プロジェクト作成
プロジェクトを作成して移動、用意されているコマンドを実行。

```
$gridsome create my-gridsome-site
$cd my-gridsome-site
$gridsome develop
```

開発用サーバーが立ち上がるのでlocalhostにアクセス

```
http://localhost:8080
```

無事に表示されれば成功！
表示されない場合は8080番ポートを他で占有してしまっていないか確認。

## ブログの用意
Gridsomeでは様々なCMS（[contentful](https://www.contentful.com/), wordpress, filesystemなどなど）をデータソースとして指定することができる。
ただし、今回は簡単のために外部サービスは利用せずにfilesystemをデータソースとする。

```
npm install @gridsome/source-filesystem
```

また、ブログをMarkdownで記述するために以下のモジュールをinstallしておく。

```
npm install @gridsome/transformer-remark
```

2つのモジュールのinstallができたらこれらのモジュールを利用するための設定を自動で生成されているgridsome.config.jsに以下のように記述する。

```javascript

// gridsome.config.js

module.exports = {
  transformers: {
    remark: {
      externalLinksTarget: '_blank',
      externalLinksRel: ['nofollow', 'noopener', 'noreferrer'],
      anchorClassName: 'icon icon-link',
      plugins: [
        // ...global plugins
      ]
    }
  },

  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        path: 'blog/**/*.md',
        typeName: 'BlogPost',
        route: '/blog/:year/:month/:day/:slug',
        remark: {
          plugins: [
            // ...local plugins
          ]
        }
      }
    }
  ]
}
```

## サンプル記事を用意
一旦表示確認のためのダミー記事を2,3個ほど用意。
ファイルはgridsome.config.jsで指定した通り以下のルールにしたがって配置する。（blog/test/sample1.md など）

```javascript
        path: 'blog/**/*.md',
```

中身はyaml形式の記述ができるので先ほどテンプレートでgraphqlのクエリに記載したパラメータを宣言しておく。
（BlogPost型がもともと持っている_idやpathなどはここで記述する必要はない）

```sample1.md

---
title: タイトル
date: 2018-09-15 01:00:00+09:00
description: "hogehoge"
tags: "hoge"
---

contents

```


## ブログのトップ画面を用意

`src/pages/index.vue`を編集。

```index.vue
<template>
  <Layout>
      <h1>Blog Posts</h1>
      <div v-for="item in $page.allBlogPost.edges" :key="item.path" class="post">
        <h2>
          <g-link :to="item.node.path">{{ item.node.title }}</g-link>
        </h2>
        <dl>
          <dt>{{ item.node.date }}</dt><dd>{{ item.node.fields.tags}}</dd>
        </dl>
        <p>{{ item.node.fields.description }}</p>
        <g-link :to="item.node.path" class="continue-link">続きを読む ></g-link>
      </div>
  </Layout>
</template>

<page-query>
  query Home ($page: Int) {
    allBlogPost (page: $page) {
      edges {
        node {
          _id
          title
          date (format: "YYYY年MM月DD日 HH:mm:ss")
          fields {
            description
            tags
          }
          path
        }
      }
    }
  }
</page-query>

<script>
  export default {}
</script>

```

※graphqlについて
本筋ではないので簡単に流しますが、gridsomeではデータソースへのアクセスにgraphqlを採用しています。
今回では定義されているBlogPost型のデータを全て取得するのでallBlogPost、各BlogPostの取得したいパラメータがnode配下で指定されています。
これらのパラメータは先ほど用意したmdファイルにて設定してます。
（正直graphqlよくわかってないマン、変なこと書いてたら詳しい方教えてくださいorz）

## ページのテンプレートを用意
`src/templates/BlogPost.vue`というファイルを作成。
これが各ブログ記事の中身が挿入されるテンプレートになる。

```BlogPost.vue
<template>
  <Layout>
      <h1>{{ $page.blogPost.title }}</h1>
      <dl>
        <dt>{{ $page.blogPost.date }}</dt><dd></dd>
      </dl>
      <div class="content" v-html="$page.blogPost.content" />
  </Layout>
</template>

<page-query>
query MarkdownPost ($path: String!) {
  blogPost (path: $path) {
    title
    date (format: "YYYY年MM月DD日 HH:mm:ss")
    content
  }
}
</page-query>

<script>
  export default {}
</script>
```

リンクが正しく機能すれば成功！

## まとめ
まだまだ新しい技術で公式サイトも情報が少なかったりして苦戦したので同じ道をたどる迷える子羊を救えたらと思います。
wordpressなどで管理するよりもページへのアクセスが静的ファイルなので圧倒的に早いはず。
[netlify](https://www.netlify.com/)などへのデプロイも簡単なのでぜひお試しください。