株式会社UKMETAのエンジビズ開発チームです。小さな会社サイトとして始まったGatsbyプロジェクトが、大量の案件を扱うサービスになるまでと、現在感じているつらさを振り返ります。
Gatsby、これからどうする?
最近、エンジビズのコードを触りながら何度も考えます。
「Gatsby、これからどうする?」
正直、つらいです。
コンテンツを1件直すだけでもビルドが走る。GraphQLのフィールドがデータ次第で消える。公開中案件の条件を変えると、一覧、詳細、スキル別ページ、サイトマップまで確認しなければならない。
「別のフレームワークに移行した方が早いのでは」と思う日もあります。
ただ、最初からGatsbyの選定が間違っていたわけではありません。そもそも私たちは、案件プラットフォームを作るためにGatsbyを選んだわけではありませんでした。
Gatsbyを選んだ、というよりスターターを選んだ
このリポジトリは、2024年3月に株式会社UKMETAのコーポレートサイトとして始まりました。
当時のpackage.jsonにはukmeta home pageと書かれ、構成はGatsby 4、React 17、LekoArtsのgatsby-theme-caraでした。必要だったのは、会社概要、事業紹介、問い合わせ先を掲載する小さなサイトです。
正確には、Gatsbyを他のフレームワークと比較して選んだというより、短期間で見栄えのよい会社サイトを公開できるGatsby製スターターを選びました。
当時は新しいメンバー、特に経験の浅いメンバーが入るたびに、まずこのプロジェクトを触ってもらうこともありました。色や余白を直したり、セクションを追加したりする、いわば「会社サイトを少しずつ飾る」ような位置づけでした。
Reactで編集でき、サーバーを管理せず、静的ファイルとして公開できる。小規模な会社サイトとしては十分に合理的でした。
気づけば大量の案件を扱うサービスになった
その後、サイトの役割は少しずつ変わりました。
- MicroCMSを導入
- ブログと案件データをCMSから取得
- 案件一覧と案件詳細を追加
- スキル別、職種別、働き方別、単価別ページを追加
- ページネーション、並び替え、お気に入り、応募フォームを追加
- サイトマップ、canonical、noindex制御を追加
気づいたときには、会社サイト向けのスターターが、大量の案件データから多くのページを生成するサービスになっていました。
ここで、Gatsbyの「便利だった部分」が「つらい部分」に変わり始めます。
つらさ1:CMSの更新がサイトの再ビルドになる
Gatsbyはビルド時にMicroCMSからデータを取得し、ページを生成します。
案件が少ないうちは問題ありません。しかし、詳細、一覧、条件別ページ、ページネーションまで増えると、「案件を1件公開する」という小さな操作が、大量のデータを扱うサイト全体のビルドにつながります。
静的サイトの単純さと引き換えに、更新コストがビルド側へ集まりました。
つらさ2:GraphQLの便利な魔法
GatsbyのGraphQLは、CMSデータを短いクエリで扱えるため便利です。一方、任意フィールドに値を持つコンテンツがなくなると、スキーマ推論からフィールド自体が消えてビルドに失敗することがあります。
エンジビズでは、案件の再公開日時を保持するpostedAtがこの問題に当たり、スキーマを明示することになりました。
export const createSchemaCustomization = ({ actions }) => {
actions.createTypes(`
type MicrocmsJobList implements Node @infer {
postedAt: Date @dateformat
}
`)
}
便利な魔法は、動いている間はコードを減らしてくれます。壊れると、Gatsby、GraphQL、CMSのどこが原因なのかを追う必要があります。
つらさ3:「公開中」の定義が散らばる
案件の公開判定自体は単純です。
const isJobOpen = (job) => job.opened === true
しかし、この条件はトップページ、案件一覧、条件別ページ、関連案件、詳細、ページネーション、サイトマップ、noindex判定のすべてに関係します。
実際、一時期はトップ、案件一覧、スキル別ページで意味の違う件数が、十分な説明なしに表示されていました。
現在はアプリケーション側の判定を共通化しています。
export const isJobOpen = ({ opened }) => opened === true
export const isJobClosed = (job) => !isJobOpen(job)
ただし、GraphQLのfilterには同じ関数を直接使えません。静的生成するページが増えるほど、同じビジネスルールを複数のレイヤーに重複して持ちやすくなります。
つらさ4:昔の「速く作れる」が今の「変更しづらい」になる
現在のプロジェクトには、Gatsby Themeのshadowing、Theme UI、通常のコンポーネント、JavaScript、TypeScriptが共存しています。
どれも、その時点で機能を早く追加するための現実的な選択でした。しかし今は、画面を直す前に「これはテーマ側か、shadowing側か、通常ページ側か」を探すことがあります。
最初に開発速度を上げてくれた構造が、サービスの成長後には理解と変更のコストになりました。
では、Gatsbyをどうするか
大量の既存URLを一度に移行するのは危険です。URL、canonical、構造化データ、サイトマップ、リダイレクトを誤れば、これまでの検索評価にも影響します。
そのため、今は次の順序が現実的だと考えています。
- 公開状態などのビジネスルールを共通化する
- CMSデータの欠損でGraphQLスキーマが変化しないようにする
- 生成するページとサイトマップを整理する
- 検索やマッチングなど、更新頻度の高い機能から静的生成の外へ分離する
- 移行するなら、SEOページとアプリケーション機能の境界を先に決める
Next.jsやAstroへ替えるだけでは、散らばったビジネスルールは直りません。フレームワーク選定より先に、データと責務の境界を整理する必要があります。
Gatsbyはクソだったのか
開発中には「Gatsby、つらい」「これどうするんだ」と言いたくなることがあります。
それでも、Gatsbyがなければ当時の私たちは会社サイトをあの速度で公開できなかったかもしれません。サーバー管理なしで始め、後からMicroCMSや案件ページを追加できたのも事実です。
Gatsbyが突然悪い技術になったわけではありません。
小さな会社サイトに合っていた構成を、前提が変わった後も拡張し続けた結果、現在の要件とのズレが大きくなった。
これが一番正確な振り返りです。
技術的負債は、間違った選択からだけ生まれるものではありません。当時は正しかった選択を、条件が変わった後も使い続けることでも生まれます。
同じように「会社サイトとして始めたGatsbyが、いつの間にか大きなサービスになっていた」という方がいれば、ぜひ経験を聞かせてください。
エンジビズのサイトはこちら
👨💻 執筆者・所属
株式会社UKMETA(https://ukmeta.jp/)
Web・アプリ受託開発、SES、ITフリーランス向けプラットフォーム「エンジビズ」を運営しています。