🚀

Nuxt4アップグレードガイドの内容を整理してみた

に公開

はじめに

Nuxt3 から Nuxt4 へのアップグレードは、公式の充実したガイドが用意されているため、基本的には記載されている手順に従って作業すれば問題ありません。

Upgrade Guide · Get Started with Nuxt v4

しかし、公式ガイドは分量が多く、項目も多岐にわたるため、全体像を把握するのに時間がかかります。この記事では、実際のアップグレード作業を通じて得た知見をもとに、公式ガイドのどこを重点的に読めばよいかを整理しました。

最終的には公式ガイドを参照して作業することになりますが、事前にこの記事を読むことで全体の作業を効率化できるはずです。

アップグレードの全体的な流れ

Nuxt4 アップグレードは、大きく 3 つのステップに分かれます:

ステップ 内容 目的
1. バージョンアップ Nuxt4 へのアップデート 最新バージョンの導入
2. 互換性設定の追加 v3 の挙動を維持する設定を追加 まず動かすことを優先
3. 段階的な移行 互換性設定を 1 つずつ外していく 安全な移行とビッグバンリリースの回避

Step 1: Nuxt4 へのバージョンアップ

公式ガイドのコマンドを実行して Nuxt4 にアップデートします。

Step 2: 互換性設定の追加による動作確認

この段階では、既存コードを大量に書き換える前に、まず動かすことが重要です。

  • 後述の「v3 の挙動を保持する設定」をすべて追加
  • 動作がおかしい部分があれば修正(特に互換性設定がない項目)
  • 型エラーが発生する可能性があるので対応
  • この時点で一度 PR レビュー&マージできると理想的

Step 3: 段階的な移行

互換性設定を1 つずつ外して動作確認とコード修正を行います。

  • codemodも活用
  • 影響範囲と原因を特定しやすくなる
  • こまめに PR マージができるためビッグバンリリースを避けられる
  • 全ての設定を外す必要はないが、将来的には移行が必要
  • フラグを残し続けると新機能が利用できず、負債化する可能性が高い

項目別の影響範囲と対応方法

実際のアップグレード作業を通じて感じた影響度をまとめました。
特に影響を受けやすいのは 「New Directory Structure」「Data Fetch(useFetch/useAsyncData)関連項目」 です。

項目名 Impact Level 影響を受けるケース(代表例) codemod v3 の挙動を保持する設定
New Directory Structure Significant ほぼ全プロダクト nuxt/4/file-structure export default defineNuxtConfig({ srcDir: '.', dir: { app: 'app' } })
Singleton Data Fetching Layer Moderate 同じキーで useAsyncData/useFetch を複数回呼んでいる export default defineNuxtConfig({ experimental: { granularCachedData: false, purgeCachedData: false } })
Corrected Module Loading Order in Layers Minimal Nuxt layers を使用してレイヤーの module 実行順に依存 なし(フックで対応)
Deduplication of Route Metadata Minimal route.meta.name などを直接参照 なし
Normalized Component Names Moderate @vue/test-utils の findComponent を使用、<KeepAlive>を使用 export default defineNuxtConfig({ experimental: { normalizeComponentNames: false } })
Unhead v2 Minimal useHead でvmid, hid, children, body等の削除済 API を使用 export default defineNuxtConfig({ unhead: { legacy: true } })
New DOM Location for SPA Loading Screen Minimal CSS またはdocument.queryElementで SPA loading template をターゲット export default defineNuxtConfig({ experimental: { spaLoadingTemplateLocation: 'within' } })
Parsed error.data Minimal error.data を手動で JSON.parse なし
More Granular Inline Styles Moderate グローバル CSS を使用(nuxt.config.tscssプロパティなど) export default defineNuxtConfig({ features: { inlineStyles: true } })
Scan Page Meta After Resolution Minimal pages:extend フックを使用 export default defineNuxtConfig({ experimental: { scanPageMeta: true } })
Shared Prerender Data Medium 複数ページで同一データを fetch している export default defineNuxtConfig({ experimental: { sharedPrerenderData: false } })
Default data and error values in useAsyncData and useFetch Minimal useAsyncData/useFetchdata.valueまたはerror.valuenullかチェック nuxt/4/default-data-error-value export default defineNuxtConfig({ experimental: { defaults: { useAsyncData: { value: 'null', errorValue: 'null' } } } })
Removal of deprecated boolean values for dedupe option Minimal refresh({ dedupe: true/false })を使用 nuxt/4/deprecated-dedupe-value なし
Respect defaults when clearing data Minimal clear/clearNuxtDataを使用 なし
Alignment of pending value in useAsyncData and useFetch Medium useAsyncData/useFetchpendingを使用 export default defineNuxtConfig({ experimental: { pendingWhenIdle: true } })
Key Change Behavior in useAsyncData and useFetch Medium useAsyncData/useFetchimmediate:falseを指定 export default defineNuxtConfig({ experimental: { alwaysRunFetchOnKeyChange: true } })
Shallow Data Reactivity in useAsyncData and useFetch Minimal data.valueの深い reactivity に依存 nuxt/4/shallow-function-reactivity export default defineNuxtConfig({ experimental: { defaults: { useAsyncData: { deep: true } } } })
Absolute Watch Paths Minimal nuxt.hook('builder:watch')でカスタム module が相対パスを期待 nuxt/4/absolute-watch-path なし
Removal of window.__NUXT__ object Minimal クライアントコードでwindow.__NUXT__を参照 なし
Directory index scanning Medium middleware ディレクトリに子ディレクトリが存在 なし
Template Compilation Changes Minimal ファイルシステム上の.ejsテンプレートを直接扱うコード生成 nuxt/4/template-compilation-changes なし
Default TypeScript Config Changes Minimal TS のnoUncheckedIndexedAccessに引っかかるコード export default defineNuxtConfig({ typescript: { tsConfig: { compilerOptions: { noUncheckedIndexedAccess: false } } } })
TypeScript Config Splitting Minimal なし(明示的に設定変更しなければ有効化されない) なし
Removal of Experimental Features Minimal 記載のフラグを使用 なし
Removal of Top-Level generate Config Minimal nuxt.config.tsgenerateオプションを使用 なし

実体験に基づく感想

小〜中規模なプロダクトであれば、以前の Nuxt2→3 のアップグレードとは打って変わって、非常にスムーズにアップグレードできるケースが多いと感じています。

実際に Vue ファイル数が 60 程度の小規模プロダクトで作業した際は、0.5 人日程度で完了することができました。

Nuxt4 のアップグレードガイドは非常に丁寧に作られており、段階的に移行できる仕組みが整っています。このガイドを参考に、ぜひスムーズなアップグレードを実現してください。

まとめ

  • 公式ガイドは充実しているが、全体像把握に時間がかかる
  • 「まず動かす」→「段階的移行」の 2 段階アプローチが効果的
  • New Directory Structure と Data Fetch 関連が影響を受けやすい
  • 小〜中規模プロダクトなら比較的短時間でアップグレード可能

時間がない方は、まずは「New Directory Structure」と「Data Fetch 関連」の項目だけでも事前に確認しておくと、作業時間の短縮につながると思います。

GitHubで編集を提案

Discussion