affaan-m/ecc1 file

Vite Patterns

Vite build tool patterns including config, plugins, HMR, env variables, proxy setup, SSR, library mode, dependency pre-bundling, and build optimization. Activate when working with vite.config.ts, Vite plugins, or Vite-based projects.

Specification
Skill ID
affaan-m/ecc/vite-patterns
Publisher
affaan-m
Repository
ecc
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

affaan-m/ecc/vite-patternsInstalls these files
  • SKILL.md

What this skill tells the agent

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ベースのミニファイでアプリを本番用にバンドルします。
  • 依存関係の事前バンドルはesbuildを通じてCJS/UMD依存関係を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ワーカースレッドでHMRオーバーレイ付きの tsc + ESLintを実行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   // string
import.meta.env.MODE            // 'development' | 'production' | カスタム
import.meta.env.BASE_URL        // base設定値
import.meta.env.DEV             // boolean
import.meta.env.PROD            // boolean
import.meta.env.SSR             // boolean
設定での環境変数使用
// 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('') の落とし穴
// BAD: 第3引数として '' を渡すと、サーバーのシークレットを含む全ての環境変数が読み込まれ、
// `define` でクライアントコードにインライン化できてしまう。
const env = loadEnv(mode, process.cwd(), '')

// GOOD: 明示的なプレフィックスリスト
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)は、1つのシンボルをインポートする場合でも再エクスポートされたファイルをすべて読み込むことを強制します。これは公式ドキュメントで指摘されているデベロップメントサーバーの速度低下の主な原因です。

// BAD — 1つのユーティリティのインポートがViteにバレル全体を読み込ませる
import { slash } from '@/utils'

// GOOD — 直接インポート、そのファイルだけが読み込まれる
import { slash } from '@/utils/slash'
インポート拡張子を明示的にする

暗黙の拡張子はそれぞれ resolve.extensions を通じて最大6回のファイルシステムチェックを強制します。大規模なコードベースでは積み重なります。

// BAD
import Component from './Component'

// GOOD
import Component from './Component.tsx'

Use this skill in a project

Open any RiverX project, search the Skills panel for affaan-m/ecc/vite-patterns, and install it in one click.

Use this skill