gyojirのblog

Gatsbyでブログを作り直しました

2020/04/19gatsby

livedoorブログをやめて Gatsby + github pages にブログを移行しました。

候補としてはGatsbyのほかにHexo,Hugo,jekyll等があったのですが、 使い慣れたnode.js環境で作りたいという点と、Reactが多少分かること、GatsbyのGraphQLを使ったアプローチが ユニークであったことからGatsbyを選択しました。

Gatsbyについての解説は調べればいくらでもあるので自分は説明しません。
以下のページが参考になりました。

やったこと

自分のブログではgatsby-starter-blogを使いました。

マークダウンのfront-matterにidとtagsを追加

マークダウンは以下のようになりました。

---
id: 91sCekmFE
title: Gatsbyでブログを作り直しました
date: "2020-04-18T14:43:03.573Z"
description: ""
tags: ["gatsby"]
---

マークダウンを扱えるようにするgatsby-transformer-remarkプラグインは、Nodeの作成時に全てのfront-matterから項目を取り出して GraphQLスキーマを作成しているようなのですが、全てのtagsが空の配列であったりtagsが書いてあるmdが1つもない場合などは型推論ができず、 スキーマに登録されません。
スキーマに登録されていない項目をGraphQLで取得しようとするとcreatePages()でエラーになってしまいます。
そのため https://www.gatsbyjs.org/docs/schema-customization/#nested-types を参考にして、gatsby-node.jsに以下のコードを追記しました。

exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions

  const typeDefs = `
    type MarkdownRemark implements Node {
      frontmatter: Frontmatter
    }
    type Frontmatter {
      tags: [String!]!
    }
  `
  createTypes(typeDefs)
}

タグページの追加

以下のページを参考にしました。
Gatsby で gatsby-theme-blog を使うときの tips


記事URL(スラッグ)の変更

gatsby-starter-blogのデフォルトでは /path/to/post という感じのURLだったのですが、これだと

  • 記事を管理するためのファイル名がURLになってしまう
  • ファイル構成を変更するとURLが変わってしまう
  • 記事の日本語タイトルとURL用英語タイトルを考える必要がある
  • 後々変な英語が気になっても直しにくい

という点から、front-matterに設定したidを使って /posts/id という形式に変更しました。 これでファイル名に関してはある程度自由に管理しやすいように決めることができます。

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const id = node.frontmatter.id
    const value = `/posts/${id}`
    
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

記事ファイルの自動生成

front-matterのidをURLに使っているので、記事を新しく作るときには必ず一意なidを設定する必要があります。 また、記事を作成したときの日付も自動で入力したいです。

テンプレートから自動でファイルを生成する方法はいろいろあります。

  • Yeoman, generator-generator

    • Yeoman用の自作generatorをgenerator-generatorで作成する
  • scaffdog

    • 1つのマークダウンファイルで複数ファイルのテンプレートを定義できる
  • 自作する

初めはscaffdogが良さそうだと思い試したのですが、テンプレート内でevalは使えるものの、 id生成のように外部ライブラリを使いたい場合には向いていないようなので選択肢から外しました。

yeomanにしようかとも思ったのですが、ちょっとしたテンプレートエンジンくらいなら割と手軽に作れそうなので自作することにしました。
↓のページ
うんざりするような下準備をJavaScriptで自動化してラクをする方法
がとても参考になりました。

仕様自体はscaffdogを参考にして、templateフォルダに置いた以下のようなyamlファイルからファイルを生成するようにしました。 ソースはこんな感じ

variables:
  - name
files:
  - path: content/blog/%name%/index.md
    content: |
      ---
      id: %__id%
      title: %name%
      date: "%__date%"
      description: ""
      tags: []
      ---


今のところそれなりに満足しています。
以上です。

© 2021 gyojir