JAM StackなBlogをモダン技術で再作成した話

TL;DR

昔作っていたBlogを最近使い続けている技術で再作成しました。新しいブログを作成する際に使った技術について記事にしていきたいので、比較記事、検討した技術について書きます。

過去のブログ

過去のブログの構成技術

  • Backend

    • Heroku
    • Actix-web
    • lindera (形態素解析)
    • Tantivy (全文検索)
    • シングルバイナリで配布
  • Frontend

    • Google App Engine
    • yarn
    • mdx
    • Nextjs
    • Material UI
    • AMP

過去のブログの問題点

  • ブログのためだけにレポジトリが3つ (frontend, backend, blog posts) あってめんどくさい
  • Full AMPで作っていたため、Reactの恩恵が受けにくい
  • AMP AnalyticsがGA4に中々対応されない (Support App + Web properties on Google Analytics (gtag))。
  • Material UIを使っているので細かい調整をしようとするとめんどくさい
  • Herokuの無料枠廃止によってBackendのデプロイ先に困る

新しいブログ

過去のブログの問題点は以下のように解決したつもりになっています。

  • 複数のリポジトリを持つことが面倒だったため、単一のリポジトリにまとめるmonorepo構成にしました。
  • tailwindに似たCSS in JSのライブラリであるtwindを使用して、柔軟なスタイリングを可能にしました。
  • サーバーを必要としない検索エンジンであるmeilisearchを使用することで、バックエンドを廃止しました。
  • AMP対応を放棄することで、AMP固有の制約を回避し、更にGA4に対応しました。

新しいブログの技術構成

  • Google Cloud Run
  • pnpm
  • monorepo
  • mdx
  • Nextjs
  • twind
  • meilisearch

採用理由

  1. Google Cloud Run

今回は、Docker内のマルチステージビルドを利用して必要な記事をSSGして、Nextjsのstandaloneモードでデプロイをしたいと考えていました。そのため、DockerをそのままデプロイできるGoogle Cloud Runを利用しました。また、もともとGoogle App Engineを利用していたことから、カスタムドメインの移行が簡単なのも良かったです。

  1. monorepo

ブログ記事の前処理をCLIを使って、Frontmatterから取得したメタデータと、記事自体のMDXへコンパイルしたデータをJSON形式で保存し、そのファイルをNextjsのSSGの際に利用することにしました。

そのため、今回の構成は以下のようになりました。

  • common : zod schema + type
  • web : Nextjs
  • cli : jsonへの変換

これに加えて、MDXのオレオレパーサーを実装するため以下を作成しました。

  • md-plugins : remark, rehypeのプラグイン置き場

そのため、ブログ記事+Metadataをcommonとして切り出しzodを使って型安全にパースできるようにしました。commonのスキーマと型を使ってCLIでMarkdownをJSONに変換し、JSONをzodで型安全にパースしながらNextjsのSSGで扱えたので、体験として良かったです。

  1. Nextjs

一番使ったことがあるフレームワークだったからです。進化も著しく、キャッチアップする意味でも有意義でした。

  1. mdx

Pluginを自作するとやりたい放題できるので好きです。やりすぎると何やってるかわからなくなるので、程々に利用しようと考えています。

  1. twind

denoで使われているイメージが強いCSS in JSです。tailwind CSSと同じような感じでスタイリングできるのですが、lg:(text-xl font-bold)みたいなグルーピングができて見通しが良い、postcssなどがいらず、ビルド時にコンパイルされるなどのメリットが大きいと感じています。

  1. meilisearch

Rustで書かれたOSSの全文検索サーバーです。JSONを投げたら記事の登録ができ、クエリを投げれば記事の一覧が返ってくるので、簡単に検索サービスが実装できます。クラウドも無料で10000リクエストまで検索できるので、実装が簡単に終わります。

採用しなかった技術

  1. AMP

AMPはGoogleもやる気を失っている感じがしました。また、AMPに頼らなくても十分高速なサイトが実装できたので、あまりAMPの恩恵が感じられなくなったのもあります。

  1. Material UI

Tailwindが書きたかったからです。

  1. Custom Backend

デプロイを複数回に分けるのが面倒でした。

  1. tinysearchなどのWebassembly baseの検索

最初はこれにしようと思っていて、tinysegmenterを使って実装しようとしていました。しかし、せっかくTypescriptで完結できているが故の型安全などを捨てるのも微妙 + stop wordの除去などの前処理が非常にめんどくさいなどの理由から却下しました。Meilisearchが手軽に実装できすぎたのもあります。

この記事に関するIssueをGithubで作成する

Read Next