🍎

祝・正式リリース!5つのテーマで理解する Nuxt3 の魅力

2022/11/22に公開
3

11月16日、Nuxt 3 の初のstable版となる 3.0 がついに正式リリースされました!

https://twitter.com/nuxt_js/status/1592904778337906689

https://nuxt.com/v3

Public Beta版が公開されてから約1年、RC版で様々な改善と機能追加が行われてきましたが、待望の安定版の登場です。

個人的にこの1年いろいろな機能を試してみた感覚として、Nuxt 3 はあらゆるフロントエンド開発者にオススメできる、非常に使いやすくて優れたフレームワークだと思っています。

Nuxt 3 は非常に多機能かつ巨大なフレームワークであり、「何が優れているのか」を一言で説明するのはなかなか難しいのですが、大きく5つのテーマに分けてその魅力を整理してみました。

まず冒頭に、テーマごとの「最低限これだけ知ってもらいたい!」という要約を載せてから、細かいポイントを解説していきます。

まずは忙しい人向けの要約だけでも読んでもらって、興味が出てきた方は続きを読んで頂ければ嬉しいです!

Nuxt 3 を今すぐオススメしたい5つのポイント(忙しい人向け)

Nuxt 3 について、まずはこれだけ抑えてもらいたいというポイントをギュッと5つにまとめました。

基本的には Nuxt 3 公式サイトの Key Concepts の項から抜粋しています。

①自動インポートとTypeScript 完全対応による、便利で安全な開発体験

他の開発環境と比較して、Nuxt 3 の最大のウリであり、開発しやすさを飛躍的に高めてくれるのが自動インポートです。

defineComponentrefcomputed などといった Vue 3 の Reactivity API に加え、useStateuseRouter などのNuxt 3 が追加で提供する組み込み関数・コンポーネント、ユーザーが定義した関数やコンポーネントまで、全てが自動でインポートされ、自由に呼び出せます。

もちろんデフォルトで Tree-Shaking・分割読み込みに対応しているので、ビルドサイズやパフォーマンスへの悪影響もありません。

と、これだけ聞くと、自動インポートの多用によって可読性が下がり、保守しづらいクソコードになってしまうことを懸念する方もいると思いますが、それをカバーしてくれるのが 強力な TypeScript サポートです。

Nuxt 3 は設定不要での TypeScript サポート、特に自動で型推論&型チェックするシステムが非常に充実しており、インポートされる関数はもちろん、ユーザー定義関数からAPIの返り値まで、特に意識していなくても型付けが行われます。

Vue 3 では Template タグ上の変数やコンポーネントの props / emits もしっかり型チェックできるようになったので、普通に開発していれば、参照エラーや処理の追えないコードはまず生まれません。(もちろんこれは VS Code と Volar の凄さでもあります)

Nuxt 3 では自動インポートとTypeScriptの相乗効果によって、高い水準での生産性と安全性を両立しており、とにかく書いていて楽しいストレスフリーな開発環境になっています!

詳しくは:Auto imports · Nuxt Concepts & TypeScript · Nuxt Concepts

②SSRからエッジ環境まで、あらゆるレンダリングモード、全ての環境に対応

Nuxt.js の大きな特徴として、ブラウザ/サーバーのどちらにも対応できるレンダリングモード設定があります。

サーバーサイドで描画を行うSSR、ブラウザ上で全ての処理を行うCSR、ビルド時にページをあらかじめ生成しておくSSGにはそれぞれ利点がありますが、Nuxt.js ではこれらを全て同一コードで記述でき、簡単に切り替えることもできます。

Nuxt 3 ではこれに加えて、AWS Lambda や Firebase Functions といったサーバーレス環境、CDN上で分散処理を行う Edge Workers、Next.js × Vercel の専売特許であった Incremental Static Regeneration、さらには DenoPWA のサポートなど、あらゆるニーズに応えようとしています。

その上、Nuxt 3 では環境に応じたプリセットもあらかじめ用意されており、サーバーレスやWorkersなど設定しづらい環境にも簡単にデプロイできます。

さらに、Hybrid Rendering としてレンダリングルールを記述できるようになったため、ページごとにSSRとCSRを切り替えたり、APIだけキャッシュ期限やISRを設定したりといった設定も柔軟に行えます。

詳しく知りたい方は:Rendering Modes · Nuxt Concepts

③Vue 3 をベースとした直感的でハイパフォーマンスな開発環境

Nuxt.js は Vue.js ベースのフレームワークであり、そもそも Vue 3 が凄いという話を抜きに Nuxt 3 を語ることはできません。

Progressive Framework というコンセプトに基づく、直感的なAPI、ユーザーが意識せずに高いパフォーマンスを得られる生産性、Web標準のHTML/CSS がそのまま使えるといったメリットは未だに健在です。

さらに、2020年にリリースされた Vue 3 で、React Hooks ライクな Composition API 記法の導入、TypeScriptサポート強化によって、大規模な開発にも十分に適したフレームワークへと進化しました。

それと同時にパフォーマンス向上・バンドルサイズ削減が行われ、他のフレームワークと比較しても遜色ない速度が実現されています。TeleportSuspense といった新機能も取り入れられています。このパワーを最大限引き出しているのも Nuxt 3 の大きな利点です。

詳しくは:Vue.js Development · Nuxt Concepts

④Vite, Vue Router などが高度に統合された Vue3 フレームワークの決定版

Vue 3.0 がリリースされてからの2年間で、Vue.jsを取り巻く開発環境は大きく進化し、周辺ライブラリや新機能も次々に生み出されてきました。例えば、

  • <script setup> ── Vue 3.2 で追加された Composition API の進化系構文
  • Vite ── Evan You氏が新たに生み出した、Vue/React両対応の高速ビルド・バンドラツール
  • Vitest ── Vite ベースで実行が速い、Jest互換のテストツール
  • vue-tsc & volar ── Vue × TypeScript の開発体験を大きく向上させた、CIチェックツール&VSCode 拡張機能
  • Pinia ── Vuex に代わるシンプルで型安全なデータストアライブラリ

そんな中で満を持してリリースされた Nuxt 3 は、これらの Vue.js の進化を全て取り込む形で登場しました

ビルドツールにはデフォルトで Vite が採用されたことでビルドやホットリロードが非常に高速になり、script setup を含むComposition API の全ての機能は設定不要かつ自動インポートで使い始められます。

それと同時に、Nuxt3 の基盤となるサーバーエンジンやデータフェッチ機構は Nitroh3ofetch といった独立ライブラリとして再設計されています。

Nuxt2 の強みであったディレクトリ規約や複数レンダリングモードのサポートは引き継がれつつ、基盤となるライブラリが最新化されたことで、「Vue で開発を行うなら Nuxt 3 を選べば間違いない」と再び言えるようになったのは非常に嬉しいポイントです。

裏を返せば、Nuxt 3 の最大の強みは、無数のライブラリから必要なものを自分で探しに行くことなくVueエコシステムの恩恵を最大限に受けられる統合環境にあるとも言えるでしょう。

詳しくは:Introduction · Nuxt Concepts & Server Engine · Nuxt Concepts

⑤多数の強力ライブラリとそれを支える便利なモジュールシステム

Nuxt.js が他のライブラリと一線を画しているのが、機能モジュールの開発しやすさ・追加しやすさで、Nuxt 2 では公式・非公式を含めて様々なモジュールが開発・提供されてきました。

https://nuxt.com/modules?version=3.x

Nuxt 3 でも既に、公式が提供する @nuxt/image@nuxt/content といったコアモジュール以外にも、Tailwind CSSApollo Client のような人気ライブラリのインテグレーション、さらには Typed Router といった魅力的なアドオンまで、様々な機能を簡単に追加できるようになっています。

また、Nuxt 3 Modules 以外にも Vue 3 や Vite のプラグインにも対応しているので、 SentryGoogle Analytics など Nuxt Module がまだ提供されていない機能も簡単に追加できます。

詳しくは:Modules · Nuxt Concepts

Nuxt 3 を今すぐオススメしたい5つのポイント(時間がある人向け)

さて、ここまでの説明で Nuxt 3 に興味を持って頂けたでしょうか。

ここからは、1つ1つのテーマについて、具体的な機能や特徴を深掘りしていきます。

全ての章を合わせるとなんと40個以上あるので、適度に飛ばしつつ読むことを推奨します!

1. 自動インポートとTypeScript 完全対応による、便利で安全な開発体験

Nuxt 3 を1年使っていて自分が最も感動しているのが、革新的に快適な開発体験です。「頑張れば型を付けられないこともない」だった Vue2 / Nuxt2 とは雲泥の差、1年前にベータ版を初めて触って感じた「『開発していて楽しい』フレームワーク」という印象は全く揺らいでいません。

Nuxt3 では nuxi init した時点で何もしなくても tsconfig.json が作られ、nuxt.config.ts もTypeScriptファイルです。そして、使っているだけで自然に型の恩恵を受けられるシステムが構築されています。

Reactivity API の自動インポート

Nuxt3 で自動インポートされている項目のうち、最も恩恵を受ける機会が多いのは Composition API で提供される全ての API が明示的なインポートなしで使えることでしょう。

refcomputedwatchnextTickprovideonMountedonUnmountedといった、頻繁に使うAPIをいちいち1行目でインポートしなくても全てのコンポーネントや JS/TS ファイルで呼び出すことができ、当然ながら型も付いています。

この環境に一度慣れると、基本的な機能でさえいちいち import { ref } from 'vue' を書かないと使えない環境には戻れなくなります。

また、Vue3 が提供するAPIに加えて、Nuxt3独自に拡張された関数も多数あります。

例としては、サーバー/クライアントのデータフェッチを行う useAsyncData /useFetch 、データ管理を行う useState など。

さらに、ルーティング用のuseRouter useRoute、メタタグ定義の useHead など、他ライブラリの機能も含め、必要な機能がデフォルトで自動インポートされるので、コード量をかなり削減できます。

インポートされている関数の一覧は.nuxt/imports.d.tsで確認できます。

詳しくは:Auto imports · Nuxt Concepts

組み込みコンポーネントの自動サジェスト&型推論

自動インポート&型推論の恩恵を受けられるのは API だけではありません。NuxtおよびVueが提供する組み込みコンポーネントを Template タグで使う場合もしっかり型チェックが行われます。

例えば <template> タグ上で <Nuxt まで入力すると、以下のようにサジェストされます。(一部 @nuxt/image などのライブラリに含まれるコンポーネントが含まれています)

image-20221119205819869

そして、プロパティに誤った指定を行うと型エラーになります。

image-20221119205750145

これは Vue の組み込みコンポーネントも同様です。例えば <Teleport> を使おうとすると、 to プロパティが必須であるというメッセージが表示されます。

image-20221119210032266

VueやNuxtが組み込みで提供しているコンポーネントの数々を型定義付きで呼び出せるというのは非常に安心感がありますね。

インポートされているコンポーネントの一覧は、自動生成される.nuxt/components.d.tsで確認できます。

詳しくは:<NuxtLink> · Nuxt Components

コンポーネント components ディレクトリの自動インポート&型推論

デフォルト機能の自動インポートだけでも十分に凄いのですが、Nuxt3 ではユーザーが定義したコンポーネントや関数も同じように自動インポート対象に含めることができます。

コンポーネント名は全てフォルダ名およびファイル名から自動的に付けられてインポートされ、こちらもTemplateタグ上でのサジェストや、props/emits の型チェックがしっかり機能します。

image-20221121033340958

(まだ Nuxt 3 時代に脳が完全に追い付いていないので、ファイルの命名が下手クソなのはご容赦ください)

ディレクトリ規約をベースにしたフレームワークだからこその強力なシステムで、最初は戸惑うかもしれませんが慣れれば非常にスムーズな開発が行えるようになります。

ちなみに Nuxt Config の components プロパティで特定のパスのみをインポートさせたり、から配列を渡してインポート対象から除外することもできます。

詳しくは:components/ · Nuxt Directory Structure

カスタムフック composables ディレクトリの自動インポート&型推論

Composables の自動インポートも強力です。composables ディレクトリに配置して export した関数を、setup関数内のどこからでも呼び出せるようになります。

ここでの Composable とは Vue Composition API において、「状態のあるロジック」をカプセル化する関数を指す用語です。React Hooks のカスタムフックと同じく、 useXXX のような命名が推奨されています。

例えば、useStateuseFetch のようにサーバーとクライアントでデータを共有する場合に、それをカスタムフックに切り出すことで、型の恩恵を受けつつ複数コンポーネント間でも同じデータにアクセスできるようになります。

その他の例については、Vue 3 ドキュメントの コンポーザブル | Vue.js のページを参照すると非常にわかりやすいです。

ちなみに、状態のないロジックについては「utils」というディレクトリに配置することでこちらも自動インポートされます。

単なるヘルパー関数にまで専用ディレクトリがあるのは少し過保護な感もありますが、Nuxt.js というフレームワークに乗っかる以上はディレクトリ規約にもなるべく従った方が綺麗にコードがまとまるはずです。

(これは技術上の制限があるわけではないので、全て composables に入れても動作はします)

詳しくは:composables/ · Nuxt Directory Structure & utils/ · Nuxt Directory Structure

useFetch / $fetch での Server Routes の自動パス解決&型推論

Nuxt 3 では、API に h3 、データフェッチに ofetch という独自のライブラリが採用されており、API Routes機能を正式にサポートしました。

server/api ディレクトリに配置した TS ファイルは、API のエンドポイントとしてアクセスできるようになります。このあたりは Next.js を利用したことがあれば想像しやすいと思います。

凄いのは、こうして API Routes に定義した API に ofetch を使ってアクセスする場合、定義したURLが自動で候補に出てきて、しかも返り値にはしっかり型が付いており、おまけに SSR の場合はクライアント間通信を行わずにサーバー内部で通信を行ってくれるところです。

少し前にReact界隈で話題になった T3 Stack における tRPC で得られる体験とほとんど同じもの[1]が、Nuxt 3 ではデフォルトでセットされているようなもの、というとその凄さが伝わるでしょうか。Nuxt 3 でフロントとサーバーの両方を実装する快適さは、ぜひ一度体感して頂きたいです。

詳しくは:Data Fetching · Get Started with Nuxt & server/ · Nuxt Directory Structure

useFetch / useAsyncData で取得したデータの自動更新

useFetch / useAsyncData を使って取得したデータは、自動的にリアクティブになり、キャッシュ管理やローディング状態のアクセスも行えます。(API Routes だけでなく外部APIサーバーとの通信でも機能します)

React / Next.js における useSWR() のような機構を自前で備えており、わざわざライブラリを導入しなくてもスマートなデータフェッチができます。

この useFetch / useAsyncData については、以前かなり詳しく書いた記事があるのでここでは割愛します。興味があればぜひそちらもご覧ください。

https://zenn.dev/ytr0903/articles/6acccb5fa816ee

詳しくは:useFetch · Nuxt Composables & useAsyncData · Nuxt Composables

Plugins で Vue向けの機能拡張も手軽に取り入れられる

Nuxt において、モジュール化されていない機能をアプリ全体に対して追加する場合に使うのが plugins です。

Nuxt 2 では Configファイルで1つ1つ指定していましたが、 Nuxt 3 では plugins ディレクトリに配置されたファイルは全て自動で読み込まれます。

.client.ts のようにファイル名を変更することでサーバーサイド/クライアントサイドでのみ処理させることも可能です。

こちらも自動インポートされる defineNuxtPlugin((nuxtApp) => {}) を使うことで、引数では NuxtApp にアクセスできます。

この中で Vue インスタンスにアクセスできるため、Vue2 では Vue.useVue.directive といった指定を行っていた機能拡張をわかりやすく取り入れられます。

公式ドキュメントでは例として vue-gtag プラグインを追加するコードが紹介されていますが、Google Analytics対応はまさに Nuxt 2 にはあったが Nuxt 3 に対応していないモジュールの代表例で、そういった機能でも簡単に扱えます。

他にも SentryVee Validate V4 など、「Vue3 には対応しているが Nuxt モジュールがない」ライブラリはそれなりに多いのですが、Nuxt3 でこれらの機能を利用するのは少しも難しくありません。

詳しくは:plugins/ · Nuxt Directory Structure

プラグインを使えばグローバルヘルパーの登録&型付けも簡単

Plugins では、provide プロパティを返すことで、$hello のようなグローバルヘルパーをNuxt インスタンスに追加できます。こちらはユーザー独自機能を追加するためのプラグインの使い方と言えるでしょう。

export default defineNuxtPlugin(() => {
  return {
    provide: {
      hello: (msg: string) => `Hello, ${msg}!`,
    },
  }
})

コンポーネントでは useNuxtApp() でインスタンスを呼び出してアクセスできます。(Templateタグでは常にアクセスできるので宣言も不要です)

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>

<script setup lang="ts">
const { $hello } = useNuxtApp()
</script>

これだけだと $hello は any 型ですが、Nuxt 3 ではここにも簡単に型を付けられます。

declare module '#app' {
  interface NuxtApp {
    $hello (msg: string): string
  }
}
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $hello (msg: string): string
  }
}

グローバルヘルパーにも型を付けられると一気に安心感が出てきます。

Vue / Nuxt インスタンスの型拡張は意外とシンプルで、この方法を応用すれば同じように登録したグローバルコンポーネントやカスタムディレクティブにも型を付けられます。

詳しくは:Typing Plugins - plugins/ · Nuxt Directory Structure

ビルドから除外する .nuxtignore

自動インポートは便利な反面、あまりに利きすぎて不要なファイルまで勝手にインポートして解析されてしまうことがあります。

そこで、 .nuxtignore ファイルを使って特定のファイルやディレクトリをビルド対象から除外することができます。

例えば pages や components ディレクトリ内の同じ階層に spec ファイルも配置したい場合や、Nuxt 2 からの移行の最中に修正が完了していないファイルを無視したい場合などで活用できそうです。

なお、当初は .nuxtignore で自動インポートから除外できるという説明を記載していましたが、ビルド対象から外す機能であるとコメントで指摘を頂いたため修正しました。🙇‍♂️

Nuxt Config の imports.dirs で、特定のファイルやフォルダを追加で自動読み込みさせることもできますが、これはデフォルト設定を上書きするわけではありません。

composablesutils の自動インポートをオフにする方法は、現状では imports.autoImport で AutoImport そのものを無効化するしかなさそうです。

詳しくは:.nuxtignore · Nuxt Directory Structure

環境変数の管理も簡単 useRuntimeConfig / useAppConfig

Nuxt 2 やその他の環境では環境変数は .env ファイルに記述したものを process.env.XXX で参照したりしていましたが、Nuxt 3 ではそんなことはしません。(dotenv ファイルもサポートはしています)

Nuxt Config に環境変数を記述し、コンポーネントなどで useRuntimeConfig() と書いて呼び出すことで、環境変数にもしっかりと型が付きます。Base URL や APIキー などを any 型のまま扱う必要はもはやありません。

image-20221121033039144

またここではオブジェクトをネストすることも可能なので、例えば Sentry にエラーを送信する場合には、環境変数は以下のようにセットし、

nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      sentry: {
        dsn: 'XXXX',
        environment: process.env.NODE_ENV ,
        enabled: process.env.NODE_ENV === 'production',
      },
    },
  },
})

アプリケーション側で Sentry を初期化する際に以下のように書いても、型エラーにならずに扱えます。

import * as Sentry from '@sentry/browser'

const runtimeConfig = useRuntimeConfig()
Sentry.init(runtimeConfig.public.sentry)

詳しくは:useRuntimeConfig · Nuxt Composables

2. SSRからエッジ環境まで、あらゆるレンダリングモード、全ての環境に対応

複数レンダリングモードのサポートはNuxt2 から引き続いて Nuxt.js を採用する大きなモチベーションです。

ここでは、Nuxt 3 がカバーするデプロイおよびレンダリングモードの、異次元の幅広さについて説明していきます。

SSR / CSR / SSG を幅広くサポート

おそらくほとんどのウェブサイトでは、サーバーサイドレンダリング(SSR)、クライアントサイドレンダリング(CSR)、静的サイト生成(SSG)のいずれかを採用することになると思いますが、Nuxt 3 はその全てのユースケースを手厚くサポートしています。

もちろん「SSRしないなら過剰」みたいなことも決してなく、CSRでも Nuxt 3 を選ぶメリットは十分にあります。

Nuxt 3 では storepages ディレクトリが必須ではなくなったことも、シングルページのサイトでの利用の後押しになるはずです。

Nuxt 3 の公式ページでレンダリングモードごとの Pro/Con 比較もされているので、参考になるのではないでしょうか。

詳しくは:Rendering Modes · Nuxt Concepts

Node.js サーバー や静的ホスティングサービスへの簡単デプロイ

Nuxt 3 で本番環境にデプロイする方法は、Deployment • Nuxt を読めば簡単にわかります。

デフォルトの設定は Node.js サーバー上で動作する SSR モード。ポートの変更も引数で簡単に行えるので、Node.js が動くクラウドサーバーやDockerベースの環境では、特別な設定は不要です。

静的ホスティングの場合も、クライアントサイドでルーティングを含めた処理を行う CSR(SPA)と、ファイルベースでの事前の静的サイト出力(SSG)のどちらでも簡単に切り替えられます。

設定でルーティング配列を自分で書くこともできるので、数年前に流行した JAMStack 的な動的ルーティングもしっかり対応しています。

SPA / SSG のサポートのおかげで、Amplify や Netlifyなどの静的ホスティングサービス、もしくは一般のレンタルサーバーにも簡単にデプロイできます。

詳しくは Deployment · Get Started with Nuxt / pages/ · Nuxt Directory Structure

サーバーレス環境や Edge 環境にも手軽にデプロイできるプリセット

Nuxt 3 ではこれに加え、サーバーレスや CDN Edge といった制限のある環境にもデプロイできます。

特筆すべきは、主要なホスティング環境にデプロイするための設定がプリセットとして提供されていることで、サービスによっては自動検出できるため設定不要で様々なサービスにデプロイできます。

AWS (Lambda) / Azure / Cleavr / CloudFlare / Digital Ocean / Firebase (Functions) / heroku / layer0 / Netlify / Render / Stormkit / Vercel

主要な、といってもこれだけのラインナップが既に用意されています。

特に制約の多い AWS Lambda や Firebase Functions に手軽に SSR モードでデプロイできるのが嬉しいところ。

私自身、過去にいくつかサーバーレス環境へのデプロイを試してみましたが、どれもかなり簡単でした。サーバーやインフラに詳しくなくても気軽にSSRできます。詳細は以下の記事をどうぞ。

CDN上での分散処理であるEdge Workers 上で動作する Netlify EdgeCloudflare Workers といった環境に対してもプリセットが用意されており、こちらもユーザーの追加対応なしで動作します。

詳しくは:Rendering Modes · Nuxt Concepts

Node, ブラウザ, Deno, Workers のクロスプラットフォーム対応

Nuxt 3 がサポートしている環境はこれだけにとどまりません。

Node に代わる新たなJSランタイム環境として注目されているDenoでも既に動作するプリセットが用意されていますし、ブラウザ上の Service Workers 対応も予定されています。

https://github.com/nuxt/framework/issues/5440

Nuxt チームは多様な JS 環境の統一的な動作サポートのため、必要なライブラリを自ら UnJS (Unified JavaScript Tools)と名付けて整備するという力の入れようで、あらゆるプラットフォームをサポートする強い意志が感じられます。

詳しくは:UnJS & Server Engine · Nuxt Concepts

Incremental Static Generation 対応

Incremental Static Generation(段階的静的サイト生成、ISR/ISG)は、SSGとSSRを組み合わせて段階的にキャッシュを更新することで、ビルドと表示の両方を高速化させつつ最新のデータを維持できる仕組みです。

この仕組みはこれまで基本的に Vercel と Next.js の組み合わせでのみ動作していましたが、Nuxt 3 でもこの機能のサポートが予定されています。

現時点では Netlify でのみ動作する実験的な機能にとどまっているものの、Vercel が既に Build Output API という仕様を策定・発表していることもあり、様々な環境でのサポートが進むことが期待されます。

詳しくは Hybrid Rendering - Rendering Modes • Nuxt

.output ディレクトリで全てが完結する、出力の最適化

Nuxt 3 のビルドシステムは、CSR/SSRを問わず、最適なコード分割と非同期的なスクリプト読み込みを自動で行う仕組みが備わっています。

Nuxt 3 を使ってビルドを行うと、 必要なファイルだけが適切に分割された状態で .output ディレクトリに出力されます。デプロイ先の環境にはこのディレクトリをアップし、例えばシンプルな node.js サーバーであれば node .output/server/index.mjs を実行するだけです。

これは node_modules に依存していないことも意味します。必要なものは .output ディレクトリにコピーされています。つまり、全てのパッケージを devDependencies に指定すれば良いということです。

nuxi init すると、nuxt3 自体も devDependencies に指定されていることがわかります。

開発時と共通の node_modules はそもそも本番ビルドに含まないので、「このライブラリ/コードはランタイムに必要かどうか」をユーザーが意識する必要すらありません。デプロイ対象もわかりやすく、確実な軽量化・高速化が見込めます。

詳しくは:Standalone Server - Server Engine · Nuxt Concepts

Vue Router の任意化による完全なSPA対応

Nuxt 3 では pages ディレクトリが必須ではなくオプショナルになっており、実際に nuxi init しても初期状態では pages は作成されず、単なる SPA として動作します。

Nuxt 2 でも pagesindex.vue だけを置けばSPA的な挙動を実装することはできましたが、その場合でもルーティング用ライブラリである Vue Router が必ずバンドルされてしまいました。

この点、Nuxt 3 では pages ディレクトリを作成せずに app.vue だけを置くと、 Vue Router もビルドから除外できます。

ビルドサイズを肥大化させずに済むので、単一ページのWebアプリ(SPA)でも心置きなく Nuxt 3 の開発体験の恩恵だけを受けられます。

詳しくは:app.vue · Nuxt Directory Structure

noScripts オプションによるAstroライクな完全静的サイト生成(MPA)

現状は experimental 扱いですが、クライアントサイドのJSを完全に無効化するオプションも準備されています。

通常、Nuxt(に限らずほとんどのユニバーサルフレームワーク)における「SSR」とは「初回描画はサーバーで行い、ページ遷移はクライアントサイドで必要なデータだけを取得する」という方式が採用されており、厳密には「Universal Rendering」のことを指していました。

しかし、このオプションを使えばクライアントサイドでは JS を一切取得・実行しません。ページ遷移時も含めて全てサーバーで生成されたデータを利用することになります。

https://github.com/nuxt/framework/issues/7156

元の issue を見ると、完全な静的サイトを生成することでの高速化を謳って注目を集めたフレームワーク Astro を踏襲したアプローチとして期待されているようです。私自身もまだ試せてはいませんが、コンテンツメインのサイトで今後利用されていくかもしれません。

詳しくは:noScripts - Nuxt Configuration Reference · Nuxt

3. Vue 3 をベースとした直感的でハイパフォーマンスな開発環境

Nuxt.js は Vue.js ベースのフレームワークであり、そもそも Vue 3 が凄いという話を抜きに Nuxt 3 を語ることはできません。

この章は Vue 2 から 3 での進化ポイントについて紹介していきます。既に Vite などの環境で Vue 3 については理解している、という方は、次の章にジャンプしても大丈夫です。

また、Vue.js 自体の説明はさすがにここでは割愛します。先日、公式ドキュメントの最新版が日本語に翻訳され、サンプルコードが Composition API と Options API 切り替え対応するなど非常に読みやすくなったので、こちらも目を通すことをオススメします。

https://ja.vuejs.org/

TypeScript サポートの強化

Vue 3 の最大の特徴となるのが何と言っても TypeScript サポートの大幅な強化です。

Vue 3(Nuxt 3)自体もTypeScriptで完全にリライトされており、型定義のサポートも充実。

Templateタグ上のHTML要素もJSXベースでの型解析が行われるなど、もはや「VueとTSは相性が悪い」というイメージは過去のものとなりつつあります。

詳しくは:TypeScript で Vue を使用する | Vue.js

大幅なパフォーマンス向上とバンドルサイズの削減

Vue 3 の主要機能の多くは Vue 2 にもライブラリとして提供されてきましたが、あえてメジャーアップデートを行う利点の1つがパフォーマンスの大幅な改善です。

https://blog.vuejs.org/posts/vue-3-one-piece.html

Vue 3 リリース時の発表によると、バンドルサイズが41%削減、初期描画が55%速くなり、メモリ使用量も55%少なくなったとされています。

言うまでもなくこの数値には Vite や Nuxt 3 の効果は含まれていないため、Nuxt 3 ではさらなる高速化が期待できます。

Composition API の標準採用

Vueにおける新しい記法として提案され、プラグインでVue 2にも先行提供されていたComposition API。Vue 3 では基本機能として自然に組み込まれ、今後は徐々にこちらが主流になっていくと思われます。

従来の記法であるOptions APIと比較した最大の強みはTypeScriptとの親和性。これまでのVueは「頑張れば型を付けることもできる」程度の部分的なサポートで、thisに型が増えていくだけでしたが、

Composition APIではそもそもthisを使わなくなり、refやcomputedが全て関数化されたことで、何も意識せずに型安全な開発を行うことができます。

Vue 2時代のOptions APIに慣れている方からすると、Composition APIは見た目があまりにも違うので取っつきにくく感じるかもしれません(私も以前はそうでした)が、おそらく使ってみると結構同じです。computedはcomputedだし、watchはwatchだし、mountedはonMountedだし、少なくともReact Hooksを習得するよりは遥かに簡単です。

圧倒的に簡潔に書ける <script setup> 記法

Vue 3.2で新たに導入された <script setup> では、Composition APIの良さを保ったままもっとシンプルに書けるようになりました。

コンポーネント宣言や return が不要になった一方で、基本的な関数は Composition API から変わっていないため、Vue2 でこれまで Composition API を使っていた人であれば違和感なく移行できるかと思います。

https://zenn.dev/azukiazusa/articles/676d88675e4e74

より詳しい解説はこちらの記事が素晴らしいのでそちらも見て頂けたらと思うのですが、単に記述量が減るだけでなく、ランタイムパフォーマンスが向上する、defineProps/defineEmits(後述)が使えるなど、基本的にはメリットしかない記法です。

しかもNuxt 3 は Composition API の関数が自動インポートされるため、よくあるカウンターアプリもたったこれだけのコードで作れます。インデントが浅くなるのも嬉しいところ。

<script setup>
const count = ref(0);
const increment = () => count.value++;
</script>

コンパイルマクロであるため CDN では使えませんが、Nuxt 3 であれば基本的にこの記法を使うのがオススメです。

defineProps でpropsが普通に書けるようになった

script setupでのみ使える defineProps では、propsの型定義が一般的なTypeScriptと同じ形式で書けるようになりました。

https://zenn.dev/aoito/articles/a09eb484344ae2

defineProps についても既に多くの方がまとめているのでここでは割愛しますが、個人的に Vue 2と比較して一番の進化ポイントがこれだと思っています。

また、defineComponent ではリアクティブの制限で分割代入できず、常に props.title のように書いて参照する必要がありましたが、defineProps では分割代入にも対応しています。

https://github.com/vuejs/core/pull/7986

Vue 2 の Composition APIでこれまで開発してきた人なら、propsを分割代入できないことに地味にストレスを感じていたと思いますが、これも改善されました。

emits の型付けが可能に

そもそも Vue 2 では emits の型付けには対応していません。子コンポーネントはランタイムで $emit にイベント名や引数を渡すだけで、それらの事前宣言を行うオプションは存在していませんでした。

Vue 3 では props 同様、子コンポーネントが emits で呼び出すイベント名を事前に定義することができます。これはオプションではなく必須であり、script setup だけでなく Options API や Composition API にも対応しています。

詳しくは:Options API とともに TypeScript を使用する | Vue.js

サンプルコード
import { defineComponent } from 'vue'

export default defineComponent({
  emits: {
    addBook(payload: { bookName: string }) {
      // ランタイムでバリデーションが実行される
      return payload.bookName.length > 0
    }
  },
  methods: {
    onSubmit() {
      this.$emit('addBook', {
        bookName: 123 // 型エラー!
      })

      this.$emit('non-declared-event') // 型エラー!
    }
  }
})

TypeScriptを使わない場合、 emits: ['addBook'] のようにイベント名だけを定義することもできます。

ちなみにこれを <script setup> で書くとこうなります。(単なる型宣言のため Validator は省略しています)

const emit = defineEmits<{
  (e: 'addBook', payload: { bookName: string }): void
}>()

const onSubmit = () => {
  emit("addBook", {
    bookName: 123, // 型エラー!
  });
  emit("non-declared-event"); // 型エラー!
};

props / emits による双方向のデータハンドリングは React にないもので、v-model などの便利なシュガーシンタックスも含めてシンプルにフォームなどを記述できるのは Vue の大きな強みの1つです。

Vue 2 では emits が TypeScript に対応していないためにやや利用を躊躇してしまう部分がありましたが、この悩みから解放されたのは嬉しいところです。

オブジェクト・配列のリアクティブ検知に関する制限が撤廃

Vue.js において開発者がハマりやすい罠の1つが、オブジェクトおよび配列の要素の一部を変更した際に、その変更を Vue が検知することができない(テンプレートの再描画や computed の更新などがトリガーされない)というものでした。

const arr = ref([])
arr.value = ['new'] // 検知できる
arr.value.push('new2') // push や splice は検知できる
arr.value[0] = 'new3' // 検知できない
Vue.set(arr.value, 0, 'new4') // Vue に変更を検知させるためのメソッド

Vue3 ではこの問題が解消され、arr.value[0] = 'new3' のような書き方をしても問題なく変更が反映されます。

詳しくは:リアクティビティーの基礎 | Vue.js

JSX/TSXのデフォルトサポート

React におけるHTML記法として普及している JSX/TSXも Vue 3 ではサポートしています。Vue2 でも利用することはできましたが、より導入しやすくなりました。

特に Nuxt3 ではプラグインの追加すら不要で、<script lang="tsx"> と書くだけで使えます。JSX/TSXファイルの自動インポートさえも対応しています。

個人的には <script setup> が十分に強力なので、あえてTSXで書くモチベーションはそこまで高くなくなったのですが、Templateタグに抵抗がある方や、Reactからコードを移植する場合にオススメです。

詳しくは:Render 関数と JSX | Vue.js

styleタグから Vue 変数にアクセスできるように

Vue SFC の大きな特徴として、デフォルトで <style> タグが存在しており、Web標準のHTMLと同じ感覚でCSSを記述できる点も見逃せません。

scopedsass / scssCSS Modules 、などもしっかりサポートしています。Nuxt3 では CSS Modules を有効に扱うための useCssModule() という関数もグローバルインポートされます。

https://ja.vuejs.org/api/sfc-css-features.html

他にも Vue 3 での強化ポイントはいくつかありますが、最大の強化は JS 変数に styleタグからアクセスできるようになったことです。

<template>
  <div class="text">hello</div>
</template>

<script lang="ts" setup>
const color = ref('red')
</script>

<style>
.text {
  color: v-bind(color);
}
</style>

ちなみにこの機能の実現には CSS Variables が不可欠です。Vue3 が IE11 対応をドロップしたのは英断と言えますね。

コンポーネント設計とHTML構造の分離 <Teleport>

Vue3 ではIDを指定して特定の位置に一部のHTMLを描画する機能が搭載されました。React の Portalに相当し 、Vue2 では Portal Vue というライブラリで提供されていたものです。

特にモーダル・ダイアログなどで、アプリケーション上の階層とHTML上の構造を分離したい場合や、親要素のz-indexの影響を無視したい場合に手軽に活用できます。

https://v3.ja.vuejs.org/guide/teleport.html

複数DOMをルート要素に配置可能Fragments

Vue 2 では 1つのコンポーネントのルートに 1つの要素しか配置できないという制約がありましたが、Vue 3 ではその制約がなくなりました。DOM階層を無駄に深くする必要がなくなって嬉しいです。

コンポーネント内の部分レンダリングを簡単に <Suspense>

これはまだ実験的な機能ではありますが、子コンポーネントの setup 内に非同期処理が存在する場合に、ローディング中のフォールバックを親コンポーネント側に記述する方法が提供されています。

https://ja.vuejs.org/guide/built-ins/suspense.html#suspense

4. Vite, Vue Router などが高度に統合された Vue3 フレームワークの決定版

ここまで Nuxt 3 の機能をたくさん見てきましたが、実は 「Nuxt3そのものの機能」と言えるものは意外と多くありません

その多くは既に Vue エコシステムに存在しているものだったり、または Nuxt チームが独立ライブラリ UnJS として整備した上で取り込まれたツールだったりします。

裏を返せば、無数にあるツールの中からユーザーが個別に選んで組み合わせなくても、それらの恩恵を最大限に受けられる統合環境こそが Nuxt 3 の本質とも言えます。

Nuxt 3 を支える個々のライブラリを見ていけば、その機能の大部分を理解できることでしょう。もちろんここに挙げるのは代表的な一部です。

HMRもビルドも超高速な次世代フロントエンドツール Vite + esbuild

Vue.js の作者である Evan You 氏が2021年に新しく発表し、JavaScript ライジングスター 2021にもランクインするなどフロントエンド界隈全体からの注目を集めたVite

ネイティブESMやHMRの強力なサポートにより、開発サーバーの起動・開発中のサーバー更新・ビルドの全てが高速で軽快に動作します。

https://ja.vitejs.dev/

Nuxt 3 では この Vite をデフォルトのバンドラとして採用したことで、サーバー起動やホットリロードが重いという Nuxt2 の弱点を克服しています。

Vite 向けの設定は Nuxt Config に記述することができ、ある程度は Vite の設定との互換性を備えています。

同時に、Vue 3 に合わせてレガシーブラウザのサポートを切ったこともあり、バンドラーのデフォルトも高速な esbuild に変更されました。(Webpack 5 もサポートされています。)

詳しくは:Nuxt Configuration Reference • Nuxt

型チェックツール vue-tsc & Volar

Vue 3 開発環境における進化として見逃してはならないのが、Vetur に代わる型チェックツールとして登場した Volar です。

https://github.com/johnsoncodehk/volar

それまでの Veturよりも高速かつ安定した型チェックが行われ、しかも Templateタグ や Props の型チェックもサポートするということから一気に普及しました。現在ではVueの公式拡張として、VSCode Marketplace にも Vue.volar という名前で登録されています。

また、共通の解析システムで静的チェックを行う vue-tsc が同時に提供されたことで、CI上での型チェックが容易になりました。

Nuxt 2 でも nuxt/typescript モジュールを使えばランタイムでのチェックはできていましたが、CIとの連携は難しく、ランタイムでもTemplateタグ内の変数などのタイプエラーはチェックされていませんでした。

その点、Nuxt 3 では型チェックには全面的に vue-tsc が採用されており、しかも npx nuxi typecheck コマンドを使えば、まず .nuxt ディレクトリを生成してから vue-tsc が実行されるため、CI上でも簡単に型チェックが行えます。

この型チェックはランタイムに実行するオプションもあるので、開発中に即座にエラーを確認することもできます。(パフォーマンス観点からデフォルトではオフになっています)

詳しくは:nuxi typecheck • Nuxt

簡単セットアップ Nuxt CLI

Nuxt 3 ではコマンドラインも充実していて、nuxi コマンドで簡単に呼び出せます。

よく使うのは初期化の nuxi init 、開発サーバー起動の nuxi dev、ビルド時の nuxi build 、静的サイト向けの nuxi generate でしょうか。

nuxi typecheckvue-tsc を実行するのと基本的には同等ですが、.nuxt ディレクトリを先に生成してくれるので、Nuxt の自動インポートを解決した上で型チェックを行ってくれるので、CI上での自動実行に向いています。 nuxi prepare してから実行すれば良いだけと言えばそうなのですが、わかりやすくて良いですね。

個人的に注目しているのが、正式リリース目前のRC14で急に追加され、まだドキュメントにもページがない nuxi test です。

https://github.com/nuxt/framework/pull/4578

nuxi typecheck 同様、Nuxt をセットアップしてから Vitest を実行してくれるというものです。後述するように現状の Nuxt 3 × Vitest には少し難があるので、これが将来的に Vitest サポートの基盤になってくれたら嬉しいなと思っています。

次世代サーバーエンジン nitro & h3

Nuxt 3 のサーバーサイドの基盤となっているのが、このためにゼロから開発された Nitro エンジンです。

前述したクロスプラットフォーム対応やレンダリングサポートに加え、自動コード分割やホットリロード機能を備え、Nuxt 3 での開発体験を1段階上のものにしています。

https://nitro.unjs.io/

また、ミニマル HTTP フレームワーク h3 によって API Routes サポートも大きく拡張されています。

既存のフレームワークだと Express に近い動きと考えるとイメージしやすいでしょうか。こちらも型厳格でかなり扱いやすいAPI となっいます。

詳しくは:h3@1.0.1 - jsDocs.io

Viteベースの高速ユニットテスト Vitest & @nuxt/test-utils-edge

Jest に代わるユニットテストツールとして注目を集めているのが Vitest です。

A blazing fast unit-test framework を標榜している通り、非常に高速なテスト実行を特徴としています。Nuxt 3 と同じく Vite ベースであることから、設定を共通化できるのも嬉しいところです。

このツールは厳密には Nuxt 3 に最初からバンドルされているわけではないのですが、公式ドキュメントにも記載があり、 npx nuxi testコマンドを使った際に Vitest がインストールされていないとエラーが出るので、Nuxt 3 におけるテストツールとしてはほぼこれ一択と考えて良いでしょう。

……ただし、この Vitest と Nuxt 3 の組み合わせは微妙に整備されきっていない感があります。Nuxt 3 の自動インポートや、Nuxt独自の関数(useNuxtAppuseState など)を呼び出す場合に、ユニットテストでそれを上手く動作させる最適解が、未だに固まっていないように見えます。

https://github.com/nuxt/framework/issues/2465

https://github.com/danielroe/nuxt-vitest

これについての issue も複数立っているので、また今後進展があれば追記したいと思います。

https://tech.andpad.co.jp/entry/2023/03/16/100000

現時点で Vitest を利用する手順はこちらの記事に詳しく書いていますので、興味のある方は参考にしてみてください。

詳しくは:Testing · Get Started with Nuxt

スマートで多機能なFetch API ofetch

Nuxt 3 ではデータフェッチライブラリも全く新しいものが搭載されています。Nitro, h3 と同じく独自開発の unjs/ofetch です。

Node や workers など Fetch API がない環境では自動で代替ライブラリを使ってくれる点、レスポンスの JSON を自動的にパースできることからサーバーとの型補完をスムーズに行ってくれる点などが魅力です。

Nuxt 3との組み合わせでは、SSRなどサーバー内で ofetch を呼び出した場合に自動的にサーバー内部での直接コールに切り替わる機能もあり、基本的にはこれを使うのが推奨されます。

既存のミドルウェアを使いたい場合など axios の方が適している場面もあるものの、Interceptorもサポートしているなど、機能的にはかなり過不足のないライブラリとなっています。

ちなみに少し前までは ohmyfetch という名前でしたが、Nuxt 3 リリースの直前にリネームされました。お嬢様言葉みたいで良い響きですね

詳しくは:unjs/ofetch: A better fetch API. Works on node, browser and workers.

Vue Router でのファイルベースルーティング、Nested Routes にも対応済

Vue Router は Nuxt 2 から継続採用されているお馴染みのルーティングライブラリです。

Composition API でも useRoute useRouter という2つのAPIによって柔軟にルート管理が行え、CSR/SSRの両方でURLを管理できます。

ディレクトリベースの自動ルーティングシステムにも基本的には変更はありませんが、動的ルートの記述方法が変わり、Next.js に近いものになりました。(_id.vue から [id].vue に変更)

これにより、Nuxt2では難しかった「ファイル名の一部だけを動的ルートにマッチさせる」「スラッシュ配下を含む全てのルートにマッチさせる」といった設定がファイル名だけで行えるようになったのも嬉しいポイントです。

また、Remix や Next.js などのフレームワークで採用されている Nested Routes にも対応したため、より柔軟なページ構築も行えます。

詳しくは:pages/ · Nuxt Directory Structure

5. 多数の強力ライブラリとそれを支える便利なモジュールシステム

ここまで紹介してきたのは Nuxt 3 に最初から備わっている機能ですが、さらなる機能を追加できる拡張性も Nuxt の魅力です。

Nuxt 3 および Vue 3 では既に様々な便利モジュールが提供されており、これらを組み合わせることで効率的な開発が可能となります。

全てを紹介するのは難しいので、個人的にぜひ知っておいてもらいたいライブラリをいくつか紹介したいと思います。

Vuex に代わる型厳格なステート管理ライブラリ Pinia

Vue 3 では Vuex に代わって Pinia が公式に推奨されるグローバルデータストアライブラリとなりました。

https://twitter.com/VueDose/status/1463169464451706897

Pinia は軽量かつ型安全なデータストアで、ある程度Vuexとの互換を備えつつもより直感的に利用できます。

また、Vuex ライクな Options Store だけでなく、Composition API と同じ関数が使える Setup Store という記法も提供されているので、Composition API に慣れている方はより少ない学習コストで型安全なストアを利用できます。

Vue2/3のどちらにも対応し、Nuxt 3 向けのモジュールも既に提供されています。

Nuxt 2 ではVuex がデフォルトで組み込まれており外すのは困難でしたが、Nuxt 3 では Vuex はバンドルされていません。

stores ディレクトリの自動読み込みはないものの、composables に配置するか、または Nuxt Config で import.dirs に追加すれば、Nuxt 2 までと変わらない使用感でストアを呼び出すこともできるでしょう。

nuxt.config.ts
export default defineNuxtConfig({
  imports: {
    dirs: ['stores'],
  },
})

詳しくは:Home | Pinia

Composition API での開発を劇的に加速させる便利な詰め合わせ VueUse

Vue3 / Nuxt3 での開発を行う際にぜひともセットで検討したいライブラリが、Composition API における便利な機能がたくさん入ったライブラリ VueUseです。

https://vueuse.org/

既になんと200 以上の機能が提供されており、useIntersectionObserveruseClipboarduseDraggableuseMediaQuery など、自分で実装するのが微妙に面倒な機能が、リアクティブなコンポーサブルとして多数用意されています。

当然ながらこれも Tree Shakeable なので、実際に使う機能しかビルドサイズには含まれません。

Nuxt 向けのModuleも既に準備されていて、これを導入すると VueUse の関数も全て自動インポートの対象となります

他にも、文字を入力した際にフィールドが自動拡大する useTextareaAutosize、どこにもフォーカスせずにタイプすると発火するonStartTyping、バッテリーの充電状態かどうかなどを取得できる useBattery など、ニッチながら使い道のありそうな機能がたくさん眠っており、

この VueUse の機能一覧を眺めているだけでも 「こんな機能/サービスが作れそう!」というインスピレーションを受けられる のでとても楽しいです。

このような便利なライブラリにどこまで依存するかは検討の余地があると思いますが、機能ごとに別々のライブラリを導入するよりは、車輪の再発明を避けつつ依存するパッケージの絶対数を減らして集約できるメリットは非常に大きいと考えています。

1つ1つの機能はシンプルで処理も理解しやすく、また Vue / Nuxt のコアコミッターでもある antfu さん中心に活発なメンテナンスが行われているのも安心できるポイントです。

また、Vue Composable を切り出す際のコードのサンプルとしても非常に優れているので、リポジトリを見て実装の参考にするのもオススメです。

詳しくは:Get Started | VueUse

@nuxtjs/tailwindcss ならテーマプレビューも自動

最近のフロントエンドにおけるスタイリングの定番となりつつある Tailwind CSS 。もちろんこちらのモジュールも提供されています。

Modules · Nuxt

Nuxt 3向けモジュールでのダウンロード数も1位。利用者の多さが伺えます。

個人的に便利だと感じたのが、 nuxi dev で起動した際にローカルでテーマプレビューを一緒に表示できる点です。特に Tailwind を自分でカスタマイズして使う際に力を発揮することでしょう。

ちなみに、Tailwind互換の WindiCSS や、より先進的な UnoCSS のようなモジュールも同様に提供されているので、必要に応じてそちらを選ぶこともできます。

マークダウンベースのサイトを手軽に作成 @nuxt/content

Nuxt 公式モジュールの中でも比較的初期に Nuxt 3 対応版が公開されていたのが @nuxt/content

https://content.nuxtjs.org/

公式サイトにも content/ ディレクトリのページが用意されているほど密接に連携された機能です。というか、Nuxt公式サイト自体がこのモジュールで開発されています

マークダウンや yml で書かれたページをファイルベースで自動的にルーティングでき、MongoDBのようなクエリも備えているので、ドキュメントサイトやブログを非常に簡単に作成することができます。

いわゆるコーポレートサイトを作る際などにも活用できそうです。

Nuxt 3 を使ってみたいがどんなサイトを作ったら良いかわからないという方は、まずはこの @nuxt/content を試してみるのが良いのではないでしょうか。

詳しくは:content/ · Nuxt Directory Structure

ドキュメントサイトに必要な全てが揃ったテンプレート Docus

Nuxt Labs が開発している機能の中で、少し前から存在だけは知られていたものの一体何なのかよくわからなかったのが Docus だったのですが、最近になってその全容にアクセスできるようになりました。

https://docus.dev/

これが何かというと、どうやら @nuxt/content@vueuse/nuxt、さらには CSS in TS フレームワークpinceau などが最初からセットされ、さらに Alert や CodeBlock などの独自コンポーネント・コンポーザブル一式が用意された、Nuxt3 向けのテンプレートだったようです。

デザインや機能も含めてとにかく最速でサイトを作ってみたい場合、こちらのテンプレートを利用するのが良さそうです。

また、このテンプレートについてもう1つ特筆すべきなのが、Nuxt Config の記述。Docus テンプレートを利用してサイトを作成すると、Nuxt Configには

nuxt.config.ts
export default defineNuxtConfig({
  extends: '@nuxt-themes/docus'
})

なんとこれだけしか書いていません。

Nuxt Config の extends プロパティで別のNuxt アプリケーションを指定すると、そのNuxt アプリケーションに登録されているコンポーネントやコンポーザブルなどを自由に呼び出せるようになるというテーマ機能が活用されています。

https://twitter.com/jacobandrewsky/status/1584545739832557569

Nuxt Theme について、現状では公式サイトにも記述があまりないのですが、以下のページでは他にもいくつかのテーマや、自作テーマを作るためのスターターテンプレートなんかも用意されているので、興味のある方は覗いてみてください。

https://github.com/nuxt-themes

iOS / Androidアプリも作れる? @nuxt/ionic

https://nuxt.com/modules

Nuxt Module では他にもたくさんの機能が提供されており、便利そうなものを紹介し出すと本当にキリがないので、個人的にざっと眺めた中で、一切中身見てないけど気になったものを1つだけ選びました。

https://ionic.nuxtjs.org/

2年ほど前、JavaScriptベースでアプリ開発が行えるフレームワーク「Ionic Framework」が Vue 3 に対応するというニュースを見て、もしかしたら React Native のように Vue でもアプリ開発できる時代が来る? と密かに気になっていたのですが、

Nuxt 3 でアプリ開発までできるようになる、というのはちょっとワクワクしますね。現状ではまだまだ課題も多そうですが、期待が高まります。

おわりに

あまりに長すぎてここまで読んでくださった方が本当に要るのか書いていて不安になっているのですが、もしいるとしたら本当にありがとうございます。

約1年前、Nuxt 3 を今すぐオススメしたい 15 のポイントという記事を書き、ありがたいことに想像以上の反響と大量のいいねを頂きました。

そこからも様々な更新があり、また私自身も Nuxt 3 を1年間いろいろ触ってみて「これも紹介すれば良かった…!」という部分もたくさんあったのですが、おそらく加筆修正を始めると原型をとどめなくなってしまいそうだったので、正式リリースを機にゼロからまとめ直してみることにしました。

ここ数年、Nuxt 3 がなかなかリリースされないことで、この先どうなるのかという不安も少しあったのですが、リリースされた Nuxt 3 を触ってみると、期待を遥かに上回る便利さと完成度の高さでした。

Nuxt 2 を初めて触った時に覚えた感動と同じかそれ以上のものだったので、きっと利用者も増えていくはずだと信じています。

Vue 3 のリリースからは2年2ヶ月という長い時間が経ちましたが、逆にこの2年の準備期間があったことで、Vue界隈でもTypeScript と Composition API が定着し、そしてちょうど6月で IE11 のサポートが正式に終了するなど、Nuxt 3 に移行するための追い風が吹いてきたようにも感じています。

2023年の Vue 界隈はいよいよ Nuxt 3 一色になっていくはずです。この記事を読んで、Nuxt 3 を使ってみたいと思う方が1人でも増えたら嬉しい限りです!

脚注
  1. フロントからサーバーに送る際のバリデーション・型推論が未実装なので完璧ではありません ↩︎

Discussion

Yuki YamadaYuki Yamada

Nuxt 3の魅力がとても伝わる素晴らしい記事でした👏

自動インポートの部分で気になったのでコメントします。

.nuxtignoreは自動インポートから除外する機能ではなく、ビルド時のソースから除外するものだと思われます。公式ドキュメントでもビルド時に無視する旨だけが書かれています。

https://nuxt.com/docs/guide/directory-structure/nuxtignore#nuxt-ignore-file

現状では、自動インポートから特定のファイルを除く方法はなく、

  • components
  • composables

の2つのディレクトリ配下のは自動インポートの対象となると割り切ったほうが良いかと思います。

あるいはnuxt.config.tsautoImport: falseを設定することで自動インポートを無効にできる旨を追加しても良いかと思いました。

export default defineNuxtConfig({
  imports: {
    autoImport: false
  }
})

https://nuxt.com/docs/guide/concepts/auto-imports#disable-auto-imports

ykoizumi0903ykoizumi0903

コメントありがとうございます! .nuxtignore に関して誤解していたので内容を修正しました。

components については、

export default defineNuxtConfig({
  components: {
    dirs: [],
  },
})

のようにコンポーネントオプションの配列を空にすることで、自動登録の対象から除外することができそうでした。

composables utils については imports.dirs でもデフォルトの設定を上書きすることはできなかったので、autoImport を無効化する以外の方法はなさそうです。

Yuki YamadaYuki Yamada

ありがとうございます!

確かにcomponents配下に関しては、記載していただいた内容で制御できました。
共有していただきありがとうございます🙇‍♂️