Communitygithub.com

Viteパターン集

Viteビルドツールの設定、プラグイン、HMR、環境変数、プロキシ設定、SSR、ライブラリモード、依存関係のプリバンドル、ビルド最適化に関するパターン集。vite.config.tsやViteプラグイン、Viteベースのプロジェクトを扱う際に有効化。

Viteパターン集 とは?

このスキルは、Vite 8+ プロジェクト向けのビルドツールおよび開発サーバーのパターンを包括的にまとめたガイドです。vite.config.ts の設定、環境変数、プロキシ設定、ライブラリモード、依存関係のプリバンドル、そして一般的な本番環境の落とし穴をカバーします。開発モードではソースファイルをネイティブESMとして提供し、バンドルを行わないため高速な起動と正確なHMRを実現。ビルドモードではRolldown(v7+)またはRollup(v5–v6)を使用し、ツリーシェイキングやコード分割、Oxcベースのミニファイを実行します。プラグインは開発・ビルド間で統一されたインターフェースを持ち、環境変数はビルド時に静的にインライン化されます。また、`VITE_`接頭辞のセキュリティ境界、バレルファイルの回避、依存関係のプリバンドル最適化など、パフォーマンスとセキュリティに関するベストプラクティスも提供します。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/vite-patterns

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Viteパターン集 は何をしますか?

Vite 8+ プロジェクト向けのビルドツールおよび開発サーバーのパターン集。設定、環境変数、プロキシ設定、ライブラリモード、依存関係のプリバンドル、一般的な本番環境の落とし穴を網羅します。

使用するタイミング

  • vite.config.ts または vite.config.js の設定
  • 環境変数または .env ファイルの設定
  • APIバックエンド向けの開発サーバープロキシ設定
  • ビルド出力の最適化(チャンク、ミニファイ、アセット)
  • build.lib によるライブラリの公開
  • 依存関係のプリバンドルまたはCJS/ESM相互運用のトラブルシューティング
  • HMR、開発サーバー、ビルドエラーのデバッグ
  • Viteプラグインの選択または順序付け

仕組み

  • 開発モードでは、ソースファイルをネイティブESMとして提供し、バンドルは行いません。変換はモジュールリクエストごとにオンデマンドで実行されるため、コールドスタートが高速でHMRが正確です。
  • ビルドモードでは、Rolldown(v7+)またはRollup(v5–v6)を使用してアプリケーションを本番用にバンドルし、ツリーシェイキング、コード分割、Oxcベースのミニファイを実行します。
  • 依存関係のプリバンドルは、CJS/UMDの依存関係をesbuildを介して一度だけESMに変換し、その結果を node_modules/.vite にキャッシュします。これにより、以降の起動ではこの処理がスキップされます。
  • プラグインは開発とビルドで統一されたインターフェースを共有します。同じプラグインオブジェクトが、開発サーバーのオンデマンド変換と本番パイプラインの両方で機能します。
  • 環境変数はビルド時に静的にインライン化されます。VITE_ 接頭辞の付いた変数はバンドル内の公開定数となり、接頭辞なしの変数はクライアントコードからは見えません。

例

設定構造

基本設定

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

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: { '@': new URL('./src', import.meta.url).pathname },
  },
})

条件付き設定

// 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())   // VITE_ 接頭辞のみ(安全)

  return {
    plugins: [react()],
    server: command === 'serve' ? { port: 3000 } : undefined,
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

主要な設定オプション

キーデフォルト値説明
root'.'プロジェクトルート(index.html がある場所)
base'/'デプロイされたアセットの公開ベースパス
envPrefix'VITE_'クライアント公開環境変数の接頭辞
build.outDir'dist'出力ディレクトリ
build.minify'oxc'ミニファイア('oxc'、'terser'、または false)
build.sourcemapfalsetrue、'inline'、または 'hidden'

プラグイン

必須プラグイン

ほとんどのプラグインニーズは、十分にメンテナンスされた少数のパッケージでカバーされます。独自のプラグインを作成する前に、これらを使用してください。

プラグイン目的使用するタイミング
@vitejs/plugin-react-swcSWCによるReact HMR + Fast RefreshReactアプリのデフォルト(Babel版より高速)
@vitejs/plugin-reactBabelによるReact HMR + Fast RefreshBabelプラグイン(emotion、MobXデコレータ)が必要な場合のみ
@vitejs/plugin-vueVue 3 SFCサポートVueアプリ
vite-plugin-checkerワーカースレッドで tsc + ESLintを実行し、HMRオーバーレイを表示任意のTypeScriptアプリ — Viteは vite build 中に型チェックを行いません
vite-tsconfig-pathstsconfig.json の paths エイリアスを有効にするtsconfig.json にエイリアスが既に存在する場合
vite-plugin-dtsライブラリモードで .d.ts ファイルを出力TypeScriptライブラリの公開
vite-plugin-svgrSVGをReactコンポーネントとしてインポートSVGをコンポーネントとして使用するReactアプリ
rollup-plugin-visualizerバンドルのツリーマップ/サンバーストレポート定期的なバンドルサイズ監査(enforce: 'post' を使用)
vite-plugin-pwa設定不要のPWA + Workboxオフライン対応アプリ

重要な注意点: vite build はトランスパイルを行いますが、型チェックは行いません。vite-plugin-checker を追加するか、CIで tsc --noEmit を実行しない限り、型エラーは本番環境にそのまま出荷されます。

カスタムプラグインの作成

カスタムプラグインの作成は稀です。ほとんどのニーズは既存のプラグインでカバーされます。必要な場合は、まず vite.config.ts にインラインで記述し、再利用する場合にのみ抽出してください。

// vite.config.ts — 最小限のインラインプラグイン
function myPlugin(): Plugin {
  return {
    name: 'my-plugin',                       // 必須、一意である必要がある
    enforce: 'pre',                           // 'pre' | 'post'(オプション)
    apply: 'build',                           // 'build' | 'serve'(オプション)
    transform(code, id) {
      if (!id.endsWith('.custom')) return
      return { code: transformCustom(code), map: null }
    },
  }
}

主要なフック: transform(ソースを変更)、resolveId + load(仮想モジュール)、transformIndexHtml(HTMLに挿入)、configureServer(開発用ミドルウェアを追加)、hotUpdate(カスタムHMR — v7+で非推奨となった handleHotUpdate を置き換え)。

仮想モジュールは \0 接頭辞の規則を使用します。resolveId は '\0virtual:my-id' を返し、他のプラグインがスキップするようにします。ユーザーコードは 'virtual:my-id' をインポートします。

完全なプラグインAPIについては、vite.dev/guide/api-plugin を参照してください。開発中は vite-plugin-inspect を使用して変換パイプラインをデバッグします。

HMR API

フレームワークプラグイン(@vitejs/plugin-react、@vitejs/plugin-vue など)はHMRを自動的に処理します。import.meta.hot を直接使用する必要があるのは、カスタム状態ストア、開発ツール、フレームワークに依存しないユーティリティを構築し、更新間で状態を保持する必要がある場合のみです。

// src/store.ts — バニラモジュールの手動HMR
if (import.meta.hot) {
  // 更新間で状態を保持(.data を再代入せず、必ずミューテーションすること)
  import.meta.hot.data.count = import.meta.hot.data.count ?? 0

  // モジュールが置き換えられる前に副作用をクリーンアップ
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

  // このモジュール自身の更新を受け入れる
  import.meta.hot.accept()
}

すべての import.meta.hot コードは本番ビルドからツリーシェイクで削除されるため、ガードを削除する必要はありません。

環境変数

Viteは .env、.env.local、.env.[mode]、.env.[mode].local をこの順序で読み込みます(後で読み込まれたものが優先されます)。*.local ファイルはgitignoreされており、ローカルの機密情報向けです。

クライアントサイドからのアクセス

VITE_ 接頭辞が付いた変数のみがクライアントコードに公開されます:

import.meta.env.VITE_API_URL   // 文字列
import.meta.env.MODE            // 'development' | 'production' | カスタム
import.meta.env.BASE_URL        // base 設定値
import.meta.env.DEV             // 真偽値
import.meta.env.PROD            // 真偽値
import.meta.env.SSR             // 真偽値

設定内での環境変数の使用

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())          // VITE_ 接頭辞のみ(安全)
  return {
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

セキュリティ

VITE_ 接頭辞はセキュリティ境界ではない

VITE_ 接頭辞が付いた変数は、ビルド時にクライアントバンドルに静的にインライン化されます。ミニファイ、Base64エンコード、ソースマップの無効化でも隠すことはできません。決心した攻撃者は、出荷されたJavaScriptから任意の VITE_ 変数を抽出できます。

ルール: 公開値のみ(API URL、機能フラグ、公開鍵)を VITE_ 変数に格納します。機密情報(APIトークン、データベースURL、秘密鍵)は、APIまたはサーバーレス関数の背後にあるサーバーサイドに必ず配置します。

loadEnv('') の落とし穴

// 悪い例:第3引数に '' を渡すと、サーバーシークレットを含むすべての環境変数が読み込まれ、
// `define` を介してクライアントコードにインライン化できるようになります。
const env = loadEnv(mode, process.cwd(), '')

// 良い例:明示的な接頭辞リスト
const env = loadEnv(mode, process.cwd(), ['VITE_', 'APP_'])

本番環境のソースマップ

本番環境のソースマップは、元のソースコードを漏洩させます。エラートラッカー(Sentry、Bugsnag)にアップロードし、その後ローカルで削除する場合を除き、無効にしてください:

build: {
  sourcemap: false,                                  // デフォルト — この設定を維持
}

.gitignore チェックリスト

  • .env.local、.env.*.local — ローカルの機密情報の上書き
  • dist/ — ビルド出力
  • node_modules/.vite — プリバンドルキャッシュ(古いエントリは誤ったエラーの原因になります)

サーバープロキシ

// vite.config.ts — server.proxy
server: {
  proxy: {
    '/foo': 'http://localhost:4567',                    // 文字列の短縮形

    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,                               // 仮想ホストバックエンドに必要
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

WebSocketプロキシの場合は、ルート設定に ws: true を追加します。

ビルド最適化

手動チャンク分割

// vite.config.ts — build.rolldownOptions
build: {
  rolldownOptions: {
    output: {
      // オブジェクト形式:特定のパッケージをグループ化
      manualChunks: {
        'react-vendor': ['react', 'react-dom'],
        'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-popover'],
      },
    },
  },
}
// 関数形式:ヒューリスティックで分割
manualChunks(id) {
  if (id.includes('node_modules/react')) return 'react-vendor'
  if (id.includes('node_modules')) return 'vendor'
}

パフォーマンス

バレルファイルを避ける

バレルファイル(index.ts がディレクトリ内のすべてを再エクスポートする)は、単一のシンボルをインポートする場合でも、Viteにすべての再エクスポートファイルを読み込ませます。これは公式ドキュメントが指摘する開発サーバー速度低下の第1の原因です。

// 悪い例 — 1つのユーティリティをインポートするためにバレル全体が読み込まれる
import { slash } from '@/utils'

// 良い例 — 直接インポート、該当ファイルのみが読み込まれる
import { slash } from '@/utils/slash'

インポート拡張子を明示的に指定する

暗黙的な拡張子ごとに、resolve.extensions による最大6回のファイルシステムチェックが発生します。大規模なコードベースでは、これが積み重なります。

// 悪い例
import Component from './Component'

// 良い例
import Component from './Component.tsx'

tsconfig.json の allowImportingTsExtensions と resolve.extensions は、実際に使用する拡張子のみに絞り込みます。

ホットパスルートのウォームアップ

server.warmup.clientFiles は、ブラウザがリクエストする前に既知のホットエントリを事前変換します。大規模アプリでのコールドロードのリクエストウォーターフォールを排除します。

// vite.config.ts
server: {
  warmup: {
    clientFiles: ['./src/main.tsx', './src/routes/**/*.tsx'],
  },
}

遅い開発サーバーのプロファイリング

vite dev が遅いと感じた場合、まず vite --profile を実行し、アプリを操作した後、p+enter を押して .cpuprofile を保存します。Speedscope に読み込んで、どのプラグインが時間を消費しているかを特定します。通常、コミュニティプラグインの buildStart、config、または configResolved フックです。

ライブラリモード

npmパッケージを公開する場合は、build.lib を使用します。設定の詳細よりも、2つの落とし穴の方が重要です:

  1. 型は出力されません — vite-plugin-dts を追加するか、tsc --emitDeclarationOnly を別途実行します。
  2. ピア依存関係は必ず外部化する必要があります — リストされていないピアはライブラリにバンドルされ、利用者側で重複ランタイムエラーが発生します。
// vite.config.ts
build: {
  lib: {
    entry: 'src/index.ts',
    formats: ['es', 'cjs'],
    fileName: (format) => `my-lib.${format}.js`,
  },
  rolldownOptions: {
    external: ['react', 'react-dom', 'react/jsx-runtime'],  // すべてのピア依存関係
  },
}

SSRの外部化

生の createServer({ middlewareMode: true }) のセットアップはフレームワーク作成者の領域です。ほとんどのアプリは、代わりにNuxt、Remix、SvelteKit、Astro、またはTanStack Startを使用する必要があります。フレームワークユーザーとして調整する可能性があるのは、依存関係がSSRで壊れる場合の外部化設定です:

// vite.config.ts — ssr オプション
ssr: {
  external: ['node-native-package'],           // SSRバンドルで require() のままにする
  noExternal: ['esm-only-package'],            // SSR出力に強制的にバンドル(ほとんどのSSRエラーを修正)
  target: 'node',                              // 'node' または 'webworker'
}

依存関係のプリバンドル

Viteは依存関係をプリバンドルして、CJS/UMDをESMに変換し、リクエスト数を削減します。

// vite.config.ts — optimizeDeps
optimizeDeps: {
  include: [
    'lodash-es',                              // 既知の重い依存関係を強制的にプリバンドル
    'cjs-package',                            // 相互運用の問題を引き起こすCJS依存関係
    'deep-lib/components/**',                 // 深いインポート用のグロブパターン
  ],
  exclude: ['local-esm-package'],             // 除外する場合は有効なESMである必要がある
  force: true,                                // キャッシュを無視して再最適化(一時的なデバッグ用)
}

よくある落とし穴

開発環境とビルド環境の不一致

開発環境では変換にesbuild/Rolldownを使用し、ビルド環境ではバンドルにRolldownを使用します。CJSライブラリは両者で動作が異なる場合があります。デプロイ前に必ず vite build && vite preview で確認してください。

デプロイ後の古いチャンク

新しいビルドは新しいチャンクハッシュを生成します。アクティブなセッションを持つユーザーは、もはや存在しない古いファイル名をリクエストします。Viteには組み込みの解決策はありません。軽減策:

  • デプロイウィンドウの間、古い dist/assets/ ファイルを保持する
  • ルーターで動的インポートエラーをキャッチし、ページのリロードを強制する

Dockerとコンテナ

Viteはデフォルトで localhost にバインドします。これはコンテナの外部から到達できません:

// vite.config.ts — Docker/コンテナ設定
server: {
  host: true,                                  // 0.0.0.0 にバインド
  hmr: { clientPort: 3000 },                   // リバースプロキシの背後にある場合
}

モノレポのファイルアクセス

Viteはファイルの提供をプロジェクトルートに制限します。ルート外のパッケージはブロックされます:

// vite.config.ts — モノレポのファイルアクセス
server: {
  fs: {
    allow: ['..'],                             // 親ディレクトリ(ワークスペースルート)を許可
  },
}

アンチパターン

// 悪い例:envPrefix を '' に設定すると、すべての環境変数(シークレットを含む)がクライアントに公開される
envPrefix: ''

// 悪い例:require() が Vite で動作すると想定している

トラブルシューティングの流れ

flowchart TD
    A[問題の特定] --> B{エラーの種類は?}
    B -->|ビルドエラー| C[vite build の出力を確認]
    B -->|開発サーバーエラー| D[ターミナルログを確認]
    B -->|HMRが動作しない| E[プラグイン設定を確認]
    C --> F{エラーが発生?}
    F -->|Yes| G[依存関係と設定を確認]
    F -->|No| H[本番環境でテスト]
    D --> I{エラーが発生?}
    I -->|Yes| J[プラグインとプロキシ設定を確認]
    I -->|No| K[正常に動作]

参考リンク

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

関連スキル