ジョブメドレーアカデミーのフロントエンドをNext.jsからVite + TanStack Routerに移行した話

はじめに

こんにちは。人材プラットフォーム ジョブメドレーアカデミー開発グループの池田です。ジョブメドレーアカデミーは、介護や障がい福祉、在宅医療などの各業種に特化した「オンライン動画研修サービス」と「勤怠・シフト管理サービス」をWeb・アプリの両方で提供しています。開発グループでは、これら両サービスの開発・運用を担当しています。

これまで、オンライン動画研修サービスのWebフロントエンドは Next.js で構築されていましたが、長期的な運用を見据えて Vite + TanStack Router への移行を行いました。本記事では、移行に至った理由と移行作業を紹介します。

移行理由について

Next.jsからViteへの移行を決定した背景は、以下の3つの理由が同時期に重なったことです。

依存関係による開発の制約

当初、デザインシステムの構築を見据え、Tailwind CSSやPanda CSSといったモダンなCSSライブラリの導入を検討していました。

しかし、当時使用していたNext.js v12が内部で保持するPostCSSのバージョンが古いために設定が競合し、導入には複雑な設定が必要であることが判明しました。また、v12自体がすでにサポート終了(EOL)を迎えており、セキュリティやメンテナンスの面でも使い続けるリスクが高まっていたため、バージョンアップまたは別構成への移行が必要な状況にありました。

デプロイツール「serverless-nextjs」のアーカイブ

インフラ構築には serverless-nextjs を使用していました。しかし、同ライブラリは現在アーカイブ(開発停止)されています。将来的なバグ修正などが困難になるため、配信基盤構築の手段を別の選択肢へ置き換える必要が生じていました。

プロダクト特性に合わせた技術スタックの見直し

Next.js採用時と現在ではフロントエンドのエコシステムが異なり、現在は多様な選択が可能になったと思います。そこで、改めてプロダクト特性などを踏まえて検討した結果、以下の観点からよりシンプルな構成が最適であると判断しました。

  • to Bサービスであり、ユーザー体験を優先する性質上、SEO観点での数値最適化(Core Web Vitals等)の必要性が比較的低い
  • バックエンドにGraphQLを採用しており、SSRを活用しようとするとキャッシュ管理等の設計が必要であり、実装コストがかかる
  • 検索やページネーション等のユーザー操作に伴う動的データが画面の大半を占めており、RSCを使用する恩恵を十分に享受できない

以上の理由から、Next.js の使用を継続するよりも、今のサービス特性に合わせた構成にするのが適していると考え、バージョンアップではなく Vite + TanStack Router へのリプレイスを決断しました。

移行作業について

ここからは、具体的な移行作業について紹介します。多岐にわたる作業の中から、本記事では特に大きな変更点である「ルーティング」と「インフラ」の2点を取り上げます。

TanStack Routerへの移行

next/routernext/link を使用していたルーティングは、TanStack Router へ移行しました。採用理由は、次の3点です。

  • パスやクエリパラメータを型安全に扱い、それに関する実装ミスをコンパイル時に検知したいため
  • 勤怠・シフト管理サービスと技術スタックを揃え、グループ内での知見共有をスムーズにしたいため
  • Next.js使用時と同じようにファイルベースルーティングを維持し、移行に伴う認知負荷を最小限に抑えるため

結果、クエリパラメータが型で管理されるようになったことで、これまで手動テストやE2Eテストでしか気付けなかったような不具合を、コードを書いている段階で(型エラーとして)検知できるようになりました。 加えて、どの画面でどのパラメータが使われているかが型から追いやすくなり、長期的な保守性の向上にもつながっています。

CloudFront Continuous Deployment の活用

Viteアプリケーションを配信するために、serverless-nextjs で構築されたCloudFront + S3 + Lambda@Edgeの構成から、CloudFront + S3の構成に移行することを行いました。

インフラ構成を簡素化できる一方で、大規模な刷新となるため、リリースにあたっては以下の要件を重視しました。

  • 万が一の際に、即座に旧構成(Next.js)へロールバックできること
  • ダウンタイムをゼロにすること(本番環境での正常動作を保証すること)

まず、これまで serverless-nextjs が構築していたリソース(CloudFront・Lambda@Edge)をTerraformで再定義しました。ライブラリ任せだったインフラ構成が可視化されたことに加え、旧構成に切り戻せる体制も整えることができました。

一方、ダウンタイムなしの切り替えを実現するために、CloudFront Continuous Deployment を活用しました。

CloudFront Continuous Deployment の構成図 出典 : CloudFront の継続的デプロイを使用して CDN 設定の変更を安全にテストする - Amazon CloudFront(Amazon Web Services, Inc.)

具体的には、既存の Next.js 配信用の設定をPrimary distribution(画像参照)におき、新しく構築したViteアプリケーション配信用の設定をStaging distributionとして用意しました。

CloudFront Continuous Deploymentでは、リクエストヘッダーまたはトラフィックレートに基づいてリクエストを振り分けることができます。今回は特定のヘッダーを付与した場合のみ Staging distribution へリクエストが流れるよう設定し、本番ドメインかつ本番環境と同じ条件下でViteアプリケーションの検証を行いました。

検証の結果、問題がないことを確認した上で、Staging distributionの設定を Primary distributionへ上書き(昇格)させました。このプロセスにより、ダウンタイムを発生させることなく、安全に新環境への切り替えを完了できました。

おわりに

今回は、ジョブメドレーアカデミーが提供するオンライン動画研修サービスのWebフロントエンドを Next.js から Vite + TanStack Router へ移行した取り組みを紹介しました。移行理由として挙げていた、プロダクト特性に合った技術スタックの見直しの達成に加え、他2点の課題も以下のように解決されました。

課題 移行後
依存関係による制約 Vite への移行により、PostCSS起因の競合が消え、Panda CSS などのライブラリが容易に導入可能になった。
デプロイツールの
アーカイブ
Terraform による IaC 管理に移行し、ライブラリに依存していたインフラ構成が可視化され、メンテナンスが容易になった。

また、上記の内容に加え、ビルド速度や画面遷移速度の向上といった改善も見られました。

プロダクトを長期的に提供できるよう、今後も機能開発と並行して技術基盤の見直しや改善に継続的に取り組んでいきます。

We’re hiring!

メドレーでは、プロダクトエンジニアをはじめ「医療ヘルスケアの未来」を共に創っていくエンジニアを大募集中です!少しでもご興味をお持ちいただけましたらぜひ、ご応募お待ちしております!

※カジュアル面談も大歓迎です!ご希望の際は、「その他の項目(希望記入欄)」にてその旨をご記載ください。