e-dash株式会社でフロントエンジニアを務める陳 文風(Bunfuu Chin)です。今回は、弊社がVue.jsからNext.jsへ移行した背景や、技術選定の経緯・課題についてお話します。
弊社は企業のCO2排出量の可視化・削減を支援するSaaSを開発・運営しているスタートアップです。 2022年の創業当初はVue.jsとPHPを組み合わせたシステムを開発していました。 しかしプロダクトが成長するにつれ、SaaSの拡張性やスケーラビリティ、メンテナンス性などの課題が顕在化したため、2023年8月に移行検討を開始、2024年4月にNext.jsへの移行を実施しました。
Vue.js 採用の背景と課題の顕在化
当時、Vue.jsを採用した理由
- 小規模チームでも素早く開発できる
- PHPとの親和性が高い
- 学習コストが低く導入しやすい
- 状態管理を意識せずシンプルに開発できる
- 外部エンジニアがVueに慣れていた
こうした理由から、創業当初はスピード重視でVue.jsを選定していました。
拡大するプロダクトと明るみに出た課題
プロダクトが大きくなるにつれて以下の問題が顕在化しました。
- 設計の統一やスケーラビリティの確保が困難
- Vue.jsのシンプルさが仇となり、大規模化での一貫したアーキテクチャの維持が難しくなる
- PHPとの密結合が拡張を阻害
- VueとPHPが入り組む構造により、柔軟なアップデートや機能追加が難しくなる
- Vue2のサポート終了とVue3への移行コストの高さ
- Vue2からVue3への移行には大幅な修正が必要で、実施の場合、開発リソースを圧迫する
- 型安全性の不足
- 製品規模拡大に伴う複雑化で、型安全なReactやTypeScriptの必要性が高まった
- エンジニアのReact知見の活用
- チーム内にReactの経験者が多く、メンバーの技術統一が図りやすかった
以上の背景から、ReactベースのフレームワークであるNext.jsへの移行が必須だと判断し、リプレイスの実施に至りました。
Next.jsへの移行と新たな技術スタック
ここからは、弊社がどのようにNext.jsを採用し、新たな技術スタックを整備しているのかについて詳しくご紹介します。
理由①:PHPのLTSサポート終了と長期的な安定性
移行の大きな理由のひとつとして、PHPのLTSサポート終了による長期的な安定開発の確保の必要性がありました。
移行前の PHP 7.3 + Vue2はコードベースが古く保守が難しい状況でした。そのため移行後はReact + Next.jsを採用し、モダンな技術に統一することにより、スケーラビリティとメンテナンス性の大幅な向上を図りました。 特にNext.jsのPages Routerを採用したのは、開発実績があったことに加え、その当時(2023年8月頃)のApp Routerが仕様変更リスクを伴うことを考慮したからです。 ※2025年3月現在は、その安全性を確認しながら一部のプロダクトでApp Routerを導入し、段階的な移行を進めています。
このように技術スタックを刷新することで、開発生産性を向上させつつ、長期的な運用に耐えうる環境を整備できました。
理由②:開発の統一と効率化
Vue.jsでの開発は、コードの書き方やライブラリ利用がチーム内での統一がされていないことが大きな課題でした。
例えば、コンポーネントの共通化が不十分なまま同じような画面コンポーネントが増えていたり、状態管理ルールが不明確だったために開発規模が大きくなるにつれて管理が煩雑になっていたりするなどの問題がありました。
Next.jsへ移行することで、これらを共通UIライブラリや標準化したコンポーネント構成で再編し、状態管理が統一され、データ取得や型の扱いが明確になりました。結果として、可読性・拡張性が向上し、開発スピードも大幅に改善することに成功しました。
理由③:型安全性とパフォーマンス向上
Vue2環境では大規模開発を行う上で、状態管理やAPI通信などにおける型の整合性を確保しづらい点がありました。
React + TypeScriptを採用することにより、型の整合性が保証され、事前に型エラーを検知し、バグを未然に防止出来る環境になりました。また、SSR(サーバーサイドレンダリング)による高速なページ表示が可能になり、結果的に保守性が飛躍的に高まり、チーム全体で柔軟かつ高速に開発できる体制が整いました。
フロントエンド実装の具体例:Zod, React Hook Form, MSW
次に、弊社が実際に導入しているフロントエンドの実装例をご紹介します。
ZodとReact Hook Formを使ったフォームバリデーションの実装
Zodを使うメリットは、バリデーションルールとTypeScriptの型を統一できる点にあります。これにより、実装や保守の煩雑さを大幅に軽減できます。
さらに、React Hook Formと@hookform/resolversを組み合わせることで、Zodのスキーマを簡単にフォームのバリデーションへ反映可能です。
- Zodでフォームスキーマを定義
- それをresolverとしてReact Hook Formに渡すことで、自動的にバリデーションが行われる
このように、入力変更時や送信時に型安全かつスムーズなバリデーションが実現できるため、大規模プロジェクトでも柔軟に対応できます。
MSW(Mock Service Worker)とOpenAPIを用いたMock APIの実装
次に、API開発やテスト効率を高めるために導入しているのが、MSW(Mock Service Worker)とOpenAPIの組み合わせです。
OpenAPIから型定義を自動生成できるため、APIの仕様変更にも強く、MSWによってモック化が容易に行えます。
実装時は以下の流れで進めます。
- OpenAPI仕様から自動生成された型をレスポンス型として活用
- MSWでmockサーバーを立ち上げ、定義したレスポンスを返却
- handlersをエクスポートして、開発環境でもモックAPIを使えるように設定
e-dashでは別のプロダクトで、OpenAPIとMSWを使ってモックAPIを自動生成する仕組みを既に導入しており、今回のプロダクトについても今後は同様の方法でMock APIを拡充していく予定です。
現在の課題と今後の展望
ここまでで、Next.jsベースへの移行によって得られたメリットや実装例をご紹介しましたが、すべての課題が解決したわけではありません。最後に、現在の課題と今後の方向性についてまとめます。
まず挙げられるのがMaterial UIに関する課題です。 MaterialUIはライブラリ自体が大きいため、バンドルサイズやパフォーマンスに影響が出たり、デフォルトのスタイルが強く、細かいデザイン調整に手間がかかります。
そのため、現在はRadix UIをベースに社内で独自のUIコンポーネントライブラリ「e-dash UI」を構築する方針を進めています。将来的にはこのライブラリを全面的に導入し、より統一的なデザインと高い拡張性を実現していく予定です。
また、状態管理の最適化も目指し、JotaiやZustand、TanStack Queryなど、開発が活発なライブラリへの移行を検討し、より柔軟でメンテナブルな状態管理を目指していく方針です。
以上、Vue.jsからNext.jsへの移行にまつわる現状の課題と展望でした。[1]
We Are Hiring!
-
本記事は、2025年3月17日に開催されたイベントの内容を元に編集した記事です。 ↩