概要
Nuxt4 は、Nuxt.js の最新バージョンであり、パフォーマンス、開発者エクスペリエンス、機能性の向上など、多くの新機能と改善が盛り込まれています。Nuxt3 から Nuxt4 への移行は、一応の後方互換性はありますが、いくつかの破壊的変更を含むため、注意が必要です。本記事では、Nuxt4 の新機能、破壊的変更、そしてスムーズな移行方法について詳しく解説します。
Nuxt4 の新機能と改善
Nuxt4 は、パフォーマンスや開発効率、機能性などの面で、多くの改善が入りました。主な新機能は以下の通りです。
-
Nitro エンジンの完全統合:
Nuxt4 は、サーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) を高速化する Nitro エンジンを採用しています。Nuxt3 でも Nitro エンジンは採用されていましたが、Nuxt4 ではより洗練され、統合され、より強力になっています。主な違いは以下です。-
Nuxt3 の Nitro エンジン
-
サーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) のための基盤:
Nuxt3 は、Nitro エンジンを使用してサーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) を実行していました。しかし、これは主にサーバーサイドレンダリングに焦点を当て、静的サイト生成はセカンドクラスの機能でした。 -
serverMiddleware
ディレクトリの使用:
サーバーサイドのミドルウェアや API エンドポイントを定義するために、serverMiddleware
ディレクトリが使用されていて、アプリケーションの構造を複雑にする可能性がありました。 -
API ルーティングの制限:
API ルーティング機能はありましたが、serverMiddleware
に大きく依存しており、複雑な API を構築するには不十分な場合がありました。 -
Nitro パッケージの依存:
Nitro は Nuxt3 のパッケージとして別々に使用されていました。
-
サーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) のための基盤:
-
Nuxt4 の Nitro エンジン
-
完全統合:
Nuxt4 では、Nitro エンジンが完全に統合され、アプリケーションのすべての側面を強化するコア機能として設計されています。 -
サーバーサイドレンダリングと静的サイト生成の最適化:
Nitro エンジンは、サーバーサイドレンダリングと静的サイト生成の両方を効率的に処理するように最適化されています。特に静的サイト生成はより高速で効率的になりました。 -
server
ディレクトリの導入:
サーバーサイドコードを管理するための新しいserver
ディレクトリが導入されました。これにより、サーバーサイドコードの構成がより明確になりました。 -
強力な API ルーティング:
Nuxt4 は、より強力な API ルーティングシステムを提供し、複雑な API を簡単に構築できます。 -
Nitro モジュールの導入:
Nitro エンジンの機能を拡張するための Nitro モジュールが導入されました。
-
完全統合:
-
-
Vue3 への完全移行:
Nuxt4 は、Vue3 をベースに構築されており、Vue3 の最新機能とパフォーマンスの向上を享受できます。 -
TypeScript の強化:
Nuxt4 は、TypeScript のサポートを強化し、開発中の型安全性をより高めています。 -
ユニバーサルなルーティング:
Nuxt4 では、サーバーサイドとクライアントサイドの両方に共通のルーティングシステムが採用されています。 -
モジュールシステムの進化:
Nuxt4 では、モジュールシステムが進化し、より柔軟性が高くなりました。 -
新しい API ルーティング:
Nuxt4 は、API ルーティングの新しい仕組みを提供し、API の開発を容易にします。 -
Composition API の活用:
Nuxt4 は、Vue3 の Composition API を全面的に採用しています。
Nuxt3 との破壊的変更
Nuxt4 は、Nuxt3 と比較していくつかの破壊的変更を導入しています。移行前に、これらの変更点を理解しておくことが重要です。
1. Nitro エンジンによるファイル構造の変更
影響レベル: 重要
Nuxt4 は Nitro エンジンの統合を強化したことで、ファイル構造が大きく変わりました。以前の pages
ディレクトリは app
ディレクトリに置き換えられ、サーバーサイドコードや API エンドポイントを管理する新しい server
ディレクトリが導入されました。
Nuxt3では各ディレクトリがルートレベルに配置されていたのに対し、Nuxt4では、app
ディレクトリがアプリケーションの主要なコンポーネントをまとめ、server
ディレクトリがサーバーサイドコードを管理します。
変更の理由
- パフォーマンス - すべてのコードをリポジトリのルートに配置すると、.git/とnode_modules/フォルダがFSウォッチャーによってスキャン/含まれる問題が発生し、Mac OS以外のOSでの起動が大幅に遅延する可能性があります。
- IDEの型安全性 - server/とアプリの残りの部分は、利用可能な異なるグローバルインポートを持つ全く異なるコンテキストで実行されているため、server/がアプリの残りの部分と同じフォルダ内にないようにすることで、IDEで自動補完が競合しないように改善されています。
Nuxt3とNuxt4のディレクトリ構造比較
// Nuxt3
├── components
│ ├── MyComponent.vue
│ └── ...
├── pages
│ ├── index.vue
│ ├── about.vue
│ └── ...
├── store
│ └── ...
├── plugins
│ └── ...
├── static
│ └── ...
├── assets
│ └── ...
└── nuxt.config.js
// Nuxt4
├── app
│ ├── app.vue
│ ├── components
│ │ ├── MyComponent.vue
│ │ └── ...
│ ├── pages
│ │ ├── index.vue
│ │ ├── about.vue
│ │ └── ...
│ └── layouts
│ └── default.vue
├── server
│ └── api
│ └── users.js
└── nuxt.config.ts
主な違い
-
app.vueの移動: Nuxt3 では
app.vue
ファイルはルートレベルにありましたが、Nuxt4 ではapp
ディレクトリ内に移動しています。 -
各ディレクトリの移動: Nuxt3 では
pages
、components
、composables
、assets
、layouts
、utils
ディレクトリはルートレベルにありましたが、Nuxt4 ではapp
ディレクトリ内に移動しています。middleware
は、クライアントサイドで使う場合はapp
ディレクトリ内に、サーバーサイドで使う場合はserver
ディレクトリ内に置くことができます -
server
ディレクトリの追加: Nuxt4 では、サーバーサイドコードや API エンドポイントを管理するためのserver
ディレクトリが追加されました。 -
nuxt.config.js
の変更: Nuxt4 では、nuxt.config.js
ファイルがnuxt.config.ts
ファイルに置き換えられています。
補足
- Nuxt4 では、
app
ディレクトリ内にassets
ディレクトリを作成することができます。public
ディレクトリは、従来通りルートレベルにしか置けません。public
ディレクトリとassets
ディレクトリの使い分けは従来通り、ビルドに含めずに利用したいファイルはpublic
ディレクトリに入れます。 -
server
ディレクトリは、API エンドポイントやサーバーサイドレンダリング機能などを実装するための場所となります。 - Nuxt4 のディレクトリ構造は、アプリケーションの規模や複雑さに合わせて調整することができます。例えば、中規模以上のアプリケーションで、複数の機能を持つときは下記のようにフォルダ構成を変更することも可能です。
// Nuxt4 中規模アプリケーションの例
├── app
│ ├── features
│ │ ├── blog
│ │ │ ├── components
│ │ │ └── pages
│ │ └── auth
│ │ ├── components
│ │ └── pages
│ ├── components
│ │ └── MyComponent.vue
│ ├── layouts
│ │ └── default.vue
│ └─── utils
│ └── default.vue
├── server
│ ├── api
│ │ ├── users.js
│ │ └── articles.js
│ └── middlewares
│ └── auth.js
└── nuxt.config.ts
2. ルーティングシステムの変更
影響レベル: 重要
Nuxt4 では、ルーティングシステムが変更され、pages
ディレクトリ内のファイルが、サーバーサイドとクライアントサイドで共有されるようになりました。
// Nuxt3
export default defineNuxtConfig({
// ...
router: {
// ...
},
})
// Nuxt4
export default defineNuxtConfig({
// ...
app: {
head: {
// ...
},
},
})
3. Composition APIの推奨とデフォルト設定
影響レベル: 小程度
Nuxt4 では、Options APIではなく、Composition API を使用することが推奨されています。Nuxt3でもComposition APIは使えましたが、Nuxt4ではデフォルトで <script setup>
が有効になります。
// Options API
<script>
import { ref, defineComponent } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
function increment() {
count.value++
}
return {
count,
increment,
}
},
})
</script>
<template>
<div>
<h1>{{ count }}</h1>
<button @click="increment">+</button>
</div>
</template>
// Composition API
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
<div>
<h1>{{ count }}</h1>
<button @click="increment">+</button>
</div>
</template>
4. Nuxt.js モジュールの廃止
影響レベル: 小程度
Nuxt4 では、以前の Nuxt.js モジュールは廃止され、代わりに Nitro モジュールが導入されました。Nitro モジュールは、Nuxt.js モジュールより効率的で柔軟性が高く、高速に実行され、アプリケーションの起動時間を短縮できるというメリットがあります。
5. 共有プリレンダリングデータ
影響レベル: 中程度
変更点:
-
useAsyncData
とuseFetch
の呼び出し結果を異なるページ間で共有する機能が有効化されました。
変更理由:
- 複数のページで同じデータを取得する際に、プリレンダリング段階で一度だけデータを取得することでパフォーマンスを大幅に向上させることができます。
- 例えば、サイト全体で共通のメニューデータやサイト設定データを取得する場合、この機能により、ページのプリレンダリング時に一度だけデータを取得し、他のページでキャッシュされたデータを使用できるようになります。
移行手順:
- データの一意のキーが常に同じデータに紐づくことを確認します。
useAsyncData
でデータを取得する場合は、データを一意に識別するキーを提供する必要があります。useFetch
は自動的にキーを生成します。 - 必要に応じて、
nuxt.config.ts
でexperimental.sharedPrerenderData
オプションをfalse
に設定することで、この機能を無効にすることができます。
例:
// app/pages/test/[slug].vue
<script setup>
const route = useRoute()
// これは動的ページでは安全ではありません。
// Nuxt はキーにスラッグを反映しないため、データの一致が保証されません。
const { data } = await useAsyncData(async () => {
return await $fetch(`/api/my-page/${route.params.slug}`)
})
// 代わりに、データを一意に識別するキーを使用します。
const { data } = await useAsyncData(route.params.slug, async () => {
return await $fetch(`/api/my-page/${route.params.slug}`)
})
</script>
6. useAsyncData
と useFetch
のデフォルト値
影響レベル: 最小
変更点:
-
useAsyncData
から返されるdata
とerror
オブジェクトは、デフォルトでundefined
になります。
変更理由:
- 以前は
data
はnull
で初期化され、error
はnull
で初期化されていました。この変更により、より一貫性のある挙動を実現しています。
移行手順:
- 必要に応じて、
nuxt.config.ts
でexperimental.defaults.useAsyncData
オプションを使用することで、以前の挙動に戻すことができます。
7. useAsyncData
と useFetch
の refresh
オプション
影響レベル: 最小
変更点:
-
refresh
オプションのdedupe
オプションのブール値エイリアス (true
はcancel
、false
はdefer
) が削除されました。
変更理由:
- ブール値エイリアスはわかりにくく、混乱を招く可能性があったため、削除されました。
移行手順:
-
refresh
オプションにcancel
またはdefer
を指定するようにコードを変更します。
8. useAsyncData
と useFetch
のデータクリア
影響レベル: 最小
変更点:
-
useAsyncData
にカスタムのデフォルト値が設定されている場合、clear
またはclearNuxtData
を呼び出す際に、デフォルト値が使用されるようになりました。
変更理由:
- データをリセット/クリアする際に、カスタムのデフォルト値を尊重することで、より適切な挙動を実現しています。
移行手順:
- 必要に応じて、
nuxt.config.ts
でexperimental.resetAsyncDataToUndefined
オプションを使用することで、以前の挙動に戻すことができます。
9. useAsyncData
と useFetch
のリアクティビティ
影響レベル: 最小
変更点:
-
useAsyncData
、useFetch
、useLazyAsyncData
、useLazyFetch
から返されるdata
オブジェクトは、shallowRef
になりました。
変更理由:
- データオブジェクトのリアクティビティを浅くすることで、パフォーマンスを向上させることができます。
移行手順:
- 必要に応じて、
deep
オプションを使用して、データオブジェクトのリアクティビティを深くすることができます。
10. builder:watch
フックの絶対パス
影響レベル: 最小
変更点:
-
builder:watch
フックは、プロジェクトのsrcDir
に対する相対パスではなく、絶対パスを発行するようになりました。
変更理由:
- これにより、
srcDir
外のパスの監視をサポートし、より複雑なプロジェクト構造に対応できるようになりました。
移行手順:
- ほとんどの場合、移行手順は必要ありません。必要に応じて、コードを調整してください。
11. ディレクトリインデックススキャン
影響レベル: 中程度
変更点:
-
middleware
フォルダの子フォルダもインデックスファイルがスキャンされ、ミドルウェアとして登録されるようになりました。
変更理由:
- Nuxt は、
middleware
とplugins
などのフォルダを自動的にスキャンします。この動作を他のフォルダにも拡張することで、より一貫性のある挙動を実現しています。
移行手順:
- 必要に応じて、フックを使用してミドルウェアをフィルタリングすることで、以前の挙動に戻すことができます。
12. テンプレートコンパイル
影響レベル: 最小
変更点:
- Nuxt は、
lodash/template
を使用してテンプレートをコンパイルする機能を廃止しました。
変更理由:
-
lodash/template
はセキュリティ問題を抱えており、重い依存関係でした。
移行手順:
-
getContents
関数を使用するか、プロジェクトの依存関係としてlodash
を使用することで、テンプレートをコンパイルしてください。
13. 実験的機能の削除
影響レベル: 最小
変更点:
- 一部の設定可能な実験的機能が削除されました。
変更理由:
- これらのオプションは、デフォルトの値に設定されているため、設定可能なままにする必要はありません。
移行手順:
- 設定を削除するだけです。
14. その他の変更
- Nuxt4 では、
nuxt.config.js
ファイルがnuxt.config.ts
に変更されています。 -
vuex
モジュールは廃止され、代わりにpinia
を使用することが推奨されています。 -
axios
モジュールは、@nuxtjs/axios
モジュールに置き換えられました。
Nuxt3 から Nuxt4 への移行方法
Nuxt3 から Nuxt4 への移行は、以下の手順で行うことができます。
1. プロジェクトの更新
- Nuxt4 に対応した依存関係を更新します。
-
package.json
ファイルからnuxt
のバージョンを^4.0.0
に変更します。 -
npm install
またはyarn install
を実行して依存関係をインストールします。
2. ファイル構造の変更
-
pages
ディレクトリをapp
ディレクトリにリネームします。 -
server
ディレクトリを作成し、サーバーサイドコードや API エンドポイントを移動します。 -
nuxt.config.js
ファイルをnuxt.config.ts
にリネームします。
3. コードの更新
- コンポーネントの書き方を Composition API に合わせて変更します。
- 廃止されたモジュールを新しいモジュールに置き換えます。
-
nuxt.config.ts
ファイルで、新しい設定項目を定義します。
4. テストとデバッグ
-
npm run dev
またはyarn dev
を実行してアプリケーションを起動し、すべての機能が正常に動作することを確認します。 - 必要に応じて、コードを更新して、エラーを修正します。
Nuxt3→Nuxt4移行前の破壊的変更の影響テスト方法
Nuxt3からNuxt4 への移行時に破壊的変更の影響があるかは、Nuxt3.12 でテストすることができます。Nuxt3.12 は、Nuxt4 で導入される破壊的変更の一部をプレビューとして提供しています。
-
Nuxt3.12 をインストール:
npm install --save-dev nuxt@3.12.0
またはyarn add --dev nuxt@3.12.0
-
設定ファイルの更新:
nuxt.config.js
ファイルで、vueVersion
プロパティを3.2
に設定します。 -
プロジェクトの実行:
npm run dev
またはyarn dev
を実行してプロジェクトを実行し、破壊的変更の影響を確認します。
まとめ
Nuxt4 は、パフォーマンスと開発者エクスペリエンスを大幅に向上させる多くの破壊的変更を導入しています。これから開発環境を選べるのであれば、Nuxt4を検討に入れても良いかもしれません。Nuxt3からNuxt4への移行も、アプリケーションの規模がまだ大きくなければ検討してみてください。