自転車ブログをHugoからGatsby.jsで書き直した

Gatsbyに変更した理由

Hugoは元々サイトビルドが爆速という理由で採用しました。事実、ローカルサーバを作る場合でも300ページ近いブログも一瞬(0.2秒程度)でビルドが終わりlocalhostで接続できるのでこの点については全く不満なし。

ただし、主に実際にWEBサイトとして運用するにあたって下記の点が課題になっていました。

  • レスポンシブな画像配信がテーマ任せで、デバイスごとに最適な配信がしづらい
  • 上記の影響で結局shortcodeというHugo特有の記法をMarkdownに書かねばならず、可搬性が落ちている
  • 画像サイズが最適でない影響でSEO悪化
  • 初期のバージョンで構築したので、git submoduleを使ったテーマのアップデートができなかった(そもそもテーマも結構いじってしまったので単純アップデートができない)
  • テーマをいじるのにGolangでフロントエンドを書くという苦行をしなければならない

特にきついのは画像配信周りとテーマの弄り難さでした。

そんなわけもあってReact.jsでフロント周りを自分で1から書きながらGatsby

採用したフレームワークなど

ほぼ自分でデザインを書くと決めていたので、採用するフレームワークも選び放題なのでなるべくモダンで、かつ最小で済むようにしました。
Gatsby-starter-blogをベースに使わないと思われるプラグインを削除して、下記のサービスやフレームワークに必要なものをインストール。
今はgatsby-starter-blog-mdxで始めるのがいいと思います

www.gatsbyjs.org

npmの文脈で全てが完結するので、新たに勉強しなければならないことが少なく割と楽ちんでした。
プログラミングではないけど、Google Tag Managerはかなり便利だったので別途記事書きます。

特に工夫という工夫はなく、各プラグインフレームワークの記載に従って実装しました。

というよりも、3ヶ月ほどかかってそれなりにハマったはずなのに、逐一メモらなかったために終わったら綺麗サッパリ忘れてしまった。どこかでハマってたどり着いた人はリポジトリ参照してください。

github.com

強いて言えば、Hugo時代の遺産であるdraftフラグを使うためにGraphQLに1行追加しました

....
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      skip: $skip
      limit: $limit
      filter: {frontmatter: {draft: {eq: false}}}
...
...

悲しい作業

一番不毛だと感じたのがHugo用に書いたShortcodeと、Markdownのfrontmaterを正規表現と手動Grepで置き換える作業。
Markdownでコンテンツ管理する以上は、標準的な(最低でもGithub flavorな)Markdown記法だけに利用をとどめましょう…

Markdown以外から画像を利用するのはGatsby.jsにおけるクソ実装レベルがかなり高い行為なのでなるべくMarkdownからページ生成したほうがいいということはわかった。

移行結果

f:id:gensobunya:20191109104458p:plain
lighthouse

出来上がったものがこちら

blog.gensobunya.net

記事書いといてLighthouseスコア100じゃないのかよとツッコミたくなりますが、以前のブログは画像サイズのせいで70台などと全体的に低迷していたのでかなり改善されました。Performanceは毎回数字が変わるので飾りです。AccessibilityはもうちょいUIの実装力や色の知識を上げれば90後半になりそう。

テストに関して

ホスティングに使っているNetlifyのDeploy-preview機能を利用しました。

リンクしているGithubリポジトリのプルリクから自動的にステージングサイトを生成してくれるので、CI/CDをほぼ書かなくても実装できます。
今回、本番サイトはhugoでビルドしているため、ビルドコマンドが変更となりますがNetlifyはこんな要件にも対応しています。

プロジェクトrootのnetlify.tomlに下記のように環境毎のビルドコマンドと公開ディレクトリを指定できるので本番と違うコマンドで自動ビルド可能です。

[context.production]
  command = "npm run build"
  publish = "/public"

[context.deploy-preview]
  command = "npm run build"
  publish = "/public"

[context.branch-deploy]
  command = "npm run build"
  publish = "/public"

JavaScript同士ならnpm run buildの中身を書き換えておけばいいんですが言語ごと変わるとそれもできないのでありがたい。 管理画面でBranch deployをONにすると特定のブランチが更新されるたびにステージングサイトを作ることもできます。Netlifyマジですごい、神。