Contents
前提条件と Nuxt バージョン選定
このセクションでは、プロジェクトを開始する前に必ず確認すべき開発環境の最低要件と、Nuxt 2 と Nuxt 3 のどちらを採用すべきか を判断するための比較ポイントを解説します。適切な Node 系列やパッケージマネージャのバージョンが揃っていないと、後々のビルドエラーや型チェックの不整合が頻発します。また、公式サポート状況は選定に直結する重要情報ですので、最新情報へのリンクも併せて提示します。
推奨開発ツールのバージョン
| ツール | 推奨バージョン | 主な理由 |
|---|---|---|
| Node.js | 18.17 以上(LTS) | ES2022 の機能と npm 9 系が標準で利用でき、Nuxt が推奨する Vite/webpack と相性が良い |
| npm | 9.x 系 | ワークスペースや package-lock.json の安定性が向上 |
| Yarn | 3.4 以上(Berry) | Plug‑and‑Play や Zero‑Installs が利用でき、CI 時のキャッシュ効率が高い |
| Git | 2.40 以降 | 差分取得やサブモジュール管理に必須 |
ターミナルで node -v && npm -v && git --version を実行し、上記要件を満たすことを確認してください。バージョンが古い場合は nvm(Node)や corepack(Yarn)で切り替えると手軽です。
Nuxt 2 と Nuxt 3 の比較ポイント
| 項目 | Nuxt 2 (v2.15 系) | Nuxt 3 (v3.x 系) |
|---|---|---|
| 公式サポート | 2024 年末頃に保守モードへ移行する可能性があり、2025 年末までの LTS が保証されている(※公式サポートページを参照) | 現行メジャーバージョンとして継続的に機能追加・バグ修正が提供され、長期的な保守性が最も高い |
| コア言語 | Vue 2 + Options API | Vue 3 + Composition API がデフォルト |
| ビルドツール | webpack 4/5(@nuxt/webpack) |
Vite(nuxi dev)と Webpack のハイブリッドサポート。Vite が標準 |
| TypeScript 対応 | @nuxt/typescript-build 等のプラグインで後付けが可能 |
プロジェクト作成時に tsconfig.json が自動生成され、typeCheck オプションが標準装備 |
| 推奨パッケージ | @nuxt/typescript-build, typescript, vue-tsc などを手動で追加 |
追加インストール不要(内部で typescript と vue-tsc を使用) |
選定基準のポイント
- 保守性と将来性 – 新規開発は Nuxt 3 が推奨。既存プロジェクトが Vue 2 に強く依存している場合は、移行コストを評価した上で Nuxt 2 のまま TypeScript を導入する選択肢も残ります。
- エコシステムの成熟度 – 多くの公式モジュールが Nuxt 3 に最適化されており、
@nuxtjs/axios系はnitro経由の HTTP クライアントへ置き換わっています。 - 機能差と型安全性 – Auto‑import、Server‑Side Rendering の最適化、Composable の型推論など、Nuxt 3 が提供する最新機能は TypeScript と相性が抜群です。
新規プロジェクトへの TypeScript 導入手順
この章では 「Nuxt 3」 と 「Nuxt 2(Bridge あり/なし)」 のそれぞれで、TypeScript プロジェクトを最速で作成する手順とオプションの意味合いを解説します。CLI に渡すフラグは初心者にとって分かりづらいことが多いため、具体的な挙動も合わせて記載しています。
Nuxt 3:nuxi init --ts で TypeScript 雛形を作成
nuxi は Nuxt 3 の公式 CLI です。--ts フラグを付与すると、TypeScript 用の設定ファイル一式が自動生成されます。
|
1 2 3 4 5 6 7 |
# npm ユーザー向け(Yarn/PNPM でも同様に置き換えて使用) npx nuxi init my-nuxt3-app --ts # 生成されたディレクトリへ移動し依存パッケージをインストール cd my-nuxt3-app npm install # Yarn を使う場合は `yarn install` |
--tsの意味nuxt.config.tsが作成され、型安全な設定が可能になる。tsconfig.jsonが同梱され、Vue SFC(.vue)内の<script lang="ts">を自動認識。types/ディレクトリに Nuxt の型定義ヘルパーが配置され、IDE 補完が有効になる。
生成ディレクトリ例
|
1 2 3 4 5 6 7 |
my-nuxt3-app/ ├─ app.vue ├─ nuxt.config.ts ← TypeScript 設定ファイル ├─ tsconfig.json └─ pages/ └─ index.vue ← <script lang="ts"> がデフォルトで有効 |
公式ドキュメントは Nuxt 3 の TypeScript ガイド に詳しく掲載されています。npm run dev で開発サーバーを起動すると、内部的に typeCheck: true が有効化され、保存時に自動で型チェックが走ります。
Nuxt 2(Bridge 使用)で TypeScript を有効化
Nuxt 2 単体では TypeScript の型定義が限定的ですが、@nuxt/bridge を導入すれば defineNuxtConfig が利用でき、ほぼ Nuxt 3 ライクな設定が可能です。以下は Bridge プロジェクトを作成しつつ TypeScript を組み込む手順です。
|
1 2 3 4 5 6 7 8 9 10 |
# 1. create-nuxt-app でベースプロジェクトを生成(--typescript は旧オプションなので無視) npx create-nuxt-app my-nuxt2-bridge # 2. プロジェクトディレクトリへ移動し Bridge と TypeScript 関連パッケージを追加 cd my-nuxt2-bridge npm i -D @nuxt/bridge @nuxt/typescript-build typescript vue-tsc # 3. nuxt.config.js → nuxt.config.ts に変換(後述の移行手順参照) mv nuxt.config.js nuxt.config.ts |
nuxi init --ts の Yarn バージョン
Yarn (Berry) ユーザーは dlx コマンドで同等処理が可能です。
|
1 2 3 |
yarn dlx nuxi@latest init my-nuxt3-app --ts cd my-nuxt3-app && yarn install |
dlxは一時的にパッケージを実行する Yarn の機能で、グローバルインストールが不要です。- フラグの意味は npm 版と同様です。
既存 Nuxt 2 プロジェクトへの TypeScript 後付け
ここでは すでに稼働中の Nuxt 2 アプリ に対し、最小限の手順で型安全性を追加する方法を体系的に示します。主な流れは「依存パッケージ導入 → nuxt.config の TypeScript 変換 → tsconfig.json 設定」の三段階です。
必要パッケージのインストール
|
1 2 3 4 |
npm i -D @nuxt/typescript-build typescript vue-tsc # Yarn を使う場合は yarn add -D @nuxt/typescript-build typescript vue-tsc |
- @nuxt/typescript-build
- Nuxt のビルドパイプラインに TypeScript コンパイラをフックし、
.vue内の<script lang="ts">を認識させます。 - typescript と vue-tsc は型チェックと Vue SFC の検証に必須です。
nuxt.config.js → nuxt.config.ts への移行
重要ポイント:Nuxt 2 単体で
defineNuxtConfigが使えるのは @nuxt/bridge を導入した場合のみです。Bridge 未使用の場合は従来通りexport default {}のままで構いませんが、型安全化を本格的に行うなら Bridge 推奨です。
1. ファイル名変更
|
1 2 |
mv nuxt.config.js nuxt.config.ts |
2. 正しいインポート文を追記
| ケース | インポート例 |
|---|---|
| Bridge を使用 | import { defineNuxtConfig } from '@nuxt/bridge' |
| 純粋な Nuxt 2(型チェックだけ) | // 型定義は不要です。export default {} のままで OK |
3. 設定ファイルを書き換える
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// nuxt.config.ts (Bridge 使用例) import { defineNuxtConfig } from '@nuxt/bridge' export default defineNuxtConfig({ // 既存設定をそのまま貼り付け srcDir: 'src/', buildModules: [ '@nuxt/typescript-build', // 他のモジュール … ], typescript: { typeCheck: true, // ビルド時に vue-tsc が走る shim: false // .vue ファイルで明示的な型定義を要求 } }) |
4. tsconfig.json の作成・カスタマイズ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "extends": "./node_modules/@nuxt/typescript-build/tsconfig.json", "compilerOptions": { "target": "ES2022", "module": "ESNext", "strict": true, "baseUrl": ".", "paths": { "~/*": ["./*"], "@/*": ["./*"] }, "typeRoots": [ "./types", "./node_modules/@types" }, "esModuleInterop": true, "noImplicitAny": true }, "include": ["**/*.ts", "**/*.vue"], "exclude": ["node_modules", ".nuxt", "dist"] } |
extendsによって @nuxt/typescript-build が提供するデフォルト設定 を継承し、プロジェクト固有のカスタマイズだけを上書きします。pathsは Nuxt のエイリアスと一致させることで IDE 補完が正しく機能します。
実務で役立つ tsconfig カスタマイズ例
| カスタム項目 | 目的 | 設定例 |
|---|---|---|
| API エイリアス | services/api/* を短縮インポートしたい |
"paths": { "#api/*": ["./services/api/*"] } |
| 環境変数型定義 | process.env に独自キーを付与 |
declare namespace NodeJS { interface ProcessEnv { API_URL: string; NODE_ENV: 'development' | 'production'; } } を types/env.d.ts に配置 |
| strictNullChecks の有効化 | null/undefined バグの早期検出 | "strictNullChecks": true(strict が true なら自動) |
Vue コンポーネント・プラグインの TypeScript 化
この章では、Vue SFC と Nuxt のプラグイン/ミドルウェアを 型安全に記述 するためのベストプラクティスと、実装例を多数紹介します。コンポーネント間で正確な型が共有できれば、IDE が自動補完・リファクタリング支援を行ってくれるので開発効率が大幅に向上します。
<script lang="ts"> を用いた基本コンポーネント例
以下は カウンター コンポーネントの最小構成です。ref<number> のようにジェネリックで明示的に型指定すると、Vue が提供する型推論が正確になります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<template> <button @click="increment">{{ count }}</button> </template> <script lang="ts"> import { defineComponent, ref } from 'vue' export default defineComponent({ name: 'CounterButton', setup() { const count = ref<number>(0) const increment = () => (count.value += 1) return { count, increment } } }) </script> |
- ポイント
defineComponentの戻り値は自動的にコンポーネント型としてエクスポートされ、他ファイルからインポートしたときも型情報が保持されます。<script lang="ts">が付いているだけで vue‑tsc が.vue内の型チェックを実行します。
Props と Emits の型定義ベストプラクティス
| 項目 | 実装例 | 解説 |
|---|---|---|
| Props のリテラル型 | role: { type: String as PropType<'admin'|'editor'|'viewer'>, default: 'viewer' } |
Union 型で許容値を限定し、IDE が補完候補を提示 |
| Emit の型安全化 | emits: { update: (payload: User) => true } |
関数シグネチャで payload の型を明示。emit('update', user) 時に型チェックが走る |
| Composable での型エクスポート | export type UseUserReturn = ReturnType<typeof useUser> |
再利用可能な型エイリアスを作成し、テストコードでも同一定義を使用 |
Props / Emits の実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import { defineComponent, PropType } from 'vue' type User = { id: number name: string } export default defineComponent({ name: 'UserCard', props: { userId: { type: Number as PropType<number>, required: true }, role: { type: String as PropType<'admin' | 'editor' | 'viewer'>, default: 'viewer' } }, emits: ['update'], async setup(props, { emit }) { const load = async () => { const data: User = await fetchUser(props.userId) emit('update', data) // payload が User 型であることが保証される } return { load } } }) |
プラグイン・ミドルウェアの型宣言方法
Nuxt 3 用プラグイン例(plugins/api-client.ts)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// plugins/api-client.ts import { defineNuxtPlugin } from '#app' import type { AxiosInstance } from 'axios' export default defineNuxtPlugin((nuxtApp) => { const api: AxiosInstance = createAxiosInstance() nuxtApp.provide('api', api) }) // コンテキストに型拡張 declare module '#app' { interface NuxtApp { $api: AxiosInstance } } |
defineNuxtPluginの第1引数は NuxtApp オブジェクトです。provideによって$apiがコンテキストに注入され、全ページ・コンポーネントでconst { $api } = useNuxtApp()と型安全に取得できます。
Nuxt 2(Bridge)用プラグイン例
|
1 2 3 4 5 6 7 8 9 |
// plugins/api-client.ts (Bridge) import { defineNuxtPlugin } from '@nuxt/bridge' import type { AxiosInstance } from 'axios' export default defineNuxtPlugin((context, inject) => { const api: AxiosInstance = createAxiosInstance() inject('api', api) // context.$api が利用可能になる }) |
ミドルウェア(認証チェック)
|
1 2 3 4 5 6 7 8 9 10 |
// middleware/auth.ts (Nuxt 3) import { defineNuxtRouteMiddleware, navigateTo } from '#app' export default defineNuxtRouteMiddleware((to, from) => { const auth = useAuth() if (!auth.loggedIn && to.path !== '/login') { return navigateTo('/login') } }) |
defineNuxtRouteMiddlewareが受け取るtoとfromは NavigationGuard の型情報が付与されているため、IDE がルートパラメータの補完を行います。
開発環境・CI/CD と落とし穴対策
ここでは ESLint/Prettier の連携, GitHub Actions による型チェック自動化, そして 実務で頻出する型関連の罠 を取り上げます。CI パイプラインに組み込むだけで、ローカルと本番環境の差異によるバグを大幅に削減できます。
ESLint / Prettier と @nuxtjs/eslint-module の連携設定
|
1 2 3 4 |
npm i -D eslint @nuxtjs/eslint-module \ eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin \ prettier eslint-config-prettier |
eslint.config.js(Flat Config)例(Nuxt 3)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import js from '@eslint/js' import vue from 'eslint-plugin-vue' import parser from '@typescript-eslint/parser' export default [ js.configs.recommended, ...vue.configs['flat/recommended'], { files: ['**/*.ts', '**/*.vue'], languageOptions: { parser, parserOptions: { project: './tsconfig.json' } }, plugins: { '@typescript-eslint': require('@typescript-eslint/eslint-plugin') }, rules: { 'no-console': 'warn', '@typescript-eslint/no-explicit-any': 'error', // Prettier と競合しないように無効化 ...require('eslint-config-prettier') } } ] |
parserOptions.projectにtsconfig.jsonを指定することで、型情報を参照したルール(例: no-unused-vars) が正しく機能します。@nuxtjs/eslint-moduleの設定はnuxt.config.tsに追記し、開発サーバ起動時に自動で Lint が走るようにします。
|
1 2 3 4 5 6 7 8 9 10 11 |
// nuxt.config.ts export default defineNuxtConfig({ eslint: { lintOnStart: true, configFile: 'eslint.config.js' }, typescript: { typeCheck: true // vue-tsc がビルド時に実行される } }) |
GitHub Actions での型チェック&ビルド自動化
以下は Node 18, npm, Nuxt 3 プロジェクトを想定した最小構成です。vue-tsc --noEmit によって .vue を含む全ファイルの型検査が高速に走ります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
name: CI on: push: branches: [main, develop] pull_request: jobs: lint-test-build: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x] steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Install dependencies run: npm ci - name: Lint (ESLint + Prettier) run: | npx eslint . --ext .js,.ts,.vue npx prettier --check . - name: TypeScript type check (including .vue) run: npx vue-tsc --noEmit - name: Build production bundle run: npm run build # nuxt.config.ts の typeCheck が再度実行される - name: Upload artifact (dist) if: success() uses: actions/upload-artifact@v3 with: name: nuxt-output path: .output/ |
- キャッシュ(
actions/cache)を追加すれば依存インストール時間が半減しますが、ここではシンプルさを優先しています。 npm run buildが走る段階でnuxt.config.tsのtypeCheck: trueが再度適用され、CI とローカルの挙動が一致します。
実務で遭遇しやすい型関連の落とし穴と対策
| 落とし穴 | 具体例 | 推奨対策 |
|---|---|---|
Auto‑import の型が any |
useFetch を自動インポートしたら IDE が any と表示 |
nuxi prepare で型定義ファイルを生成し、nuxt.d.ts に declare function useFetch<T>(...): Promise<T> を追記 |
| サードパーティモジュールに型が無い | import dayjs from 'dayjs' → 型情報が欠如 |
npm i -D @types/dayjs か、types/dayjs.d.ts に declare module 'dayjs'; を追加 |
.vue の型宣言不足 |
<MyComponent/> が「Property does not exist on type …」とエラーになる |
Nuxt 3 では自動生成される components.d.ts をプロジェクトに残すか、手動で shims-vue.d.ts に declare module '*.vue' { import Vue from 'vue'; export default Vue; } を記述 |
| strict モードでの null/undefined エラー | API のレスポンスが { data: T | null } だとビルドエラー |
DTO(Data Transfer Object)を type ApiResponse<T> = { data: T | null } と定義し、使用箇所で if (resp.data) … ガードを必ず入れる |
| paths エイリアスが IDE とビルドで不一致 | import Foo from '@/components/Foo.vue' が VSCode では解決できない |
tsconfig.json の paths と nuxt.config.ts の alias を同一に保ち、例: alias: { '@': resolve(__dirname, './') } |
Auto‑import 型生成の具体手順
|
1 2 3 4 5 |
# プロジェクトルートで実行 npx nuxi prepare # これにより .nuxt/types.d.ts が作成され、全 auto‑import 関数に型が付与される |
shims-vue.d.ts のサンプル
|
1 2 3 4 5 6 7 |
// types/shims-vue.d.ts declare module '*.vue' { import { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component } |
まとめ
- 開発環境は Node 18+、npm 9+/Yarn 3+、Git 2.40+ を満たすことが前提です。
- Nuxt のバージョン選定では公式サポートの見通し(Nuxt 2 は 2024 年末頃に保守モードへ移行する可能性)とエコシステムの成熟度を比較し、長期的に保守しやすい Nuxt 3 を推奨します。
- 新規プロジェクトは
npx nuxi init --ts(または Yarn のdlx)で TypeScript 雛形を即生成し、公式の Nuxt 3 TypeScript ガイド を参照してください。 - 既存 Nuxt 2 へは
@nuxt/bridgeと@nuxt/typescript-buildの組み合わせでnuxt.config.tsに変換し、tsconfig.jsonを整備すれば型安全化が完了します。 - コンポーネント・プラグインは
<script lang="ts">とdefineComponent / defineNuxtPluginを活用し、PropTypeやEmitの型定義で契約を明示すると IDE 補完が最大化します。 - CI/CDでは ESLint/Prettier と
vue-tsc --noEmitを組み合わせた GitHub Actions が最小構成で効果的です。 - 落とし穴対策として Auto‑import の型生成、サードパーティの型宣言、エイリアス統一などを事前に実装しておくことで、開発途中やデプロイ時の型エラーを大幅に減らせます。
上記手順とベストプラクティスに沿って設定すれば、Nuxt プロジェクト全体のコード品質が向上し、保守性・拡張性の高い TypeScript 開発環境が構築できます。ぜひ本稿をリファレンスとして、プロジェクトごとに適切な選択と設定を行ってください。