Nuxt 3からNuxt 4へのメジャーアップデート:手順とハマりどころ、対応工数まとめ
はじめに
この記事は レバテック開発部 Advent Calendar 2025 12日目の記事です。
この記事では、Nuxt 3からNuxt 4へメジャーアップデートした際の手順と感想を紹介します!
(最近はNext.jsの記事が多く、Nuxtの人達はどこにいったんだろう...とふと思うことがありますw)
まだまだサポート期限まで余裕があると思いきや、EOL(2026-01-31)が意外と迫っていたため、早めの対応を行いました。(すぐにNuxt5も来そうで怖い....
この記事でわかること
- Nuxt 4に上げた際の具体的な「ハマりどころ」
- 手動でのディレクトリ移行手順
- 実際のアップデート方法と対応工数
前提
-
構成
- Monorepo構成
- 879コンポーネント、85ページ、約113,000行
-
移行方針: 手動アップデート
- 公式がCodemodsを提供していますが、Monorepoかつ独自のディレクトリ構成を採用していたため、手動での対応を選択しました。
- fetch系の対応については事前に対応が済んでいるので触れません
- (追記する可能性があります)
対象読者
- Nuxt 4に上げたいが、工数が読めずなかなか着手できていない方
- 破壊的変更がどれくらいあるのか、具体的に知りたい方
アップデート手順
基本的には公式の Upgrade Guide に沿って進めればOKですが、実戦でのポイントを補足します。
手順1:Nuxt 4本体のアップデート
まずはコマンドでアップグレードを実行します。
yarn nuxt upgrade
Nuxt 4に上げた後にtypecheckを実行すると、プロダクトによっては noUncheckedIndexedAccessエラーや、今まで検出されなかった型エラーが多数発生する可能性があります。
今回対応したプロダクトでは、合計360件程度のエラーが発生しました😭
-
noUncheckedIndexedAccess: 配列アクセス時の
undefined考慮など。数が多すぎるため、今回はtsconfigでfalseに設定し、一時的に回避(別タスクで対応予定)。 - その他のエラー: 引数なし/ありイベントの混在など。こちらはロジック修正で対応。
まずはここでtypecheckのエラーを潰しきれば、第一段階はクリアです。
手順2:app ディレクトリへの移行(破壊的変更)
ここが最大の山場です。前提の通り、今回は手動でディレクトリ整理を行いました。
元々src配下などで管理していたcomponentsやmiddlewareなどを、Nuxt 4推奨の app ディレクトリ構成へ移動させます。
▼ 変更後のディレクトリ構成イメージ
.
├── .output/
├── .nuxt/
├── app/ <-- 新設(クライアントサイドのコードを集約)
│ ├── assets/
│ ├── components/
│ ├── composables/
│ ├── layouts/
│ ├── middleware/
│ ├── pages/
│ ├── plugins/
│ ├── utils/
│ ├── app.config.ts
│ ├── app.vue
│ └── router.options.ts
├── content/
├── layers/
├── modules/
├── node_modules/
├── public/
├── shared/ <-- 新設(Server/Client共有の型やUtils)
├── server/ <-- Nitroなどサーバーサイドコード
│ ├── api/
│ ├── middleware/
│ ├── plugins/
│ ├── routes/
│ └── utils/
└── nuxt.config.ts
⚠️ ここでの注意点(tsconfigの罠)
ディレクトリ移動時に大量のPathエラーが出ますが、焦ってコードを修正しないことが大切です!
今回のアップデートでtsconfigの生成ルールが変わり、役割ごとにファイルが分割されるようになりました。これにより、以前"extends": "./.nuxt/tsconfig.json"だけで効いていた型定義が効かなくなる可能性があります。
-
.nuxt/tsconfig.app.json: Vue コンポーネントなどアプリコード用 -
.nuxt/tsconfig.server.json: Nitro などサーバーコード用 -
.nuxt/tsconfig.node.json: ビルドタイム用(modules, nuxt.config.tsなど) -
.nuxt/tsconfig.shared.json: アプリ・サーバー共有用 -
.nuxt/tsconfig.json: 後方互換用のレガシー設定
また、ServerとClient側で共通して使用していた型定義ファイルなどは、新設されたshared/配下に移行しました。
Use the shared/ directory to share functionality between the Vue app and the Nitro server.
手順3:Config周り&テスト修正
ディレクトリ構造の変更に伴い、設定ファイルのパス修正を行います。
-
パスの修正:
-
.storybook/main.tsのパス修正 -
nuxt.config.tsのsrcDirを修正 -
testsディレクトリのパス解決(nuxt.config.tsのtsConfigオプションで拡張)
-
-
tsconfig設定の移行:
- これまで
tsconfig.jsonに直接書いていた拡張設定は非推奨となりました。今後はnuxt.config.ts経由で設定します。
- これまで
We do not recommend modifying the contents of this file directly... Instead, extend it via nuxt.config.ts.
ハマりポイント
今回の対応で最も伝えたい教訓はこれです!
「appディレクトリ変更時に出る型エラーは、コード修正の前に tsconfig周りを見直せ!」
公式には Impact Level: Minimal(影響レベル:最小) と書いてありますが、実際の影響は結構大きかったです(笑)。
私はディレクトリ変更時に発生した大量の型エラーを、コード側で一つずつ修正しようとしてしまい、結果的に後戻り作業が発生しました。実はtsconfig.json周りの設定を公式ドキュメントベースに正しく修正すれば、それだけでエラーの殆どが解消しました。
srcをパス指定している箇所はプロダクトによって異なると思うので、まずは設定周りを疑って確認しましょう。(公式ドキュメントは何度でも読もう)
Monorepo・大規模開発での進め方
一度にすべてやろうとせず、以下のサブタスクに切って進めることで、早期解決が図れました。
- Nuxt 4アップデート
- appディレクトリへの変更
- Config周りの修正
- テスト修正(Snapshot更新含む)
こまめにcommitし、typecheckを回すのがおすすめです。
既存開発との兼ね合い(ブランチ戦略)
「機能開発を止めてメジャーアップデート対応だけ行う」というのは現実的に難しいですよね。私のチームでも機能開発が進行中だったため、以下のようなフローで進めました。
-
developからfeature/nuxt_4ブランチを切る。 - 既存開発のコンポーネント実装などは、完了次第
developにマージしていく。(※細かいブランチ運用については触れません) -
feature/nuxt_4は、最後にdevelopを取り込みコンフリクトを解消する。- 作業は基本的に「
appディレクトリに入れ直すだけ」なので、コンフリクト解消の負担は少ない。
- 作業は基本的に「
- テストを行い、問題なければ本番リリース。
- その後、既存機能の画面構築フェーズへ入る。
万が一不具合があった場合の切り戻しにも対応しつつ、既存の機能も開発できるような進め方にしました!(本来であれば、既存で進めている機能を全てリリースしきるか、別の機能開発が進んでいない時にアップデートした方が良いかと思いますが、開発状況的にはこの対応がベストだと判断しました。)
対応工数
プロダクトの規模や実装状況にもよりますが、アップデート作業自体は2日(実働 10時間強)で完了しました。
※ ここで言う「完了」とは、storybook起動、typecheck、lint、コンポーネントテスト、build が正常に通る状態を指します(本格的なQA工数は含んでいません)。
比較的スムーズに進んだ要因として、事前にチームで「Upgrade Guideの読み合わせ会」を行っていたことが挙げられます。これにより、着手前に主な変更点と影響範囲のイメージをチーム内で共有できていたのが大きかったです。
今回はMonorepo構成で大きく2箇所の対応が必要だったことや、他のタスクの合間に進めたことを考慮すると、構成によっては1日で作業が終わるチームもあるのではないかと思います。
まとめ
今回のアップデートは、既存の型定義の甘い部分が浮き彫りになるような、「厳格化」を感じるものでした。しかし、ある程度の互換性を保ったまま移行できたので、過去のNuxt(Vue)の反省が活かされていると感じます。
Nuxt 4へのアップデートを検討中の方、ライブラリやフレームワークのアップデートは計画的に行いましょう!
Discussion