
こんにちは。開発チームでフロントエンドを担当している芳賀です。
Nuxt 4 がリリースされましたね! kickflowでも、この度Nuxt 4へのアップグレード対応を行いました 🎉
結論から言うと、移行作業は想像以上にスムーズでした。これは、Nuxt 4の優れた後方互換性と、AIによる強力なサポートがあったからだと感じています。 本記事では、kickflowが実践したNuxt 4への移行プロジェクトの全貌をご紹介します。
変更点の調査
まず初めに、Nuxt 3からNuxt 4へのアップグレードに伴う変更点を調査しました。 今回は、AIツールを活用して効率的に情報を収集しました。以下がkickflowのプロダクトに影響がありそうだと判断した主な変更点です(影響がありそうな項目に ⭐️ を付けています)。
- ⭐️ インストール・アップグレード:
npm install nuxt@^4.0.0でアップグレード可能です。また、npx codemod@latest nuxt/4/migration-recipeという自動移行ツールが提供されています。 - ⭐️ 新しいディレクトリ構造: デフォルトの
srcDirがapp/に変更されます。assets/,components/,composables/,layouts/,middleware/,pages/,plugins/,utils/,app.vue,error.vue,app.config.tsをapp/内に移動する必要があります。ただし、後方互換性があるため、すぐに対応しなくても動作します。 - データフェッチング:
useAsyncData/useFetchで同じキーのrefが共有されるようになり、getCachedDataが毎回呼び出されるようになります。リアクティブキーのサポートが追加され、データクリーンアップ機能も改善されました。 - コンポーネント名の正規化: Vueコンポーネント名がNuxtの命名パターンと一致するように正規化されます。
- Unhead v2への更新:
<head>タグを生成するライブラリが更新され、一部プロパティが削除されました。 - CSSインライン化: Vueコンポーネントのスタイルのみがインライン化されるようになります(グローバルCSSは対象外)。
- プリレンダーデータ共有: 同じデータを使用するページ間でペイロードデータが自動的に共有され、パフォーマンスが向上します。
- shallowRefの採用:
useAsyncData等のdataがパフォーマンス向上のためshallowRefに変更されました。 window.__NUXT__の削除: ハイドレーション後にグローバルオブジェクトが削除されます。今後はuseNuxtApp().payloadを介してアクセスする必要があります。- ⭐️ TypeScript設定の改善と分離:
noUncheckedIndexedAccess: trueがデフォルトになり、コンテキスト別のtsconfigが生成されるようになります。 generate設定の廃止:generate.excludeやgenerate.routesはnitro.prerenderに移行します。
特に影響が大きいのは、やはりディレクトリ構成の変更とTypeScriptの設定変更でした。
事前検証
変更点の調査が完了したところで、次に事前検証を行いました。
Nuxt 3.12から導入された compatibilityVersion というフラグを利用することで、Nuxt 3環境のままでNuxt 4相当の振る舞いを先取りして検証できます。
export default defineNuxtConfig({ future: { compatibilityVersion: 4 // ← Nuxt 4 相当の振る舞いを有効化 } })
この設定を有効にして、kickflowで利用している主要なコマンドを実行した結果がこちらです。
| コマンド | 実行結果 |
|---|---|
yarn build |
✅️ 問題なし |
yarn test |
✅️ 問題なし |
yarn lint |
✅️ 問題なし |
yarn typecheck |
⚠️ Nuxt 4起因の型エラーが発生 |
yarn build や yarn test は問題なく通りましたが、yarn typecheck で 392個もの型エラーが検出されてしまいました。
これは主に、TypeScriptの設定変更(noUncheckedIndexedAccess: true)に起因するものです。
このまま公式のマイグレーションガイドに従って単純にアップグレードを進めると、開発に大きな支障が出ると判断し、慎重に移行計画を立てることにしました。
移行計画
やることの整理
まず、移行に際して「やること」を整理し、優先度を付けました。
| 優先度 | やること | 対応案 |
|---|---|---|
| ❗️ 必須 | 型エラーの修正 | 移行前にすべて解消する |
| ❗️ 必須 | Nuxt 4へのバージョンアップ | 型エラー修正後に対応する |
| ⚠️ 優先 | 新しいディレクトリ構成への移行 | バージョンアップのタイミングで実施する |
| ℹ️ 任意 | フロントエンドのディレクトリ名変更 | 移行完了後に別タスクとして対応する |
必須作業はライブラリの更新と型エラーの修正のみです。 Nuxt 4の新しいディレクトリ構成は後方互換性があるため、すぐに対応する必要はありませんが、今後のメンテナンス性を考慮して今回の計画に含めることにしました。
また、関連タスクとして「フロントエンドのソースコードが配置されているディレクトリ名を変更したい」という要望も上がっていましたが、問題発生時の切り分けを容易にするため、Nuxt 4移行が完了した後に別件として対応することにしました。
立てた移行計画
上記の整理に基づき、以下の5ステップで移行を進める計画を立てました。
① Nuxt 3環境で型エラーを修正
ローカル環境でのみ compatibilityVersion: 4 を有効にし、Nuxt 3のままで事前に型エラーをすべて修正します。
エラー数が多いため、AIを積極的に活用して修正作業を効率化する想定です。
ℹ️ この時点での状態
- Nuxtのバージョン: 3
-
compatibilityVersion: なし(ローカルでは4を指定) - ディレクトリ構成: Nuxt 3のまま
② compatibilityVersion: 4 を本流に適用
型エラーの修正が完了したら、compatibilityVersion: 4 の設定をコミットして、masterブランチにマージします。
これにより、CI上で常にNuxt 4互換の型チェックが実行されるようになり、新たな型エラーの発生を防ぎます。
ℹ️ この時点での状態
- Nuxtのバージョン: 3
-
compatibilityVersion: 4 - ディレクトリ構成: Nuxt 3のまま
③ Nuxtのライブラリをバージョンアップ
いよいよNuxt 3からNuxt 4へバージョンアップします。 この時点ではまだディレクトリ構成は古いままですが、Nuxtが自動で検出してくれるため問題なく動作します。この互換性は非常にありがたいですね。
ℹ️ この時点での状態
- Nuxtのバージョン: 4
-
compatibilityVersion: 4 - ディレクトリ構成: Nuxt 3のまま
④ ディレクトリ構成を変更
公式のマイグレーションツールやAIを活用して、Nuxt 4の新しいディレクトリ構成に移行します。 この変更は多くのファイル移動を伴うため、他の開発メンバーの作業ブランチにコンフリクトなどの影響を与える可能性があります。 そこで、事前に移行作業日をアナウンスし、その日はフロントエンドのコードマージを一時的に停止してもらうよう協力を依頼しました。
ℹ️ この時点での状態
- Nuxtのバージョン: 4
-
compatibilityVersion: 4 - ディレクトリ構成: Nuxt 4の構成
⑤ compatibilityVersion を削除
Nuxt 4へのアップグレードとディレクトリ構成の移行が完了したため、後片付けとして compatibilityVersion の設定を削除します。
これで、すべての移行作業が完了です。
ℹ️ この時点での状態
- Nuxtのバージョン: 4
-
compatibilityVersion: 削除 - ディレクトリ構成: Nuxt 4の構成
移行作業の実際
結果として、移行はほぼ計画通りに進めることができました。 想定外だったのは、ディレクトリ構成の変更時にマイグレーションツールがうまく動作しなかった点ですが、これはAI(社内の秘蔵 Claude code サブエージェント)を活用することで無事に乗り切れました。
また、移行当日は、開発チームの皆さんにフロントエンドに関する作業を調整していただくなど、多大なご協力をいただきました。この場を借りて改めて感謝申し上げます。
まとめ
正直なところ、以前のNuxt 2からNuxt 3への移行経験から、今回のアップグレードも大きな手術になるのではないかと少し身構えていました。 しかし、実際に着手してみると、想像以上にスムーズに移行を完了できたというのが率直な感想です。
スムーズに進んだ要因は、主に以下の3点だと考えています。
- 破壊的変更が少なく、後方互換性が手厚く考慮されていたこと
compatibilityVersionにより、段階的な移行が可能だったこと- AIのサポートにより、大量の型エラー修正などを効率化できたこと
ちなみに、他のエンジニアからは「いつの間にかNuxt 4になっていて、移行した実感がなかった」というコメントをもらいました(笑)。それくらい、開発を止めることなく「ぬるっと」移行できた証かもしれません。
kickflowは無事にNuxt 4という新たな基盤への移行を完了しました。これからも、モダンな技術を積極的に活用し、プロダクト開発を加速させていきます。
本記事が、これからNuxt 4への移行を検討されている方々の助けになれば幸いです。
kickflowでは、モダンな技術スタックで開発したいエンジニアを募集しています! ご興味のある方は、ぜひ採用サイトをご覧ください。