Gatsby.js + microCMSで技術ブログを構築しました

エンジニア歴2年目に突入し、もう半年ほど経ちそうです。
最近になって、本業では使わない(使えない)技術スタックを身につけるためにプライベートの時間を使って勉強する習慣がついてきました。
が、やはり仕事で使わないとすぐ頭から抜けてしまうので、理解したことを記録しておくためにこのブログを作ることにしました。
あと自作ブログをやってみたかったというのも理由としてはあります。

筆者のスキルセット

  • まともに書ける言語の中ではPHP歴が一番長い(7系しか書いたことないです。仕事ではPHP7.4使ってます)
  • CSSは最低限かける。複雑なアニメーションとかは厳しい。
  • jsは仕事ではノンフレームワークなvalilla jsでしか書いたことない
  • Reactは独学で初めて2~3ヶ月くらい


自分のスキルセットはこんな感じです。
このレベル感の人間がGatsbyで自作ブログ構築するにあたって、学習の流れや難しかったところ・ハマったところ等を書こうと思います。

学習の流れ

Gatsby.jsは、ページの表示に必要なデータをGraphqlで一気に取得して、それをReactコンポーネントに流し込むことでSSG(ServerSideGenarating)してくれる静的サイトジェネレータです(という理解です)。
そのため、GraphqlとReactの理解は必須となります。

GraphqlはUdemyで1本講座を買って勉強しました。この方の動画はTypeScript入門で買ったことがあるのですが、わかりやすかったです。
フロントエンドエンジニアのためのGraphQL with React 入門

その後に、「Webサイト高速化のための静的サイトジェネレーター活用入門」という本を読みました。Gatsby本とか呼ばれてるらしいです(?)
この本を手を動かしながらやりきると、Gatsby + Contentful製のブログが一本出来上がります。
このブログもそれをベースにカスタマイズして作りました。
ページネーションやSEOの実装まで丁寧に解説してくれています。
Webサイト高速化のための静的サイトジェネレーター活用入門

Reactそのものに関しては、話すとボリュームが大きくなりそうなので省略します。

Gatsby + microCMSでのブログ実装

実現する機能としては以下のような感じです。

  • コンテンツはすべてmicroCMSで管理
  • シンタックスハイライト
  • 記事のカテゴライズ


まずは、Gatsby本をやってできたブログから、Contentful依存の実装を剥がすしてmicroCMSでの実装に置き換えるところからはじめました。
microCMSを選んだのは、管理画面が日本語でUIもContentfulよりわかりやすいと感じたからです。
Gatsby本ではContentful依存の実装の剥がし方・microCMSへの乗り換え方まで付録で解説しくれていたのでこのステップでは特に困りませんでした。

microCMSで用意するAPI

ブログAPI、カテゴリAPI、aboutページ用APIを用意しました。
gatsby-source-microcms という、gatsbyでmicroCMSからGraphqlでデータ取得できるようにするためのプラグインが用意されているのでこちらにAPIの設定を記載します。



        // gatsby-config.js
        {
            resolve: "gatsby-source-microcms",
            options: {
              apiKey: process.env.microCMS_API_KEY,
              serviceId: "eringiv3devblog",
              apis: [
                {
                  endpoint: "blog",
                  query: {
                    limit: 100,
                  },
                },
                {
                  endpoint: "category",
                  query: {
                    limit: 100,
                  },
                },
                {
                  endpoint: "about",
                  format: "object",
                },
              ],
            },
        },
   

リスト形式のレスポンスか、オブジェクト形式のレスポンスを返すかで、formatオプションの値を変える必要がある点に注意が必要です。
ドキュメントにきちんと記載されているのですが、見落としてしまいハマりました。
デフォルトでは、format: "list"が指定されるようで、オブジェクト形式のレスポンスを返すAPIで明示的にformat: "object"を指定しないとビルドが失敗します。

コードにシンタックスハイライトを効かせる

「Gatsby syntax highlight」とかでググっても、gatsby-remark-prismjsというプラグインを使ってmarkdownで入稿する前提でハイライトを効かせる方法ばかりヒットします。
「静的サイトジェネレータを使って技術ブログを開設する」という目的に対しては多くの場合、ContentfulやmicroCMSのようなヘッドレスCMSを使わなくても、markdownファイルにコンテンツを書き込んでgit pushすれば済む話なので、そもそもAPIのレスポンスの中に含まれるHTML文字列からシンタックスハイライトを効かせられるようにするというモチベーションが発生しないのだと思います。
ただ、今回はどうしてもmicroCMSを使ってみたかったのでmarkdownは使わずに済む方法を考えました。

レスポンスのHTML文字列からシンタックスハイライトを効かせる手順は以下のようにしました。

  1. microCMSの繰返し項目機能を使って、ブログコンテンツに繰返し項目(リッチエディタ項目 or HTML項目を設定)をもたせる
  2. レスポンスに含まれる繰返し項目の項目IDで何の項目かを判別し、HTML項目の場合はHTMLとしてパースしReactコンポーネントに変換する
  3. Prismjsを使って、useEffectでクライアント側でハイライトを行う


コードはこんな感じになりました。
https://github.com/EringiV3/devBlog/blob/master/src/components/post-body.js

繰返し項目にHTML入力用の項目を設ける理由は、prismjsに言語の種類を識別させてハイライトして貰う必要があるためです。pre要素のclassにlanguage-xxxを指定すると、xxx言語の構文として解釈してくれます。
ただ、問題点があってprismjsとjsxの相性が良くないみたいで自分の手元ではjsxのシンタックスハイライトを効かせることができていません。すぐには解決できなそうだったので今後の課題です。

繰返し項目のIDで処理を分岐させるのは、microCMSのブログに実装例があったのでそれを真似しました。
繰り返しフィールドが追加されました

スタイリング

Gatsby本では外部のcssファイルにクラス指定でスタイルを当てていましたが、それをやめてstyled jsxを使ってみることにしました。CSS in JSのライブラリは種類が多くてどれを選択すればいいか迷ったのですが、グローバルな領域にスタイルを書き込んでいくのはどうしても嫌・styledComponentはコンポーネントが増えてなんか嫌という理由でstyled jsxを選びました。軽量かつ、<style jsx></style>で囲むだけでコンポーネントに対してscopedなスタイルを当てることができてシンプルなのがいいなと思いました。記法も普通のCSSと同じなのでとっつきやすかったです。
基本的にはすべてscopedにして、ページネーション等の複数のjsxファイルにまたがるクラスに対してのスタイルは<style jsx global></style>でグローバルな領域のスタイルとして記述しました。

デプロイ

Netlifyを使っています。GitHub, microCMSと連携してmasterへのコミットや、CMSで管理されているコンテンツの更新でデプロイされます。

その他

Google Analyticsやサイトマップの設定も、プラグインが用意されており、gatsby-config.jsにちょこっと設定を書き足すだけだったので自分でやることはほぼありませんでした。

計測

トップページをLighthouseで計測してみたら4項目すべて100点でした!

まだ1記事しか存在していないのでいい点数が出やすいのは当然だと思うので、今後記事が増えても点数が下がらないように気をつけます。
ちなみに、記事詳細ページで計測したらもう少し低いスコアになりました。

まとめ

Gatsby + microCMSという構成で、コンテンツはすべてmicroCMS管理かつシンタックスハイライトも効かせられる最低限の技術ブログができました。
今後の改善点として以下があります。

  • シンタックスハイライトについて、現在はクライアントサイドで実行するようになっているがGatsbyのメリットを活かせていない気がするので、サーバーサイドでハイライトした状態のHTML文字列を返すようにしたい
  • TypeScript導入
  • microCMSのプレビュー機能対応


TypeScriptはできれば最初から入れたかったのですが、初めて触るフレームワーク(Gatsby)、初めて触るCMS(microCMS)という構成だったので、カオスになるのを防ぐために、とても使いこなせるとは言えないレベルの習熟度のTypeScriptを入れるのは先送りとしました。
とりあえず公開するところまでたどり着けたのは「Webサイト高速化のための静的サイトジェネレータ活用入門」とmicroCMSの運営の方(Twitterでつまづいているところをつぶやいたら助けてくれた!)のおかげだと思います。
アウトプットのために作ったブログなのでこれで満足しないようにしたいです。