T-CREATOR

Vite の公式ドキュメントを読み解く:主要 API と Tips

Vite の公式ドキュメントを読み解く:主要 API と Tips

モダンなフロントエンド開発において、ビルドツールの選択は開発効率を大きく左右します。Vite は、その高速性と使いやすさから多くの開発者に支持されているビルドツールです。

この記事では、Vite の公式ドキュメントを深く読み解き、実際の開発で役立つ主要 API と Tips をご紹介します。初心者の方でも理解しやすいよう、段階的に解説していきますので、ぜひ最後までお付き合いください。

Vite の基本概念と特徴

Vite は、Evan You 氏によって開発された次世代のフロントエンドビルドツールです。その最大の特徴は、開発時の驚異的な高速性にあります。

Vite の核となる技術

Vite は以下の技術を組み合わせることで、従来のビルドツールを凌駕するパフォーマンスを実現しています:

ES Modules(ESM)の活用

javascript// 従来のバンドル方式
import { createApp } from 'vue';
import App from './App.vue';

// Viteでは、ブラウザが直接ESMを理解できるため
// 開発時はバンドルせずにモジュールを直接提供

開発サーバーの高速起動

bash# Viteプロジェクトの作成
yarn create vite my-project --template vue

# 開発サーバーの起動(通常1秒以内)
cd my-project
yarn dev

従来ツールとの比較

項目WebpackVite
開発サーバー起動30 秒〜数分1 秒以内
ホットリロード遅い即座に反映
ビルド時間長い短い
設定の複雑さ複雑シンプル

Vite のこの高速性は、開発者の体験を劇的に改善し、より創造的な開発作業に集中できる環境を提供してくれます。

開発サーバーの設定と起動

Vite の開発サーバーは、その高速性の要となる部分です。適切に設定することで、さらに快適な開発環境を構築できます。

基本的な開発サーバーの起動

まず、Vite プロジェクトを作成して開発サーバーを起動してみましょう:

bash# プロジェクトの作成
yarn create vite my-vite-app --template react-ts

# 依存関係のインストール
cd my-vite-app
yarn install

# 開発サーバーの起動
yarn dev

開発サーバーの詳細設定

vite.config.tsファイルで開発サーバーの動作をカスタマイズできます:

typescriptimport { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    // ポート番号の指定
    port: 3000,
    // 自動でブラウザを開く
    open: true,
    // HTTPSの有効化
    https: false,
    // プロキシ設定
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});

よくある開発サーバーのエラーと解決策

ポートが既に使用されている場合

bash# エラーメッセージ
Error: listen EADDRINUSE: address already in use :::3000

# 解決策1: 別のポートを指定
yarn dev --port 3001

# 解決策2: 使用中のポートを確認して終了
lsof -ti:3000 | xargs kill -9

モジュールが見つからない場合

bash# エラーメッセージ
Error: Cannot find module './components/Header'

# 解決策: ファイルパスと拡張子を確認
# 正しい例
import Header from './components/Header.vue'
import Header from './components/Header.tsx'

開発サーバーの設定を適切に行うことで、チーム開発での一貫性を保ち、効率的な開発フローを実現できます。

ビルド設定と最適化

Vite のビルドプロセスは、本番環境でのパフォーマンスを最大化するために設計されています。適切な設定により、高速で軽量なアプリケーションを構築できます。

基本的なビルド設定

vite.config.tsでビルド設定をカスタマイズできます:

typescriptimport { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    // 出力ディレクトリ
    outDir: 'dist',
    // アセットの配置
    assetsDir: 'assets',
    // ソースマップの生成
    sourcemap: true,
    // チャンクサイズの警告閾値
    chunkSizeWarningLimit: 1000,
    // ロールアップの設定
    rollupOptions: {
      output: {
        // チャンクの分割
        manualChunks: {
          vendor: ['react', 'react-dom'],
          utils: ['lodash', 'axios'],
        },
      },
    },
  },
});

ビルドの実行と最適化

bash# 本番用ビルドの実行
yarn build

# ビルド結果のプレビュー
yarn preview

ビルド時のよくあるエラーと解決策

依存関係の解決エラー

bash# エラーメッセージ
Error: Could not resolve entry module "src/main.tsx"

# 解決策: エントリーポイントの確認
// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: 'src/main.tsx'
      }
    }
  }
})

アセットの読み込みエラー

bash# エラーメッセージ
Error: Failed to load resource: net::ERR_FILE_NOT_FOUND

# 解決策: パブリックディレクトリの設定
// vite.config.ts
export default defineConfig({
  publicDir: 'public',
  build: {
    assetsInlineLimit: 4096 // 4KB以下のアセットはインライン化
  }
})

ビルド最適化の Tips

コード分割の活用

typescript// 動的インポートによるコード分割
const LazyComponent = lazy(
  () => import('./components/LazyComponent')
);

// 条件付きインポート
if (process.env.NODE_ENV === 'development') {
  import('./utils/devTools');
}

アセットの最適化

typescript// vite.config.ts
export default defineConfig({
  build: {
    // 画像の最適化
    assetsInlineLimit: 4096,
    // CSSの分割
    cssCodeSplit: true,
    // 不要なコードの除去
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
    },
  },
});

適切なビルド設定により、ユーザーが快適に利用できるアプリケーションを提供できます。

プラグインシステムの活用

Vite のプラグインシステムは、開発効率を大幅に向上させる強力な機能です。公式プラグインからコミュニティプラグインまで、豊富な選択肢があります。

公式プラグインの活用

React プラグイン

bash# Reactプラグインのインストール
yarn add -D @vitejs/plugin-react
typescript// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    react({
      // Fast Refreshの設定
      fastRefresh: true,
      // JSXの設定
      jsxRuntime: 'automatic',
    }),
  ],
});

Vue プラグイン

bash# Vueプラグインのインストール
yarn add -D @vitejs/plugin-vue
typescript// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
});

人気のコミュニティプラグイン

ESLint プラグイン

bash# ESLintプラグインのインストール
yarn add -D vite-plugin-eslint
typescript// vite.config.ts
import { defineConfig } from 'vite';
import eslint from 'vite-plugin-eslint';

export default defineConfig({
  plugins: [
    eslint({
      include: ['src/**/*.ts', 'src/**/*.tsx'],
      exclude: ['node_modules/**'],
    }),
  ],
});

PWA プラグイン

bash# PWAプラグインのインストール
yarn add -D vite-plugin-pwa
typescript// vite.config.ts
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    VitePWA({
      registerType: 'autoUpdate',
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
      },
    }),
  ],
});

プラグイン開発の基礎

カスタムプラグインを作成することで、プロジェクト固有の要件に対応できます:

typescript// plugins/my-plugin.ts
import type { Plugin } from 'vite';

export default function myPlugin(): Plugin {
  return {
    name: 'my-plugin',
    // プラグインの初期化
    config(config, { command }) {
      console.log(`Running in ${command} mode`);
    },
    // ファイルの変換
    transform(code, id) {
      if (id.endsWith('.vue')) {
        // Vueファイルの処理
        return code.replace(
          /console\.log/g,
          '// console.log'
        );
      }
    },
  };
}
typescript// vite.config.ts
import { defineConfig } from 'vite';
import myPlugin from './plugins/my-plugin';

export default defineConfig({
  plugins: [myPlugin()],
});

プラグイン関連のよくあるエラー

プラグインの読み込みエラー

bash# エラーメッセージ
Error: Cannot find module '@vitejs/plugin-react'

# 解決策: プラグインの再インストール
yarn add -D @vitejs/plugin-react

プラグインの設定エラー

bash# エラーメッセージ
Error: Plugin "my-plugin" does not export a default function

# 解決策: プラグインのエクスポート形式を確認
export default function myPlugin() {
  return {
    name: 'my-plugin'
  }
}

プラグインシステムを活用することで、開発効率を大幅に向上させ、プロジェクトの要件に最適化された開発環境を構築できます。

環境変数と設定ファイル

Vite では、環境変数と設定ファイルを活用することで、開発環境と本番環境で異なる設定を管理できます。これにより、安全で効率的な開発が可能になります。

環境変数の設定と利用

環境変数ファイルの作成

bash# .env(全環境共通)
VITE_APP_TITLE=My Vite App
VITE_API_BASE_URL=https://api.example.com

# .env.development(開発環境)
VITE_API_BASE_URL=http://localhost:3000
VITE_DEBUG_MODE=true

# .env.production(本番環境)
VITE_API_BASE_URL=https://api.production.com
VITE_DEBUG_MODE=false

環境変数の利用

typescript// src/config/api.ts
export const API_CONFIG = {
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 5000,
  debug: import.meta.env.VITE_DEBUG_MODE === 'true',
};

// src/utils/logger.ts
export const logger = {
  log: (message: string) => {
    if (import.meta.env.VITE_DEBUG_MODE === 'true') {
      console.log(`[DEBUG] ${message}`);
    }
  },
};

設定ファイルの階層構造

プロジェクトルートの設定

typescript// vite.config.ts
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig(({ command, mode }) => {
  // 環境変数の読み込み
  const env = loadEnv(mode, process.cwd(), '');

  return {
    plugins: [react()],
    define: {
      // グローバル定数の定義
      __APP_VERSION__: JSON.stringify(
        env.npm_package_version
      ),
      __BUILD_TIME__: JSON.stringify(
        new Date().toISOString()
      ),
    },
    server: {
      port: parseInt(env.VITE_PORT) || 3000,
    },
  };
});

環境別の設定ファイル

typescript// config/vite.dev.ts
import { defineConfig } from 'vite';
import baseConfig from './vite.base';

export default defineConfig({
  ...baseConfig,
  server: {
    port: 3000,
    open: true,
  },
  build: {
    sourcemap: true,
  },
});
typescript// config/vite.prod.ts
import { defineConfig } from 'vite';
import baseConfig from './vite.base';

export default defineConfig({
  ...baseConfig,
  build: {
    sourcemap: false,
    minify: 'terser',
  },
});

環境変数関連のよくあるエラー

環境変数が読み込まれない

bash# エラーメッセージ
import.meta.env.VITE_API_URL is undefined

# 解決策1: 環境変数名の確認(VITE_プレフィックスが必要)
VITE_API_URL=https://api.example.com

# 解決策2: 環境変数ファイルの配置場所を確認
# .envファイルはプロジェクトルートに配置

型定義のエラー

typescript// src/env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_BASE_URL: string;
  readonly VITE_DEBUG_MODE: string;
  readonly VITE_APP_TITLE: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

設定のベストプラクティス

セキュリティを考慮した設定

typescript// vite.config.ts
export default defineConfig({
  define: {
    // 機密情報は環境変数から読み込み
    __API_KEY__: JSON.stringify(process.env.VITE_API_KEY),
    // 不要な情報は除外
    __NODE_ENV__: JSON.stringify(process.env.NODE_ENV),
  },
  server: {
    // 開発時のみの設定
    ...(process.env.NODE_ENV === 'development' && {
      proxy: {
        '/api': {
          target: 'http://localhost:8080',
          changeOrigin: true,
        },
      },
    }),
  },
});

環境別の最適化

typescript// vite.config.ts
export default defineConfig(({ mode }) => {
  const isProduction = mode === 'production';

  return {
    build: {
      // 本番環境ではソースマップを無効化
      sourcemap: !isProduction,
      // 本番環境ではコンソールログを除去
      minify: isProduction ? 'terser' : false,
      ...(isProduction && {
        terserOptions: {
          compress: {
            drop_console: true,
            drop_debugger: true,
          },
        },
      }),
    },
  };
});

適切な環境変数と設定ファイルの管理により、開発から本番まで一貫した設定を維持できます。

パフォーマンス最適化の Tips

Vite の真価は、その優れたパフォーマンスにあります。適切な最適化を行うことで、ユーザー体験を大幅に向上させることができます。

コード分割の最適化

動的インポートの活用

typescript// src/components/LazyComponent.tsx
import { lazy, Suspense } from 'react';

// 動的インポートによるコード分割
const HeavyComponent = lazy(
  () => import('./HeavyComponent')
);

export default function LazyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

ルートベースのコード分割

typescript// src/router/index.tsx
import { lazy } from 'react';
import { Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('../pages/Home'));
const About = lazy(() => import('../pages/About'));
const Contact = lazy(() => import('../pages/Contact'));

export default function AppRouter() {
  return (
    <Routes>
      <Route path='/' element={<Home />} />
      <Route path='/about' element={<About />} />
      <Route path='/contact' element={<Contact />} />
    </Routes>
  );
}

アセットの最適化

画像の最適化設定

typescript// vite.config.ts
export default defineConfig({
  build: {
    // アセットのインライン化閾値
    assetsInlineLimit: 4096,
    // アセットのファイル名設定
    rollupOptions: {
      output: {
        assetFileNames: (assetInfo) => {
          const info = assetInfo.name.split('.');
          const ext = info[info.length - 1];
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(ext)) {
            return `images/[name]-[hash][extname]`;
          }
          return `assets/[name]-[hash][extname]`;
        },
      },
    },
  },
});

CSS の最適化

typescript// vite.config.ts
export default defineConfig({
  css: {
    // CSSの分割
    postcss: {
      plugins: [
        require('autoprefixer'),
        require('cssnano')({
          preset: 'default',
        }),
      ],
    },
  },
});

キャッシュ戦略の実装

Service Worker の活用

typescript// public/sw.js
const CACHE_NAME = 'vite-app-v1';
const urlsToCache = [
  '/',
  '/static/js/main.js',
  '/static/css/main.css',
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches
      .match(event.request)
      .then((response) => response || fetch(event.request))
  );
});

HTTP キャッシュヘッダーの設定

typescript// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // ファイル名にハッシュを含める
        entryFileNames: 'js/[name]-[hash].js',
        chunkFileNames: 'js/[name]-[hash].js',
        assetFileNames: 'assets/[name]-[hash][extname]',
      },
    },
  },
});

パフォーマンス監視の実装

Web Vitals の測定

typescript// src/utils/performance.ts
import {
  getCLS,
  getFID,
  getFCP,
  getLCP,
  getTTFB,
} from 'web-vitals';

export function reportWebVitals() {
  getCLS(console.log);
  getFID(console.log);
  getFCP(console.log);
  getLCP(console.log);
  getTTFB(console.log);
}

パフォーマンスメトリクスの収集

typescript// src/utils/metrics.ts
export function measurePerformance() {
  // ページロード時間の測定
  window.addEventListener('load', () => {
    const loadTime = performance.now();
    console.log(`Page load time: ${loadTime}ms`);
  });

  // リソース読み込み時間の測定
  const observer = new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) => {
      if (entry.entryType === 'resource') {
        console.log(`${entry.name}: ${entry.duration}ms`);
      }
    });
  });
  observer.observe({ entryTypes: ['resource'] });
}

よくあるパフォーマンス問題と解決策

バンドルサイズが大きすぎる

bash# 分析コマンド
yarn build --analyze

# 解決策: 不要な依存関係の除去
yarn remove unused-package

初回ロードが遅い

typescript// 解決策: プリロードの活用
<link rel="preload" href="/static/js/main.js" as="script">
<link rel="preload" href="/static/css/main.css" as="style">

ホットリロードが遅い

typescript// vite.config.ts
export default defineConfig({
  server: {
    // ファイル監視の最適化
    watch: {
      usePolling: false,
      interval: 100,
    },
  },
});

パフォーマンス最適化により、ユーザーが快適に利用できるアプリケーションを提供できます。

トラブルシューティングとデバッグ

開発中に遭遇する問題を効率的に解決するため、Vite のトラブルシューティングとデバッグ手法を身につけましょう。

よくあるエラーと解決策

モジュール解決エラー

bash# エラーメッセージ
Error: Cannot resolve module 'react' from '/src/components/App.tsx'

# 解決策1: 依存関係の確認
yarn install

# 解決策2: node_modulesの再構築
rm -rf node_modules yarn.lock
yarn install

# 解決策3: パスエイリアスの設定
// vite.config.ts
export default defineConfig({
  resolve: {
    alias: {
      '@': '/src',
      '~': '/src'
    }
  }
})

TypeScript 設定エラー

bash# エラーメッセージ
TS2307: Cannot find module './components/Header' or its corresponding type declarations.

# 解決策1: ファイル拡張子の追加
import Header from './components/Header.tsx'

# 解決策2: TypeScript設定の確認
// tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  }
}

ビルドエラー

bash# エラーメッセージ
Error: ENOENT: no such file or directory, open 'src/main.tsx'

# 解決策: エントリーポイントの確認
// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: 'src/main.tsx'
      }
    }
  }
})

デバッグ手法

開発サーバーの詳細ログ

bash# 詳細ログの有効化
yarn dev --debug

# 特定のプラグインのデバッグ
DEBUG=vite:* yarn dev

ビルド分析ツールの活用

bash# バンドル分析
yarn add -D rollup-plugin-visualizer

# vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    visualizer({
      open: true,
      filename: 'dist/stats.html'
    })
  ]
})

パフォーマンスプロファイリング

typescript// src/utils/debug.ts
export function debugPerformance() {
  if (import.meta.env.DEV) {
    // メモリ使用量の監視
    setInterval(() => {
      const memory = performance.memory;
      console.log(
        `Memory usage: ${
          memory.usedJSHeapSize / 1024 / 1024
        }MB`
      );
    }, 5000);

    // レンダリング時間の測定
    const observer = new PerformanceObserver((list) => {
      list.getEntries().forEach((entry) => {
        if (entry.entryType === 'measure') {
          console.log(`${entry.name}: ${entry.duration}ms`);
        }
      });
    });
    observer.observe({ entryTypes: ['measure'] });
  }
}

開発環境の最適化

ホットリロードの設定

typescript// vite.config.ts
export default defineConfig({
  server: {
    // ホットリロードの設定
    hmr: {
      overlay: true,
      port: 24678,
    },
    // ファイル監視の最適化
    watch: {
      usePolling: false,
      interval: 100,
      ignored: ['**/node_modules/**', '**/dist/**'],
    },
  },
});

エラーハンドリングの改善

typescript// src/utils/errorBoundary.tsx
import React from 'react';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error(
      'Error caught by boundary:',
      error,
      errorInfo
    );
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

本番環境でのトラブルシューティング

本番ビルドの検証

bash# ビルドの実行
yarn build

# ビルド結果のプレビュー
yarn preview

# ビルドサイズの確認
du -sh dist/

ログの収集と分析

typescript// src/utils/logger.ts
export const logger = {
  error: (message: string, error?: Error) => {
    console.error(`[ERROR] ${message}`, error);
    // 本番環境では外部サービスに送信
    if (import.meta.env.PROD) {
      // SentryやLogRocketなどのサービスに送信
    }
  },
  warn: (message: string) => {
    console.warn(`[WARN] ${message}`);
  },
  info: (message: string) => {
    console.info(`[INFO] ${message}`);
  },
};

ヘルスチェックの実装

typescript// src/utils/healthCheck.ts
export async function healthCheck() {
  try {
    const response = await fetch('/api/health');
    if (!response.ok) {
      throw new Error('Health check failed');
    }
    return true;
  } catch (error) {
    console.error('Health check error:', error);
    return false;
  }
}

適切なトラブルシューティングとデバッグ手法により、開発効率を大幅に向上させることができます。

まとめ

Vite の公式ドキュメントを読み解き、主要 API と Tips をご紹介しました。Vite は、その高速性と使いやすさから、モダンなフロントエンド開発において欠かせないツールとなっています。

今回学んだ重要なポイント

  1. Vite の基本概念: ES Modules を活用した高速な開発サーバー
  2. 開発サーバーの設定: カスタマイズ可能な開発環境の構築
  3. ビルド設定: 本番環境での最適化手法
  4. プラグインシステム: 豊富な拡張機能の活用
  5. 環境変数管理: 安全で効率的な設定管理
  6. パフォーマンス最適化: ユーザー体験の向上
  7. トラブルシューティング: 効率的な問題解決

今後の学習の方向性

Vite を活用した開発をさらに深めるために、以下の分野の学習をお勧めします:

  • フレームワーク固有の最適化: React、Vue、Svelte との連携
  • マイクロフロントエンド: 大規模アプリケーションでの活用
  • CI/CD パイプライン: 自動化されたビルドとデプロイ
  • パフォーマンス監視: 継続的な改善の実現

Vite の真価は、開発者の体験を劇的に改善することにあります。この記事で学んだ知識を活用し、より創造的で効率的な開発を実現してください。

開発の旅路で、Vite があなたの強力な味方となることを願っています。新しい発見と学びが、素晴らしいアプリケーションの創造につながることを期待しています。

関連リンク