28
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要

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 のパッケージとして別々に使用されていました。
    • 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 では pagescomponentscomposablesassetslayoutsutilsディレクトリはルートレベルにありましたが、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. 共有プリレンダリングデータ

影響レベル: 中程度

変更点:

  • useAsyncDatauseFetch の呼び出し結果を異なるページ間で共有する機能が有効化されました。

変更理由:

  • 複数のページで同じデータを取得する際に、プリレンダリング段階で一度だけデータを取得することでパフォーマンスを大幅に向上させることができます。
  • 例えば、サイト全体で共通のメニューデータやサイト設定データを取得する場合、この機能により、ページのプリレンダリング時に一度だけデータを取得し、他のページでキャッシュされたデータを使用できるようになります。

移行手順:

  • データの一意のキーが常に同じデータに紐づくことを確認します。useAsyncData でデータを取得する場合は、データを一意に識別するキーを提供する必要があります。useFetch は自動的にキーを生成します。
  • 必要に応じて、nuxt.config.tsexperimental.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. useAsyncDatauseFetch のデフォルト値

影響レベル: 最小

変更点:

  • useAsyncData から返される dataerror オブジェクトは、デフォルトで undefined になります。

変更理由:

  • 以前は datanull で初期化され、errornull で初期化されていました。この変更により、より一貫性のある挙動を実現しています。

移行手順:

  • 必要に応じて、nuxt.config.tsexperimental.defaults.useAsyncData オプションを使用することで、以前の挙動に戻すことができます。

7. useAsyncDatauseFetchrefresh オプション

影響レベル: 最小

変更点:

  • refresh オプションの dedupe オプションのブール値エイリアス (truecancelfalsedefer) が削除されました。

変更理由:

  • ブール値エイリアスはわかりにくく、混乱を招く可能性があったため、削除されました。

移行手順:

  • refresh オプションに cancel または defer を指定するようにコードを変更します。

8. useAsyncDatauseFetch のデータクリア

影響レベル: 最小

変更点:

  • useAsyncData にカスタムのデフォルト値が設定されている場合、clear または clearNuxtData を呼び出す際に、デフォルト値が使用されるようになりました。

変更理由:

  • データをリセット/クリアする際に、カスタムのデフォルト値を尊重することで、より適切な挙動を実現しています。

移行手順:

  • 必要に応じて、nuxt.config.tsexperimental.resetAsyncDataToUndefined オプションを使用することで、以前の挙動に戻すことができます。

9. useAsyncDatauseFetch のリアクティビティ

影響レベル: 最小

変更点:

  • useAsyncDatauseFetchuseLazyAsyncDatauseLazyFetch から返される data オブジェクトは、shallowRef になりました。

変更理由:

  • データオブジェクトのリアクティビティを浅くすることで、パフォーマンスを向上させることができます。

移行手順:

  • 必要に応じて、deep オプションを使用して、データオブジェクトのリアクティビティを深くすることができます。

10. builder:watch フックの絶対パス

影響レベル: 最小

変更点:

  • builder:watch フックは、プロジェクトの srcDir に対する相対パスではなく、絶対パスを発行するようになりました。

変更理由:

  • これにより、srcDir 外のパスの監視をサポートし、より複雑なプロジェクト構造に対応できるようになりました。

移行手順:

  • ほとんどの場合、移行手順は必要ありません。必要に応じて、コードを調整してください。

11. ディレクトリインデックススキャン

影響レベル: 中程度

変更点:

  • middleware フォルダの子フォルダもインデックスファイルがスキャンされ、ミドルウェアとして登録されるようになりました。

変更理由:

  • Nuxt は、middlewareplugins などのフォルダを自動的にスキャンします。この動作を他のフォルダにも拡張することで、より一貫性のある挙動を実現しています。

移行手順:

  • 必要に応じて、フックを使用してミドルウェアをフィルタリングすることで、以前の挙動に戻すことができます。

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への移行も、アプリケーションの規模がまだ大きくなければ検討してみてください。

28
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?