Vite plus

Vite+ 完全ガイド:統一されたJavaScript/TypeScriptツールチェーンの全貌


目次

  1. はじめに
  2. なぜVite+が必要か
  3. アーキテクチャ
  4. 統合ツールチェーン
  5. インストールとセットアップ
  6. 設定ファイル
  7. 開発サーバー(vp dev)
  8. コード品質(vp check)
  9. リンティング(vp lint)
  10. フォーマッティング(vp fmt)
  11. テスト(vp test)
  12. ビルド(vp build)
  13. タスク実行(vp run)
  14. パッケージング(vp pack)
  15. CI/CD統合
  16. コミットフック
  17. IDE統合
  18. 対応プラットフォーム
  19. まとめ

1. はじめに

1.1 Vite+とは何か

Vite+(ヴィートプラス)は、JavaScript/TypeScript開発における統一ツールチェーンである。従来、Web開発プロジェクトではバンドラー、テストフレームワーク、リンター、フォーマッター、タスクランナーといった複数のツールを個別に設定・管理する必要があった。Vite+はこれらすべてを単一のエントリーポイントに統合し、一つの設定ファイル(vite.config.ts)で全ツールを管理可能にするプロジェクトである。

Vite+のコア思想は「統一(Unified)」である。開発者がプロジェクトを始める際に、バンドラーにはVite、テストにはVitest、リンターにはESLint、フォーマッターにはPrettierといった具合に個別のツールを選定し、それぞれの設定ファイルを書き、依存関係を管理するという煩雑なプロセスを排除する。代わりに、vp(Vite Plus)という単一のCLIコマンドから、開発に必要なすべての操作を実行できるようにする。

1.2 Viteとの関係

Vite+は、Viteの上位に位置するツールチェーンである。Vite自体はビルドツール兼開発サーバーとして広く普及しているが、Vite+はViteをその構成要素の一つとして内包し、さらにテスト、リンティング、フォーマッティング、タスク実行といった領域まで統合している。

両者の関係を明確にするために、以下の対比表を示す。

項目Vite(単体)Vite+
開発サーバーありあり(Vite経由)
プロダクションビルドRollupRolldown
テスト別途Vitestを導入統合済み(Vitest)
リンティング別途ESLint等を導入統合済み(Oxlint)
フォーマット別途Prettier等を導入統合済み(Oxfmt)
型チェック別途tsc等を導入統合済み(vp check)
タスクランナーなし統合済み(Vite Task)
パッケージビルドなし統合済み(tsdown)
設定ファイルvite.config.tsvite.config.ts(拡張)
CLIvitevp

重要な点として、Vite+はViteを置き換えるものではなく、Viteを基盤として拡張するものである。Viteの設定はそのままvite.config.tsの中で有効であり、Vite+はその設定ファイルにtestlintfmtrunpackstagedといった追加の設定セクションを加える形で拡張している。

1.3 Vite+が解決する根本的な課題

現代のJavaScript/TypeScript開発において、プロジェクトのセットアップは年々複雑化している。一般的なプロジェクトでは、以下のようなツールスタックが必要とされる。

  • バンドラー: webpack / Vite / Rollup / esbuild
  • テストフレームワーク: Jest / Vitest / Mocha
  • リンター: ESLint + 各種プラグイン
  • フォーマッター: Prettier
  • 型チェック: TypeScript Compiler (tsc)
  • タスクランナー: npm scripts / Turborepo / nx
  • パッケージビルド: tsup / unbuild / rollup

これらのツールはそれぞれ独立した設定ファイル(.eslintrc.prettierrcjest.config.jstsconfig.json等)を持ち、それぞれのバージョンを管理し、互いの互換性を確認する必要がある。Vite+はこの「ツール地獄」を根本から解消するために設計されている。

1.4 本記事の構成

本記事では、Vite+の全体像を網羅的に解説する。アーキテクチャの設計思想から始まり、各統合ツールの詳細、具体的な設定例、CI/CDへの統合、既存ツールからの移行方法まで、実務で必要となるすべての知識を体系的にまとめている。


2. なぜVite+が必要か

2.1 JavaScript開発エコシステムの断片化

JavaScript/TypeScriptのエコシステムは、その柔軟性と豊富な選択肢が強みである一方、深刻な断片化問題を抱えている。2020年代のWebプロジェクトにおいて、開発者は平均して5〜8個の独立したツールを設定・管理しなければならない。

この断片化は以下の問題を引き起こす。

2.1.1 設定ファイルの増殖

一般的なTypeScriptプロジェクトのルートディレクトリを見ると、以下のような設定ファイルが散在している。

my-project/
├── .eslintrc.js           # ESLint設定
├── .eslintignore           # ESLint除外パターン
├── .prettierrc             # Prettier設定
├── .prettierignore         # Prettier除外パターン
├── jest.config.ts          # Jestテスト設定
├── tsconfig.json           # TypeScript設定
├── tsconfig.build.json     # TypeScriptビルド用設定
├── vite.config.ts          # Vite設定
├── vitest.config.ts        # Vitest設定
├── turbo.json              # Turborepo設定
├── .lintstagedrc.js        # lint-staged設定
├── .husky/                 # Huskyフック設定
│   ├── pre-commit
│   └── commit-msg
└── package.json            # 依存関係・スクリプト定義

Vite+では、これらの設定のほとんどが単一のvite.config.tsに集約される。

my-project/
├── vite.config.ts          # すべてのツール設定を統一
├── tsconfig.json           # TypeScript設定(Vite+とは独立)
└── package.json            # 依存関係(大幅に簡素化)

2.1.2 依存関係のドリフト

プロジェクトが成長するにつれ、各ツールの依存関係は複雑に絡み合い、バージョン間の不整合(ドリフト)が発生する。典型的な例として、ESLintのメジャーバージョンアップに伴い、そのプラグインやパーサー(@typescript-eslint/parser@typescript-eslint/eslint-plugin等)もすべて対応バージョンに更新しなければならない。さらに、PrettierとESLintの競合を防ぐためにeslint-config-prettierのバージョンも合わせる必要がある。

このドリフトは、以下のような連鎖的な問題を引き起こす。

  1. ビルドの破損: ツールAのアップデートがツールBとの互換性を壊す
  2. セキュリティ脆弱性の放置: 依存関係の更新が複雑すぎて後回しにされる
  3. 開発者体験の劣化: 新しいチームメンバーが環境構築で躓く
  4. CI/CDの不安定化: ローカルとCI環境で異なるバージョンが使われる

Vite+は統合ツールチェーンとしてこれらのツールを内部的に管理するため、依存関係のドリフト問題は原理的に発生しない。

2.2 パフォーマンスの問題

従来のJavaScriptベースのツールチェーンには、本質的なパフォーマンスの限界がある。

2.2.1 JavaScriptベースツールの限界

ESLintやPrettierはJavaScriptで実装されており、シングルスレッドで動作する。大規模プロジェクトでは、リンティングに数分、フォーマッティングに数十秒を要することが珍しくない。これはCI/CDパイプラインのボトルネックとなり、開発者のフィードバックループを遅延させる。

2.2.2 Rustベースツールによる高速化

Vite+が統合するOxlint(リンター)とOxfmt(フォーマッター)は、Rustで実装されている。Rustはゼロコスト抽象化とメモリ安全性を両立する言語であり、以下の利点をもたらす。

  • ネイティブ速度: JIT(Just-In-Time)コンパイルのオーバーヘッドがない
  • マルチスレッド処理: OSスレッドを活用した真の並列処理
  • 低メモリ消費: ガベージコレクションが不要
  • 予測可能なパフォーマンス: GCの一時停止やJITの暖機が不要

Vite+はこれらのRustベースツールを統合することで、従来のアプローチと比較して10倍から100倍の高速化を実現している。特にvp checkコマンドはフォーマット、リンティング、型チェックを並列実行し、従来のアプローチの2倍の速度で静的チェックを完了する。

2.3 コード品質の一貫性

チーム開発において、コード品質の一貫性は生産性に直結する。しかし、ツールが分散していると以下の問題が生じやすい。

  • ツール設定の乖離: チームメンバー間で異なるESLint/Prettier設定が使われる
  • チェックの漏れ: CIで実行するチェックとローカルで実行するチェックが異なる
  • ルールの不整合: ESLintとTypeScriptの型チェックが矛盾する指摘を出す

Vite+はvp checkコマンドにより、フォーマット(Oxfmt)、リンティング(Oxlint)、型チェック(TypeScript)を単一コマンドで一括実行する。これにより、ローカルとCIで完全に同一のチェックが実行されることが保証される。

2.4 開発者体験(DX)の向上

Vite+の設計目標の一つは、開発者体験(Developer Experience)の大幅な向上である。

従来のワークフロー:

# プロジェクト作成
npm create vite@latest my-app -- --template react-ts
cd my-app

# 追加ツールのインストール
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install -D prettier eslint-config-prettier
npm install -D vitest @testing-library/react
npm install -D husky lint-staged

# 各種設定ファイルの作成
# .eslintrc.js, .prettierrc, vitest.config.ts, .husky/pre-commit ...

Vite+のワークフロー:

# これだけで完了
vp create my-app --template vite:application
cd my-app
# すべてのツールが統合済み、設定はvite.config.tsに統一

この簡潔さは、特に以下のシナリオで大きな価値を発揮する。

  • 新規プロジェクトの立ち上げ: 数分でフル装備のプロジェクトが作成できる
  • チーム間の標準化: 全プロジェクトで同一のツールチェーンが使われる
  • オンボーディング: 新しい開発者がプロジェクト構造を即座に理解できる
  • メンテナンス: ツールの更新がVite+のバージョンアップのみで完了する

3. アーキテクチャ

3.1 二重構造の設計

Vite+のアーキテクチャは、二つの主要コンポーネントから構成される。

  1. vp(グローバルCLI): システム全体にインストールされるコマンドラインインターフェース
  2. vite-plus(ローカルパッケージ): プロジェクトごとにインストールされるツールチェーンパッケージ

この二重構造には明確な設計意図がある。

3.1.1 vpグローバルCLI

vpはグローバルにインストールされる軽量なCLIツールである。その役割は以下の通りである。

  • プロジェクト作成: vp createコマンドで新規プロジェクトをスキャフォールドする
  • コマンドのディスパッチ: vp devvp build等のコマンドを受け取り、ローカルにインストールされたvite-plusパッケージに処理を委譲する
  • バージョン管理: プロジェクトが要求するvite-plusのバージョンを自動的に検出し、適切なバージョンで実行する

vp CLIは非常に薄いラッパーとして設計されており、実際のツール実行ロジックはすべてvite-plusパッケージに含まれている。これにより、異なるプロジェクトで異なるバージョンのvite-plusを使用しても、グローバルのvpコマンドは単一のバージョンで対応できる。

# グローバルインストール
npm install -g @aspect-build/vp

# または特定のパッケージマネージャーで
pnpm add -g @aspect-build/vp
yarn global add @aspect-build/vp

3.1.2 vite-plusローカルパッケージ

vite-plusはプロジェクトのローカル依存関係としてインストールされるパッケージである。このパッケージには以下が含まれる。

  • 統合ツールチェーンのランタイム: Vite、Vitest、Oxlint、Oxfmt、Rolldown、tsdown、Vite Taskのすべて
  • 設定解析エンジン: vite.config.tsから各ツールの設定を解析し、適切なツールに渡す
  • プラグインシステム: Viteプラグインエコシステムとの互換性を維持するプラグインランタイム
# プロジェクトローカルにインストール
npm install -D vite-plus

# package.jsonに追加される
{
  "devDependencies": {
    "vite-plus": "^1.0.0"
  }
}

3.1.3 二重構造のメリット

この設計には以下のメリットがある。

  1. バージョンの独立性: プロジェクトAはvite-plus@1.0、プロジェクトBはvite-plus@2.0を使用できる
  2. 再現可能性: package.jsonpackage-lock.jsonにより、チーム全員が同一バージョンを使用することが保証される
  3. 段階的な移行: 既存プロジェクトに段階的にVite+を導入できる
  4. CI/CDの簡素化: グローバルインストールなしにnpx vpで実行可能

3.2 Rustベースツールとnapi-rs

Vite+の高速性の源泉は、コアツールがRustで実装されている点にある。しかし、JavaScriptエコシステムとの統合には工夫が必要であり、ここでnapi-rsが重要な役割を果たす。

3.2.1 napi-rsとは

napi-rs(Node-API Rust)は、RustからNode.jsのNative APIにアクセスするためのフレームワークである。これにより、Rustで記述された高速な処理をNode.jsモジュールとしてシームレスに呼び出すことができる。

┌─────────────────────────────────────────────────┐
│                  JavaScript層                     │
│                                                   │
│  vite.config.ts → 設定パーサー → ツール実行エンジン  │
│                                                   │
├─────────────────────────────────────────────────┤
│                  napi-rs ブリッジ                   │
│                                                   │
│  JavaScript ←──── N-API ────→ Rust                │
│                                                   │
├─────────────────────────────────────────────────┤
│                   Rust層                           │
│                                                   │
│  Oxlint │ Oxfmt │ Rolldown │ tsdown              │
│                                                   │
│  ● マルチスレッド並列処理                           │
│  ● ゼロコスト抽象化                                │
│  ● ネイティブ速度                                  │
└─────────────────────────────────────────────────┘

3.2.2 JavaScriptの拡張性

Rustで高速化を図りつつも、Vite+はJavaScriptエコシステムの拡張性を犠牲にしていない。napi-rsを通じて、以下のようなJavaScriptベースの拡張が可能である。

  • Viteプラグイン: 既存のViteプラグインがそのまま使用可能
  • カスタムルール: OxlintのルールをJavaScriptで拡張可能
  • テストプラグイン: Vitestのカスタムレポーターやプラグインが使用可能

この「Rustのパフォーマンス + JavaScriptの拡張性」というアプローチは、Vite+の重要な設計原則であり、開発者が既存のエコシステム資産を活用しながら大幅なパフォーマンス向上を享受できる構造になっている。

3.3 コマンドフロー

vpコマンドの実行フローは以下の通りである。

ユーザー入力: vp dev
    │
    ▼
┌──────────────────────┐
│  vp(グローバルCLI)    │
│                        │
│  1. コマンド解析         │
│  2. プロジェクトルート検出│
│  3. vite-plus検出       │
└──────────┬─────────────┘
           │
           ▼
┌──────────────────────────────┐
│  vite-plus(ローカルパッケージ) │
│                                │
│  1. vite.config.ts 読み込み     │
│  2. 設定のマージ・バリデーション │
│  3. 対応ツールの起動             │
│     → vp dev → Vite dev server │
│     → vp build → Rolldown      │
│     → vp test → Vitest          │
│     → vp lint → Oxlint          │
│     → vp fmt → Oxfmt            │
│     → vp check → Oxfmt+Oxlint+tsc│
│     → vp run → Vite Task        │
│     → vp pack → tsdown          │
└──────────────────────────────┘

3.4 設定の統一アーキテクチャ

Vite+の設定統一アーキテクチャは、単一のvite.config.tsから各ツールの設定を分配する仕組みである。

// vite.config.ts
import { defineConfig } from 'vite-plus';

export default defineConfig({
  // ── Vite標準設定 ──
  server: { /* ... */ },     // → Vite Dev Server
  build: { /* ... */ },      // → Rolldown
  preview: { /* ... */ },    // → Vite Preview Server

  // ── Vite+拡張設定 ──
  test: { /* ... */ },       // → Vitest
  lint: { /* ... */ },       // → Oxlint
  fmt: { /* ... */ },        // → Oxfmt
  run: { /* ... */ },        // → Vite Task
  pack: { /* ... */ },       // → tsdown
  staged: { /* ... */ },     // → pre-commitフック
});

この統一設定により、以下の利点が得られる。

  1. 単一の型定義: defineConfig関数がすべての設定項目の型を提供し、IDEの補完が完全に動作する
  2. 設定の共有: 共通の設定(パス、除外パターンなど)を一箇所で定義し、各ツールで共有できる
  3. バリデーション: 設定の整合性がVite+レベルで検証される
  4. ドキュメント: 単一の設定ファイルがプロジェクトのツール設定のドキュメントとしても機能する

4. 統合ツールチェーン

Vite+は7つの主要ツールを統合している。それぞれの役割と特徴を詳述する。

4.1 Vite(開発サーバー/バンドラー)

役割: 開発サーバーの提供、ES Modulesベースの高速ホットモジュールリプレイスメント(HMR)

Viteは、Evan You氏(Vue.jsの作者)によって開発されたフロントエンドビルドツールである。開発時にはネイティブESMを活用してバンドルなしで高速にモジュールを提供し、プロダクションビルドではバンドルを行う。

Vite+においては、Viteは主に開発サーバー(vp dev)とプレビューサーバー(vp preview)を担当する。Vite 8がベースとなっており、最新のWeb標準とフレームワークをサポートしている。

主要機能:

  • ネイティブESMによる即座の開発サーバー起動
  • HMR(Hot Module Replacement)による即座のコード反映
  • CSS/SCSSの組み込みサポート
  • TypeScriptのネイティブサポート
  • React/Vue/Svelte等のフレームワークプラグイン

4.2 Vitest(テストフレームワーク)

役割: ユニットテスト、統合テスト、コンポーネントテスト

VitestはViteのエコシステムに最適化されたテストフレームワークであり、Jest互換のAPIを提供する。Vite+においては、vp testコマンドでVitestが実行される。

重要な違い: スタンドアロンのVitestはデフォルトでwatchモードで起動するが、Vite+経由(vp test)ではwatchモードがデフォルトで無効になっている。これはCI/CD環境での利用を考慮した設計である。watchモードが必要な場合は明示的に--watchフラグを指定する。

# デフォルト: watchモードなし(テスト実行後に終了)
vp test

# watchモードを有効にする場合
vp test --watch

主要機能:

  • Viteと同一の設定・プラグインを共有
  • Jest互換のAPIとマッチャー
  • コードカバレッジ(c8 / istanbul)
  • スナップショットテスト
  • 並列テスト実行
  • ブラウザモードテスト

4.3 Oxlint(リンター)

役割: コードの静的解析、バグの早期検出、コーディング規約の強制

OxlintはRustで実装された超高速リンターであり、ESLintの代替を目指すツールである。Vite+ではvp lintコマンドで実行される。

ESLintと比較して50〜100倍の速度で動作し、数千のファイルを持つ大規模プロジェクトでも数秒でリンティングを完了する。

主要機能:

  • ESLint互換のルールセット
  • TypeScript型対応リンティング(typeAware)
  • TypeScript型チェック統合(typeCheck)
  • 自動修正(--fix
  • プラグインシステム

4.4 Oxfmt(フォーマッター)

役割: コードスタイルの統一、自動フォーマット

OxfmtはRustで実装された高速コードフォーマッターであり、Prettierの代替として機能する。Vite+ではvp fmtコマンドで実行される。

Prettierと比較して大幅に高速であり、一貫したコードスタイルをチーム全体に強制することができる。

主要機能:

  • Prettier互換のフォーマットルール
  • TypeScript/JSX/TSXのサポート
  • CSS/SCSS/LESSのフォーマット
  • Markdownのフォーマット
  • 差分のみのフォーマット(--changed

4.5 Rolldown(プロダクションバンドラー)

役割: プロダクション向けの最適化されたバンドル生成

RolldownはRollupのRust実装であり、Vite 8のプロダクションビルドバックエンドとして使用される。Vite+ではvp buildコマンドの実行時にRolldownが呼び出される。

主要機能:

  • Rollup互換のプラグインAPI
  • ツリーシェイキング(未使用コードの除去)
  • コード分割
  • ソースマップ生成
  • ES Module / CommonJS出力
  • ネイティブ速度のバンドル処理

4.6 tsdown(TypeScriptバンドラー)

役割: ライブラリパッケージのビルド、TypeScript型定義の生成

tsdownはTypeScriptライブラリのパッケージングに特化したバンドラーであり、tsupの後継に位置づけられる。Vite+ではvp packコマンドで実行される。

主要機能:

  • ESM/CJS/UMDの出力形式
  • .d.ts型定義ファイルの自動生成
  • Treeshaking
  • コード分割
  • バンドルサイズの最適化

4.7 Vite Task(タスクランナー)

役割: カスタムタスクの定義と実行、タスクの依存関係管理

Vite TaskはVite+に統合されたタスクランナーであり、vp runコマンドで実行される。npm scriptsやTurborepo、nxなどの代替として機能する。

主要機能:

  • vite.config.ts内でのタスク定義
  • タスクのキャッシュ
  • タスクの依存関係管理
  • 並列タスク実行
  • ワークスペース対応

5. インストールとセットアップ

5.1 前提条件

Vite+を使用するためには、以下の環境が必要である。

  • Node.js: v24以上(最新のLTSバージョン推奨)
  • パッケージマネージャー: npm、pnpm、yarn、Bunのいずれか

Vite+はNode.js v24を最低バージョンとして要求する。これはES Modules、import.meta、トップレベルawaitなどの最新のJavaScript機能への依存があるためである。

5.2 グローバルCLIのインストール

# npm
npm install -g @aspect-build/vp

# pnpm
pnpm add -g @aspect-build/vp

# yarn
yarn global add @aspect-build/vp

# Bun
bun add -g @aspect-build/vp

インストール後、vpコマンドが利用可能になる。

# バージョン確認
vp --version
# 出力例: vp v1.0.0

# ヘルプ表示
vp --help

5.3 プロジェクトの作成(vp create)

vp createコマンドで新規プロジェクトを作成する。

# 対話的にプロジェクトを作成
vp create my-app

# テンプレートを指定して作成
vp create my-app --template vite:application

# パッケージマネージャーを指定
vp create my-app --template vite:application --pm pnpm

5.3.1 利用可能なテンプレート

Vite+には以下の4つの組み込みテンプレートが用意されている。

テンプレート用途主な特徴
vite:applicationWebアプリケーションフルスタックのWebアプリケーション開発
vite:libraryライブラリnpmパッケージとして配布するライブラリ
vite:monorepoモノレポ複数パッケージを管理するモノレポ構成
vite:generatorジェネレーターカスタムテンプレートの生成器

5.3.2 テンプレートの詳細

vite:application テンプレート

最も一般的なテンプレートであり、Webアプリケーション開発に必要なすべてがセットアップ済みで作成される。

vp create my-web-app --template vite:application

作成されるプロジェクト構造:

my-web-app/
├── src/
│   ├── main.ts          # エントリーポイント
│   ├── App.tsx           # ルートコンポーネント
│   ├── components/       # コンポーネント
│   └── __tests__/        # テストファイル
├── public/               # 静的ファイル
├── index.html            # HTMLエントリーポイント
├── vite.config.ts        # 統一設定ファイル
├── tsconfig.json         # TypeScript設定
├── package.json          # 依存関係
└── README.md

vite:library テンプレート

npmパッケージとして配布するライブラリの開発に最適化されたテンプレートである。

vp create my-lib --template vite:library

作成されるプロジェクト構造:

my-lib/
├── src/
│   ├── index.ts          # ライブラリエントリーポイント
│   ├── utils.ts          # ユーティリティ関数
│   └── __tests__/        # テストファイル
├── vite.config.ts        # 統一設定ファイル
├── tsconfig.json         # TypeScript設定
├── package.json          # パッケージ定義
└── README.md

vite:monorepo テンプレート

複数のパッケージを一つのリポジトリで管理するモノレポ構成のテンプレートである。

vp create my-workspace --template vite:monorepo

作成されるプロジェクト構造:

my-workspace/
├── packages/
│   ├── app/              # アプリケーションパッケージ
│   │   ├── src/
│   │   ├── vite.config.ts
│   │   └── package.json
│   ├── ui/               # UIコンポーネントライブラリ
│   │   ├── src/
│   │   ├── vite.config.ts
│   │   └── package.json
│   └── shared/           # 共有ユーティリティ
│       ├── src/
│       ├── vite.config.ts
│       └── package.json
├── vite.config.ts        # ルート設定
├── package.json          # ワークスペース定義
└── pnpm-workspace.yaml   # pnpmワークスペース設定

vite:generator テンプレート

カスタムテンプレートを作成するためのジェネレーターテンプレートである。組織独自のプロジェクトテンプレートを作成し、チーム内で共有する際に使用する。

vp create my-generator --template vite:generator

5.4 既存プロジェクトへの導入

既存のViteプロジェクトにVite+を導入する場合の手順を示す。

5.4.1 パッケージのインストール

# vite-plusをdevDependencyに追加
npm install -D vite-plus

# 不要になった依存関係を削除(例)
npm uninstall eslint prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin \
  eslint-config-prettier eslint-plugin-react lint-staged husky

5.4.2 設定ファイルの移行

既存のvite.config.tsを拡張し、各ツールの設定を統合する。

移行前(複数の設定ファイル):

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

export default defineConfig({
  plugins: [react()],
  server: { port: 3000 },
});
// .eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  rules: {
    'no-unused-vars': 'warn',
  },
};
// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 80
}
// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
});

移行後(単一の設定ファイル):

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

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
  build: {
    outDir: 'dist',
  },
  test: {
    globals: true,
    environment: 'jsdom',
    include: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
  },
  lint: {
    ignorePatterns: ['dist/**', 'node_modules/**'],
    options: {
      typeAware: true,
      typeCheck: true,
    },
  },
  fmt: {},
  run: {},
  pack: {},
  staged: {},
});

5.4.3 package.jsonのスクリプト更新

{
  "scripts": {
    "dev": "vp dev",
    "build": "vp build",
    "preview": "vp preview",
    "test": "vp test",
    "lint": "vp lint",
    "fmt": "vp fmt",
    "check": "vp check"
  }
}

5.4.4 不要な設定ファイルの削除

移行後、以下のファイルは不要となるため削除できる。

# 削除対象のファイル例
rm -f .eslintrc.js .eslintrc.json .eslintrc.yml .eslintignore
rm -f .prettierrc .prettierrc.json .prettierrc.yml .prettierignore
rm -f vitest.config.ts vitest.config.js
rm -f .lintstagedrc.js .lintstagedrc.json
rm -rf .husky/

6. 設定ファイル

6.1 vite.config.tsの全体構造

Vite+の設定ファイルは、Viteのvite.config.tsを拡張したものである。defineConfig関数をvite-plusからインポートすることで、Vite+の追加設定項目に対するTypeScriptの型補完が有効になる。

import { defineConfig } from 'vite-plus';

export default defineConfig({
  // ========================================
  // Vite標準の設定セクション
  // ========================================

  // 開発サーバー設定(vp dev)
  server: {
    port: 3000,
    host: '0.0.0.0',
    open: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },

  // プロダクションビルド設定(vp build)
  build: {
    outDir: 'dist',
    sourcemap: true,
    minify: 'terser',
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
        },
      },
    },
  },

  // プレビューサーバー設定(vp preview)
  preview: {
    port: 4173,
    open: true,
  },

  // ========================================
  // Vite+拡張の設定セクション
  // ========================================

  // テスト設定(vp test)
  test: {
    include: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
    exclude: ['node_modules', 'dist'],
    globals: true,
    environment: 'jsdom',
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      thresholds: {
        branches: 80,
        functions: 80,
        lines: 80,
        statements: 80,
      },
    },
  },

  // リンティング設定(vp lint)
  lint: {
    ignorePatterns: ['dist/**', 'node_modules/**', '*.config.ts'],
    options: {
      typeAware: true,
      typeCheck: true,
    },
  },

  // フォーマッティング設定(vp fmt)
  fmt: {},

  // タスク実行設定(vp run)
  run: {},

  // パッケージング設定(vp pack)
  pack: {},

  // ステージング(pre-commit)設定
  staged: {},
});

6.2 各設定セクションの詳細

6.2.1 server設定

serverセクションはViteの開発サーバーの設定を制御する。これはVite標準の設定と完全に互換性がある。

server: {
  // ポート番号
  port: 3000,

  // ホスト(0.0.0.0でLAN内アクセスを許可)
  host: '0.0.0.0',

  // ブラウザの自動起動
  open: true,

  // HTTPS設定
  https: {
    key: fs.readFileSync('./certs/key.pem'),
    cert: fs.readFileSync('./certs/cert.pem'),
  },

  // プロキシ設定
  proxy: {
    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },

  // CORS設定
  cors: true,

  // HMR設定
  hmr: {
    overlay: true,
  },
}

6.2.2 build設定

buildセクションはプロダクションビルドの設定を制御する。Vite+ではVite 8 + Rolldownがビルドバックエンドとして使用される。

build: {
  // 出力ディレクトリ
  outDir: 'dist',

  // ソースマップ生成
  sourcemap: true,        // true | 'inline' | 'hidden' | false

  // ミニファイ設定
  minify: 'terser',       // 'terser' | 'esbuild' | false

  // ターゲットブラウザ
  target: 'es2022',

  // CSSコード分割
  cssCodeSplit: true,

  // ライブラリモード(ライブラリビルド用)
  lib: {
    entry: 'src/index.ts',
    name: 'MyLib',
    formats: ['es', 'cjs'],
    fileName: (format) => `my-lib.${format}.js`,
  },

  // Rolldownオプション
  rollupOptions: {
    external: ['react', 'react-dom'],
    output: {
      globals: {
        react: 'React',
        'react-dom': 'ReactDOM',
      },
      manualChunks: {
        vendor: ['react', 'react-dom'],
        utils: ['lodash-es', 'date-fns'],
      },
    },
  },
}

6.2.3 test設定

testセクションはVitestの設定を制御する。

test: {
  // テストファイルのインクルードパターン
  include: ['src/**/*.{test,spec}.{ts,tsx,js,jsx}'],

  // テストファイルの除外パターン
  exclude: ['node_modules', 'dist', 'e2e/**'],

  // グローバルAPI(describe, it, expect等をimportなしで使用)
  globals: true,

  // テスト環境
  environment: 'jsdom',    // 'jsdom' | 'happy-dom' | 'node'

  // セットアップファイル
  setupFiles: ['./src/test/setup.ts'],

  // タイムアウト(ミリ秒)
  testTimeout: 10000,

  // カバレッジ設定
  coverage: {
    provider: 'v8',        // 'v8' | 'istanbul'
    reporter: ['text', 'json', 'html', 'lcov'],
    include: ['src/**/*.{ts,tsx}'],
    exclude: [
      'src/**/*.test.{ts,tsx}',
      'src/**/*.d.ts',
      'src/test/**',
    ],
    thresholds: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },

  // モック設定
  mockReset: true,
  clearMocks: true,
  restoreMocks: true,
}

6.2.4 lint設定

lintセクションはOxlintの設定を制御する。

lint: {
  // 無視パターン
  ignorePatterns: [
    'dist/**',
    'node_modules/**',
    '*.config.ts',
    'coverage/**',
  ],

  // Oxlintオプション
  options: {
    // TypeScript型情報を使用したリンティング
    typeAware: true,

    // TypeScript型チェックの統合
    typeCheck: true,
  },

  // 追加ルール設定(将来的な拡張)
  rules: {
    // ルールのオーバーライド
  },
}

6.2.5 fmt設定

fmtセクションはOxfmtの設定を制御する。

fmt: {
  // フォーマット対象ファイルの指定は通常デフォルトで十分
  // 必要に応じてカスタマイズ可能
}

6.2.6 run設定

runセクションはVite Taskの設定を制御する。

run: {
  // タスク定義(将来的な拡張)
}

6.2.7 pack設定

packセクションはtsdownの設定を制御する。

pack: {
  // パッケージビルドの設定(将来的な拡張)
}

6.2.8 staged設定

stagedセクションはpre-commitフックで実行される処理を制御する。

staged: {
  // ステージングされたファイルに対する処理定義
}

6.3 環境変数との連携

Vite+はViteの環境変数システムを引き継いでおり、.envファイルによる環境変数管理が可能である。

# .env
VITE_API_URL=http://localhost:8080

# .env.development
VITE_API_URL=http://dev-api.example.com

# .env.production
VITE_API_URL=https://api.example.com

設定ファイル内で環境変数に基づく分岐を行うことも可能である。

import { defineConfig, loadEnv } from 'vite-plus';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
  
  return {
    server: {
      port: parseInt(env.PORT) || 3000,
      proxy: {
        '/api': {
          target: env.VITE_API_URL,
          changeOrigin: true,
        },
      },
    },
    build: {
      sourcemap: mode !== 'production',
    },
  };
});

6.4 TypeScriptによる型安全な設定

defineConfig関数はTypeScriptの型推論を完全にサポートしており、すべての設定項目に対してIDEの補完・エラー検出が動作する。

import { defineConfig } from 'vite-plus';

export default defineConfig({
  server: {
    port: '3000',  // ← TypeScriptエラー: 'string'は'number'に割り当てられません
  },
  build: {
    outDir: 'dist',
    sourcemap: 'invalid',  // ← TypeScriptエラー: 有効な値は boolean | 'inline' | 'hidden'
  },
  test: {
    environment: 'invalid-env',  // ← TypeScriptエラー
  },
});

この型安全性により、設定ミスがランタイムではなくエディタ上で即座に検出される。


7. 開発サーバー(vp dev)

7.1 概要

vp devコマンドは、ViteのDev Serverを起動するコマンドである。ネイティブES Modulesを活用し、バンドルレスで高速な開発サーバーを提供する。

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

# ポートを指定して起動
vp dev --port 5173

# ホストを指定して起動(LAN内アクセス許可)
vp dev --host 0.0.0.0

# 特定のモードで起動
vp dev --mode staging

7.2 HMR(Hot Module Replacement)

Vite+の開発サーバーは、ViteのHMR機能を完全に継承している。ファイルの変更が保存された瞬間に、ブラウザ上のモジュールが即座に差し替えられる。ページ全体のリロードは発生せず、コンポーネントの状態も可能な限り保持される。

HMRの動作フロー:

ファイル保存
    │
    ▼
Vite Dev Server(ファイルシステム監視)
    │
    ▼
変更されたモジュールの依存関係解析
    │
    ▼
WebSocket経由でブラウザに通知
    │
    ▼
ブラウザ側で対象モジュールのみ差し替え
    │
    ▼
UIに即座に反映(状態保持)

7.3 プロキシ設定の実践例

開発環境でバックエンドAPIにプロキシする設定例を示す。

import { defineConfig } from 'vite-plus';

export default defineConfig({
  server: {
    port: 3000,
    proxy: {
      // 単純なプロキシ
      '/api': 'http://localhost:8080',
      
      // 詳細なプロキシ設定
      '/api/v2': {
        target: 'http://localhost:8081',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api\/v2/, ''),
        configure: (proxy, options) => {
          proxy.on('error', (err, req, res) => {
            console.log('proxy error', err);
          });
          proxy.on('proxyReq', (proxyReq, req, res) => {
            console.log('Sending Request:', req.method, req.url);
          });
          proxy.on('proxyRes', (proxyRes, req, res) => {
            console.log('Received Response:', proxyRes.statusCode, req.url);
          });
        },
      },

      // WebSocketプロキシ
      '/ws': {
        target: 'ws://localhost:8082',
        ws: true,
      },

      // 正規表現によるマッチング
      '^/fallback/.*': {
        target: 'http://localhost:8083',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/fallback/, ''),
      },
    },
  },
});

7.4 HTTPS開発環境

ローカル開発でHTTPSを使用する場合の設定例を示す。

import { defineConfig } from 'vite-plus';
import fs from 'node:fs';
import path from 'node:path';

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync(path.resolve(__dirname, 'certs/localhost-key.pem')),
      cert: fs.readFileSync(path.resolve(__dirname, 'certs/localhost.pem')),
    },
  },
});

7.5 フレームワーク固有の設定

React の場合:

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

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
});

Vue の場合:

import { defineConfig } from 'vite-plus';
import vue from '@vitejs/plugin-vue';

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

Svelte の場合:

import { defineConfig } from 'vite-plus';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
  plugins: [svelte()],
  server: {
    port: 3000,
  },
});

8. コード品質(vp check)

8.1 概要

vp checkは、Vite+の最も強力なコマンドの一つである。フォーマットチェック(Oxfmt)、リンティング(Oxlint)、型チェック(TypeScript)を一つのコマンドで並列実行する。

# フォーマット + リンティング + 型チェックを一括実行
vp check

このコマンドは、従来以下のように個別に実行していた3つの処理を統合する。

# 従来のアプローチ(3つのコマンドを順次実行)
npx prettier --check .
npx eslint .
npx tsc --noEmit

# Vite+のアプローチ(1つのコマンドで並列実行)
vp check

8.2 並列実行のアーキテクチャ

vp checkは内部的に3つのチェックを並列実行する。

vp check
    │
    ├──→ Oxfmt(フォーマットチェック)  ─┐
    │                                     │
    ├──→ Oxlint(リンティング)         ─┼──→ 結果の統合・レポート
    │                                     │
    └──→ tsc(型チェック)              ─┘

OxfmtとOxlintはRustベースのため、各チェック自体も内部でマルチスレッド並列処理を行う。これにより、従来のJavaScriptベースのツールで順次実行していた場合と比較して、2倍以上の速度でチェックが完了する。

8.3 パフォーマンス比較

典型的な中規模プロジェクト(TypeScriptファイル約500個)におけるvp checkのパフォーマンスを示す。

アプローチ実行時間備考
Prettier + ESLint + tsc(順次)約45秒従来のJSベースツール
Prettier + ESLint + tsc(並列)約30秒CI環境での並列実行
vp check約12秒Rustベース + 並列実行

8.4 CI/CDでの活用

vp checkはCI/CDパイプラインでのコード品質チェックに最適である。単一コマンドで全チェックが実行されるため、CIの設定が大幅に簡素化される。

# GitHub Actions例
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '24'
      - run: npm ci
      - run: npx vp check  # これだけで全チェック完了

8.5 エラーレポート

vp checkは各チェックの結果を統合した見やすいレポートを出力する。

vp check

 ✓ Format check passed (0.3s)
 ✗ Lint check failed (1.2s)
   
   src/components/Button.tsx
     12:5  error  'useState' is defined but never used  no-unused-vars
     15:3  warn   Missing return type on function       explicit-function-return-type

 ✓ Type check passed (8.5s)

 1 check failed, 2 checks passed (10.0s total)

9. リンティング(vp lint)

9.1 概要

vp lintコマンドは、Oxlintを使用してコードの静的解析を実行する。ESLintと互換性のあるルールセットを高速に実行し、バグの早期検出、コーディング規約の強制を行う。

# リンティングの実行
vp lint

# 自動修正を適用
vp lint --fix

# 特定のファイル/ディレクトリのみ
vp lint src/components/

# 警告をエラーとして扱う
vp lint --max-warnings 0

9.2 Oxlintの特徴

OxlintはRustで実装されたリンターであり、以下の特徴を持つ。

  1. 圧倒的な速度: ESLintの50〜100倍の速度
  2. 低メモリ使用量: Rustのメモリ管理により、大規模プロジェクトでもメモリ使用量が低い
  3. ESLint互換ルール: ESLintの主要ルールをサポート
  4. TypeScript対応: TypeScriptファイルのネイティブ解析

9.3 typeAwareオプション

typeAwareオプションを有効にすると、OxlintはTypeScriptの型情報を利用したより高度なリンティングを実行する。

lint: {
  options: {
    typeAware: true,
  },
}

typeAwareリンティングでは、以下のような型情報を必要とするルールが有効になる。

// typeAwareが検出できる問題の例

// 1. await不要なPromiseの検出
async function fetchData() {
  const result = someNonAsyncFunction();
  await result;  // ← 警告: 'result'はPromiseではないため、awaitは不要
}

// 2. 型の不一致の検出
function process(value: string | number) {
  if (typeof value === 'string') {
    return value.toFixed(2);  // ← エラー: 'string'に'toFixed'は存在しない
  }
}

// 3. 不安全なany型の使用
function riskyFunction(data: any) {
  return data.map((item: any) => item.value);  // ← 警告: 'any'型の使用
}

9.4 typeCheckオプション

typeCheckオプションを有効にすると、Oxlintがリンティングと同時にTypeScriptの型チェックも実行する。

lint: {
  options: {
    typeAware: true,
    typeCheck: true,
  },
}

この設定により、vp lintの実行だけで型エラーも検出される。別途tsc --noEmitを実行する必要がなくなる。

9.5 ESLintからの移行

既存のESLint設定からOxlintへの移行は、段階的に行うことが推奨される。

ステップ1: ルールの対応表を確認

OxlintはESLintの主要なルールをサポートしているが、すべてのルールが1:1で対応しているわけではない。移行前に、使用しているESLintルールのOxlintでの対応状況を確認する。

# 現在のESLintルール一覧を確認
npx eslint --print-config src/index.ts | jq '.rules | keys[]'

ステップ2: Vite+設定にリント設定を追加

import { defineConfig } from 'vite-plus';

export default defineConfig({
  lint: {
    ignorePatterns: ['dist/**', 'node_modules/**'],
    options: {
      typeAware: true,
      typeCheck: true,
    },
  },
});

ステップ3: ESLintの設定ファイルを削除

rm -f .eslintrc.js .eslintrc.json .eslintrc.yml .eslintignore
npm uninstall eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin \
  eslint-config-prettier eslint-plugin-react eslint-plugin-import

ステップ4: 差分の確認

移行直後は、OxlintとESLintで検出結果に差異がある場合がある。vp lintを実行し、出力を確認して必要に応じてコードを修正する。

9.6 カスタムルールの設定

lint: {
  ignorePatterns: [
    'dist/**',
    'node_modules/**',
    'coverage/**',
    '**/*.generated.ts',
  ],
  options: {
    typeAware: true,
    typeCheck: true,
  },
}

10. フォーマッティング(vp fmt)

10.1 概要

vp fmtコマンドは、Oxfmtを使用してコードのフォーマットを統一する。Prettierの代替として機能し、Rustベースの高速処理でコードスタイルを強制する。

# フォーマットを適用
vp fmt

# フォーマットチェックのみ(変更は適用しない)
vp fmt --check

# 特定のファイル/ディレクトリのみ
vp fmt src/components/

# 差分のみフォーマット(Gitステージングされたファイル)
vp fmt --changed

10.2 サポートするファイル形式

Oxfmtは以下のファイル形式のフォーマットをサポートする。

  • JavaScript (.js, .jsx, .mjs, .cjs)
  • TypeScript (.ts, .tsx, .mts, .cts)
  • CSS (.css)
  • SCSS (.scss)
  • LESS (.less)
  • HTML (.html)
  • JSON (.json, .jsonc)
  • Markdown (.md, .mdx)
  • YAML (.yml, .yaml)

10.3 Prettierからの移行

PrettierからOxfmtへの移行は基本的にシームレスである。Oxfmtの出力はPrettierと高い互換性を持つため、大きなフォーマット差異は発生しにくい。

# Prettierの削除
npm uninstall prettier eslint-config-prettier

# 設定ファイルの削除
rm -f .prettierrc .prettierrc.json .prettierrc.js .prettierrc.yml .prettierignore

10.4 エディタ統合

vp fmtはCLIからの実行だけでなく、エディタのフォーマットオンセーブ機能と組み合わせることで、ファイル保存時に自動フォーマットを適用できる。VS Codeの設定例は後述のIDE統合セクションで解説する。

10.5 フォーマットの一貫性保証

チーム開発において、コードスタイルの不一致はコードレビューの負担を増大させる。vp fmtを使用することで、以下の流れでフォーマットの一貫性が保証される。

  1. ローカル開発時: エディタのフォーマットオンセーブで自動フォーマット
  2. コミット前: staged設定によるpre-commitフックでステージングファイルをフォーマット
  3. CI/CD: vp fmt --checkでフォーマット違反がないかチェック
開発者A ──→ フォーマット適用 ──→ コミット ──→ CI(フォーマットチェック)
                                                      │
開発者B ──→ フォーマット適用 ──→ コミット ──→ CI(フォーマットチェック)
                                                      │
                                                      ▼
                                               コードベース
                                            (一貫したスタイル)

11. テスト(vp test)

11.1 概要

vp testコマンドは、Vitestを使用してテストを実行する。VitestはViteのエコシステムに最適化されたテストフレームワークであり、Jest互換のAPIを提供する。

# テストの実行
vp test

# watchモードで実行
vp test --watch

# 特定のテストファイルのみ実行
vp test src/components/Button.test.tsx

# パターンマッチでテスト実行
vp test --grep "should render"

# カバレッジ付きで実行
vp test --coverage

# UIモードで実行
vp test --ui

11.2 重要な違い:watchモードのデフォルト

スタンドアロンのVitestは、デフォルトでwatchモード(ファイル変更の監視・自動再実行)で起動する。しかし、Vite+のvp testデフォルトでwatchモードが無効になっている。

この設計判断の理由は以下の通りである。

  1. CI/CD互換性: CIパイプラインではwatchモードは不要であり、プロセスが終了しない問題を引き起こす
  2. スクリプト統合: npm run testとしてpackage.jsonのスクリプトに登録した場合、watchモードがデフォルトだと使い勝手が悪い
  3. 明示的な選択: watchモードが必要な場合は--watchフラグで明示的に指定する
# デフォルト: テスト実行後に終了
vp test                # → テスト実行 → 結果出力 → プロセス終了

# watchモード: ファイル変更を監視して自動再実行
vp test --watch        # → テスト実行 → 監視開始 → 変更検出 → 再実行 → ...

11.3 テスト設定の詳細

11.3.1 テスト環境の選択

テスト対象のコードによって、適切なテスト環境を選択する。

test: {
  // ブラウザ環境のシミュレーション(React/Vue/Svelteコンポーネント向け)
  environment: 'jsdom',

  // 軽量なブラウザ環境(DOMの基本操作のみ)
  // environment: 'happy-dom',

  // Node.js環境(サーバーサイドコード向け)
  // environment: 'node',
}

11.3.2 セットアップファイル

テスト実行前に共通の初期化処理を行うセットアップファイルを指定できる。

test: {
  setupFiles: ['./src/test/setup.ts'],
}
// src/test/setup.ts
import '@testing-library/jest-dom';

// グローバルなモック設定
vi.mock('./src/api/client', () => ({
  apiClient: {
    get: vi.fn(),
    post: vi.fn(),
    put: vi.fn(),
    delete: vi.fn(),
  },
}));

// テスト前後のクリーンアップ
beforeEach(() => {
  vi.clearAllMocks();
});

afterAll(() => {
  vi.restoreAllMocks();
});

11.3.3 カバレッジの設定

test: {
  coverage: {
    // カバレッジプロバイダー
    provider: 'v8',         // 'v8'(高速)または 'istanbul'(詳細)

    // レポート形式
    reporter: [
      'text',        // コンソール出力
      'json',        // JSONファイル
      'html',        // HTMLレポート
      'lcov',        // lcov形式(SonarQube等との統合用)
      'clover',      // Clover形式
    ],

    // カバレッジ対象
    include: ['src/**/*.{ts,tsx}'],

    // カバレッジ除外
    exclude: [
      'src/**/*.test.{ts,tsx}',
      'src/**/*.spec.{ts,tsx}',
      'src/**/*.d.ts',
      'src/test/**',
      'src/types/**',
      'src/**/*.stories.{ts,tsx}',
    ],

    // カバレッジ閾値(この値を下回るとテスト失敗)
    thresholds: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },

    // すべてのファイルをカバレッジ対象に含める
    // (テストされていないファイルもレポートに表示)
    all: true,
  },
}

11.4 テストの書き方

Vite+でのテストはVitestの標準的な書き方に準拠する。

11.4.1 基本的なユニットテスト

// src/utils/math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

export function divide(a: number, b: number): number {
  if (b === 0) throw new Error('Division by zero');
  return a / b;
}
// src/utils/math.test.ts
import { describe, it, expect } from 'vitest';
import { add, multiply, divide } from './math';

describe('Math utilities', () => {
  describe('add', () => {
    it('should add two positive numbers', () => {
      expect(add(1, 2)).toBe(3);
    });

    it('should handle negative numbers', () => {
      expect(add(-1, 1)).toBe(0);
    });

    it('should handle zero', () => {
      expect(add(0, 0)).toBe(0);
    });
  });

  describe('multiply', () => {
    it('should multiply two numbers', () => {
      expect(multiply(3, 4)).toBe(12);
    });
  });

  describe('divide', () => {
    it('should divide two numbers', () => {
      expect(divide(10, 2)).toBe(5);
    });

    it('should throw on division by zero', () => {
      expect(() => divide(10, 0)).toThrow('Division by zero');
    });
  });
});

11.4.2 非同期テスト

// src/api/users.ts
export async function fetchUser(id: string): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) throw new Error('User not found');
  return response.json();
}
// src/api/users.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { fetchUser } from './users';

describe('fetchUser', () => {
  beforeEach(() => {
    vi.restoreAllMocks();
  });

  it('should fetch and return user data', async () => {
    const mockUser = { id: '1', name: 'Alice' };
    
    global.fetch = vi.fn().mockResolvedValue({
      ok: true,
      json: () => Promise.resolve(mockUser),
    });

    const user = await fetchUser('1');
    expect(user).toEqual(mockUser);
    expect(fetch).toHaveBeenCalledWith('/api/users/1');
  });

  it('should throw when user is not found', async () => {
    global.fetch = vi.fn().mockResolvedValue({
      ok: false,
      status: 404,
    });

    await expect(fetchUser('999')).rejects.toThrow('User not found');
  });
});

11.4.3 Reactコンポーネントテスト

// src/components/Button.tsx
import { type FC, type ReactNode } from 'react';

interface ButtonProps {
  children: ReactNode;
  onClick?: () => void;
  disabled?: boolean;
  variant?: 'primary' | 'secondary';
}

export const Button: FC<ButtonProps> = ({
  children,
  onClick,
  disabled = false,
  variant = 'primary',
}) => {
  return (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
      disabled={disabled}
    >
      {children}
    </button>
  );
};
// src/components/Button.test.tsx
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';

describe('Button', () => {
  it('should render children text', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });

  it('should call onClick when clicked', () => {
    const handleClick = vi.fn();
    render(<Button onClick={handleClick}>Click me</Button>);
    
    fireEvent.click(screen.getByText('Click me'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });

  it('should be disabled when disabled prop is true', () => {
    render(<Button disabled>Click me</Button>);
    expect(screen.getByText('Click me')).toBeDisabled();
  });

  it('should apply variant class', () => {
    render(<Button variant="secondary">Click me</Button>);
    const button = screen.getByText('Click me');
    expect(button).toHaveClass('btn-secondary');
  });
});

11.5 テストのパフォーマンス最適化

大規模プロジェクトでは、テストの実行時間が問題になることがある。以下の最適化手法を活用する。

test: {
  // スレッド並列実行
  pool: 'threads',       // 'threads' | 'forks' | 'vmThreads'
  
  // 並列度
  poolOptions: {
    threads: {
      maxThreads: 4,
      minThreads: 1,
    },
  },

  // ファイルレベルの並列実行
  fileParallelism: true,

  // タイムアウト設定
  testTimeout: 10000,
  hookTimeout: 10000,

  // 遅いテストの検出
  slowTestThreshold: 300,

  // テストの分離レベル
  isolate: true,
}

12. ビルド(vp build)

12.1 概要

vp buildコマンドは、Vite 8 + Rolldownを使用してプロダクション向けのビルドを実行する。アプリケーションコードを最適化し、デプロイ可能なアセットを生成する。

# プロダクションビルド
vp build

# ソースマップ付きでビルド
vp build --sourcemap

# 特定のモードでビルド
vp build --mode staging

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

12.2 Rolldownによる高速ビルド

Vite+のプロダクションビルドバックエンドであるRolldownは、RollupのRust実装であり、以下の特徴を持つ。

  1. Rustの速度: Rollupと比較して大幅に高速なバンドル処理
  2. Rollup互換性: Rollupのプラグインエコシステムとの互換性を維持
  3. ツリーシェイキング: 未使用コードの効率的な除去
  4. コード分割: 動的インポートに基づく自動的なコード分割

12.3 ビルド設定の詳細

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

export default defineConfig({
  plugins: [react()],
  
  build: {
    // 出力ディレクトリ
    outDir: 'dist',
    
    // ビルド前に出力ディレクトリをクリア
    emptyOutDir: true,
    
    // ソースマップ
    sourcemap: true,          // true: 別ファイル, 'inline': インライン, 'hidden': 非公開
    
    // ミニファイ
    minify: 'terser',         // 'terser' | 'esbuild' | false
    
    // ターゲット
    target: 'es2022',
    
    // CSSコード分割
    cssCodeSplit: true,
    
    // チャンクサイズ警告の閾値(KB)
    chunkSizeWarningLimit: 500,
    
    // アセットのインライン化閾値(バイト)
    assetsInlineLimit: 4096,
    
    // Rolldownオプション
    rollupOptions: {
      input: {
        main: 'index.html',
        nested: 'nested/index.html',
      },
      output: {
        // チャンク分割戦略
        manualChunks: (id) => {
          if (id.includes('node_modules')) {
            // vendor分割
            if (id.includes('react')) return 'vendor-react';
            if (id.includes('lodash')) return 'vendor-lodash';
            return 'vendor';
          }
        },
        
        // ファイル名パターン
        entryFileNames: 'assets/[name]-[hash].js',
        chunkFileNames: 'assets/[name]-[hash].js',
        assetFileNames: 'assets/[name]-[hash].[ext]',
      },
      external: [],
    },
  },
});

12.4 ソースマップの戦略

ソースマップの生成方法は、用途によって使い分ける。

build: {
  // 開発/ステージング: デバッグのために完全なソースマップ
  sourcemap: true,
  
  // 本番環境: エラー監視サービス用の隠しソースマップ
  // sourcemap: 'hidden',
  
  // 特殊ケース: インラインソースマップ
  // sourcemap: 'inline',
  
  // パフォーマンス優先: ソースマップなし
  // sourcemap: false,
}
設定ファイルサイズデバッグセキュリティ用途
true容易ソースコード公開開発・ステージング
'hidden'可能(要アップロード)ソースコード非公開本番(Sentry等)
'inline'最大容易ソースコード公開特殊用途
false不可安全パフォーマンス最優先

12.5 ビルド結果のプレビュー

vp previewコマンドで、ビルド結果をローカルでプレビューできる。

# ビルド後にプレビュー
vp build && vp preview
preview: {
  port: 4173,
  open: true,
  host: '0.0.0.0',
}

12.6 ライブラリモードのビルド

ライブラリとして配布するパッケージのビルドには、ライブラリモードを使用する。

import { defineConfig } from 'vite-plus';

export default defineConfig({
  build: {
    lib: {
      entry: 'src/index.ts',
      name: 'MyLibrary',
      formats: ['es', 'cjs', 'umd'],
      fileName: (format) => `my-library.${format}.js`,
    },
    rollupOptions: {
      // 外部依存(バンドルに含めない)
      external: ['react', 'react-dom'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
        },
      },
    },
  },
});

12.7 マルチページアプリケーション

複数のHTMLエントリーポイントを持つアプリケーションのビルド設定を示す。

import { defineConfig } from 'vite-plus';
import { resolve } from 'node:path';

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        admin: resolve(__dirname, 'admin/index.html'),
        login: resolve(__dirname, 'login/index.html'),
      },
    },
  },
});

12.8 ビルドの最適化チェックリスト

プロダクションビルドの品質を確保するためのチェックリストを示す。

  1. ツリーシェイキング: 未使用のエクスポートが除去されているか
  2. コード分割: 適切なチャンク分割が行われているか
  3. アセット最適化: 画像やフォントが最適化されているか
  4. ソースマップ: 本番環境に適したソースマップ戦略か
  5. 環境変数: 本番用の環境変数が正しく設定されているか
  6. バンドルサイズ: チャンクサイズが警告閾値を超えていないか
  7. ブラウザ互換性: ターゲットブラウザの設定が正しいか

13. タスク実行(vp run)

13.1 概要

vp runコマンドは、Vite Taskを使用してカスタムタスクを実行するタスクランナーである。npm scriptsやTurborepo、nxなどの代替として機能し、vite.config.ts内でタスクを定義・管理する。

# タスクの実行
vp run <task-name>

# 例
vp run db:migrate
vp run seed
vp run codegen

13.2 タスクの定義

タスクはvite.config.tsrunセクション内で定義する。

import { defineConfig } from 'vite-plus';

export default defineConfig({
  run: {
    // タスク定義の例
  },
});

13.3 タスクキャッシュ

Vite Taskはタスクの入出力を追跡し、変更がない場合はキャッシュされた結果を返す。これにより、大規模プロジェクトでのタスク実行時間が大幅に短縮される。

キャッシュの仕組み:

タスク実行リクエスト
    │
    ▼
入力ファイルのハッシュ計算
    │
    ├──→ キャッシュヒット → キャッシュから結果を返す(即座)
    │
    └──→ キャッシュミス → タスク実行 → 結果をキャッシュに保存

13.4 npm scriptsとの比較

従来のnpm scriptsとVite Taskの比較を示す。

npm scripts(従来):

{
  "scripts": {
    "db:migrate": "prisma migrate dev",
    "db:seed": "tsx scripts/seed.ts",
    "codegen": "graphql-codegen",
    "prebuild": "npm run codegen",
    "build": "vite build"
  }
}

Vite Task(Vite+):

import { defineConfig } from 'vite-plus';

export default defineConfig({
  run: {
    // vite.config.ts内でタスクを統一管理
    // キャッシュ、依存関係管理、並列実行が自動
  },
});

Vite Taskの利点:

  1. キャッシュ: 変更がないタスクはスキップされる
  2. 依存関係管理: タスク間の依存関係を宣言的に管理
  3. 並列実行: 独立したタスクは自動的に並列実行される
  4. 型安全: TypeScriptでタスクを定義できる
  5. 統一設定: vite.config.ts内で一元管理

14. パッケージング(vp pack)

14.1 概要

vp packコマンドは、tsdownを使用してTypeScriptライブラリのパッケージビルドを実行する。npmに公開するライブラリの構築に特化しており、ESM/CJS/UMDの出力、型定義ファイル(.d.ts)の生成を自動的に行う。

# パッケージビルド
vp pack

# watchモード
vp pack --watch

14.2 tsdownの特徴

tsdownはtsupの後継に位置づけられるTypeScriptバンドラーであり、以下の特徴を持つ。

  1. DTS生成: TypeScriptの型定義ファイルを自動生成
  2. 複数フォーマット出力: ESM、CJS、UMDを同時に生成
  3. Rolldownベース: 高速なバンドル処理
  4. ゼロ設定: package.jsonの情報から自動的にビルド設定を推論

14.3 ライブラリの設定例

import { defineConfig } from 'vite-plus';

export default defineConfig({
  pack: {
    // tsdownのパッケージビルド設定
  },
});

14.4 package.jsonとの連携

パッケージビルドの出力は、package.jsonのexportsフィールドと連携する。

{
  "name": "my-library",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    },
    "./utils": {
      "types": "./dist/utils.d.ts",
      "import": "./dist/utils.js",
      "require": "./dist/utils.cjs"
    }
  },
  "files": ["dist"],
  "scripts": {
    "build": "vp pack",
    "dev": "vp pack --watch"
  }
}

14.5 ライブラリ開発のワークフロー

ソースコード(src/index.ts)
    │
    ▼
vp pack
    │
    ├──→ dist/index.js      # ESM出力
    ├──→ dist/index.cjs     # CJS出力
    ├──→ dist/index.d.ts    # 型定義
    └──→ dist/index.d.cts   # CJS型定義
    │
    ▼
npm publish

14.6 tsup/unbuildからの移行

既存のtsupまたはunbuild設定からの移行例を示す。

tsup設定(移行前):

// tsup.config.ts
import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],
  dts: true,
  splitting: false,
  sourcemap: true,
  clean: true,
});

Vite+設定(移行後):

// vite.config.ts
import { defineConfig } from 'vite-plus';

export default defineConfig({
  pack: {
    // tsdownの設定
    // package.jsonから自動推論されるため、多くの場合追加設定不要
  },
});

15. CI/CD統合

15.1 GitHub Actionsとの統合

Vite+はCI/CD環境での使用を考慮して設計されている。以下にGitHub Actionsでの典型的な設定例を示す。

15.1.1 基本的なCI設定

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  check:
    name: Code Quality Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run all checks
        run: npx vp check    # フォーマット + リンティング + 型チェック

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests with coverage
        run: npx vp test --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage/lcov.info

  build:
    name: Build
    runs-on: ubuntu-latest
    needs: [check, test]    # check/testが成功後に実行
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npx vp build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

15.1.2 pnpmを使用したCI設定

# .github/workflows/ci.yml
name: CI (pnpm)

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Check (format + lint + typecheck)
        run: pnpm exec vp check

      - name: Test
        run: pnpm exec vp test --coverage

      - name: Build
        run: pnpm exec vp build

15.1.3 マトリクスビルド(複数OS・Node.jsバージョン)

# .github/workflows/matrix.yml
name: Matrix CI

on:
  push:
    branches: [main]

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: ['24']
    
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npx vp check
      - run: npx vp test
      - run: npx vp build

15.2 GitLab CIとの統合

# .gitlab-ci.yml
stages:
  - check
  - test
  - build

variables:
  NODE_VERSION: '24'

.node_template: &node_template
  image: node:${NODE_VERSION}
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  before_script:
    - npm ci

check:
  <<: *node_template
  stage: check
  script:
    - npx vp check

test:
  <<: *node_template
  stage: test
  script:
    - npx vp test --coverage
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

build:
  <<: *node_template
  stage: build
  script:
    - npx vp build
  artifacts:
    paths:
      - dist/

15.3 CI環境での最適化

CI環境ではいくつかの最適化が可能である。

# キャッシュの活用
- name: Cache node_modules
  uses: actions/cache@v4
  with:
    path: |
      node_modules
      ~/.cache
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

15.4 Dockerとの統合

# Dockerfile
FROM node:24-alpine AS builder

WORKDIR /app

# 依存関係のインストール(キャッシュ効率化)
COPY package.json package-lock.json ./
RUN npm ci

# ソースコードのコピーとビルド
COPY . .
RUN npx vp check
RUN npx vp test
RUN npx vp build

# プロダクションイメージ
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

16. コミットフック

16.1 概要

Vite+はstaged設定を通じて、Gitのpre-commitフックとの統合を提供する。コミット前にステージングされたファイルに対してフォーマットとリンティングを自動実行し、品質の低いコードがリポジトリにコミットされることを防ぐ。

16.2 staged設定

import { defineConfig } from 'vite-plus';

export default defineConfig({
  staged: {
    // ステージングされたファイルに対して
    // フォーマットとリンティングを実行
  },
});

16.3 従来のアプローチとの比較

従来のアプローチ(Husky + lint-staged):

# パッケージのインストール
npm install -D husky lint-staged

# Huskyの初期化
npx husky init
// .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
// .lintstagedrc.json
{
  "*.{ts,tsx}": [
    "eslint --fix",
    "prettier --write"
  ],
  "*.{css,scss}": [
    "prettier --write"
  ],
  "*.{json,md}": [
    "prettier --write"
  ]
}

Vite+のアプローチ:

// vite.config.ts のみ
import { defineConfig } from 'vite-plus';

export default defineConfig({
  staged: {
    // Vite+が内部的にpre-commitフックを管理
  },
});

Vite+のアプローチでは、以下の利点がある。

  1. 追加パッケージ不要: Husky、lint-stagedの個別インストールが不要
  2. 設定の統一: vite.config.ts内で完結
  3. 高速実行: Oxlint/Oxfmtの高速な処理により、コミット待ち時間が最小化
  4. シェルスクリプト不要: .husky/ディレクトリやシェルスクリプトの管理が不要

16.4 pre-commitフックの実行フロー

git commit
    │
    ▼
pre-commitフック起動
    │
    ▼
ステージングされたファイルの取得
    │
    ├──→ Oxfmt(フォーマット適用)
    │
    ├──→ Oxlint(リンティング)
    │
    ▼
結果の確認
    │
    ├──→ すべてパス → コミット実行
    │
    └──→ エラーあり → コミット中断 + エラー表示

16.5 チーム全体での運用

pre-commitフックをチーム全体で統一的に運用するために、以下のベストプラクティスを推奨する。

  1. フックのセットアップ自動化: npm install後に自動的にフックが設定されるようにする
  2. CI/CDとの一貫性: ローカルのpre-commitとCIで同じチェックが実行されることを確認
  3. ドキュメント化: 新しいチームメンバー向けにセットアップ手順を文書化
  4. バイパスオプション: 緊急時に--no-verifyでフックをスキップできることを周知

17. IDE統合

17.1 VS Code(Visual Studio Code)

Vite+はVS Codeとの統合を考慮して設計されている。

17.1.1 推奨拡張機能

// .vscode/extensions.json
{
  "recommendations": [
    "oxc.oxc-vscode",          // Oxlint + Oxfmt統合
    "vitest.explorer",          // Vitestテストエクスプローラー
    "vue.volar",                // Vue.jsサポート(Vue使用時)
    "bradlc.vscode-tailwindcss" // Tailwind CSS(使用時)
  ]
}

17.1.2 ワークスペース設定

// .vscode/settings.json
{
  // Oxfmtをデフォルトフォーマッターとして使用
  "editor.defaultFormatter": "oxc.oxc-vscode",
  "editor.formatOnSave": true,
  
  // TypeScript/JavaScript
  "[typescript]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.oxc": "explicit"
    }
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.oxc": "explicit"
    }
  },
  "[javascript]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true
  },

  // JSON
  "[json]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true
  },

  // CSS/SCSS
  "[css]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true
  },
  "[scss]": {
    "editor.defaultFormatter": "oxc.oxc-vscode",
    "editor.formatOnSave": true
  },

  // 従来のESLint/Prettierを無効化
  "eslint.enable": false,
  "prettier.enable": false,

  // Vitest統合
  "vitest.enable": true,
  "vitest.commandLine": "npx vp test"
}

17.1.3 デバッグ設定

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Vite Dev Server",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "npx",
      "runtimeArgs": ["vp", "dev"],
      "console": "integratedTerminal",
      "skipFiles": ["<node_internals>/**"]
    },
    {
      "name": "Debug Current Test File",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "npx",
      "runtimeArgs": [
        "vp", "test",
        "--reporter=verbose",
        "${relativeFile}"
      ],
      "console": "integratedTerminal",
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}

17.1.4 タスク設定

// .vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Vite+ Dev",
      "type": "shell",
      "command": "npx vp dev",
      "isBackground": true,
      "problemMatcher": [],
      "group": "build"
    },
    {
      "label": "Vite+ Build",
      "type": "shell",
      "command": "npx vp build",
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": ["$tsc"]
    },
    {
      "label": "Vite+ Test",
      "type": "shell",
      "command": "npx vp test",
      "group": {
        "kind": "test",
        "isDefault": true
      },
      "problemMatcher": []
    },
    {
      "label": "Vite+ Check",
      "type": "shell",
      "command": "npx vp check",
      "group": "build",
      "problemMatcher": ["$tsc"]
    }
  ]
}

17.2 JetBrains IDE(WebStorm/IntelliJ IDEA)

JetBrains IDEでもVite+の統合が可能である。

17.2.1 File Watcher設定

WebStormのFile Watcherを使用して、ファイル保存時にOxfmtを自動実行する。

  1. Settings > Tools > File Watchers を開く
  2. 新規ウォッチャーを追加:
    • Name: Oxfmt
    • File type: TypeScript
    • Program: npx
    • Arguments: vp fmt $FilePath$
    • Output paths to refresh: $FilePath$

17.2.2 外部ツール設定

  1. Settings > Tools > External Tools を開く
  2. 新規ツールを追加:
    • Name: Vite+ Check
    • Program: npx
    • Arguments: vp check
    • Working directory: $ProjectFileDir$

17.3 Neovim

Neovimユーザー向けの設定例を示す。

-- init.lua(nvim-lspconfig使用時)
local lspconfig = require('lspconfig')

-- TypeScript LSPの設定
lspconfig.ts_ls.setup({
  -- Vite+プロジェクトでの設定
})

-- フォーマットオンセーブ
vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = {"*.ts", "*.tsx", "*.js", "*.jsx"},
  callback = function()
    vim.cmd("silent !npx vp fmt " .. vim.fn.expand('%'))
    vim.cmd("edit")
  end,
})

18. 対応プラットフォーム

18.1 Node.jsバージョン

Vite+はNode.js v24以上を要求する。これは以下の機能への依存があるためである。

  • ES Modules: import/exportのネイティブサポート
  • import.meta: モジュールメタデータへのアクセス
  • Top-level await: モジュールのトップレベルでのawait使用
  • Fetch API: グローバルなfetch関数
  • Web Streams API: ReadableStream/WritableStream
// package.json
{
  "engines": {
    "node": ">=24.0.0"
  }
}

18.2 オペレーティングシステム

Vite+は以下のオペレーティングシステムをサポートする。

OSアーキテクチャサポート状況
Linuxx64完全サポート
Linuxarm64完全サポート
macOSx64 (Intel)完全サポート
macOSarm64 (Apple Silicon)完全サポート
Windowsx64完全サポート
Windowsarm64完全サポート

RustベースのツールはOSネイティブのバイナリとして配布されるため、各プラットフォームに対してプリコンパイル済みのバイナリが提供される。napi-rsが各プラットフォーム向けのバインディングを自動的に選択する。

18.3 パッケージマネージャー

Vite+は以下のパッケージマネージャーをサポートする。

パッケージマネージャーバージョンサポート状況
npm10+完全サポート
pnpm9+完全サポート(推奨)
yarn4+完全サポート
Bun1+完全サポート

プロジェクト作成時にパッケージマネージャーを指定できる。

# pnpmを使用
vp create my-app --template vite:application --pm pnpm

# yarnを使用
vp create my-app --template vite:application --pm yarn

# Bunを使用
vp create my-app --template vite:application --pm bun

# npmを使用(デフォルト)
vp create my-app --template vite:application --pm npm

18.4 フレームワークサポート

Vite+はフレームワーク非依存(framework-agnostic)であり、以下のフレームワークをサポートする。

フレームワークプラグイン備考
React@vitejs/plugin-reactReact 18/19対応
Vue@vitejs/plugin-vueVue 3対応
Svelte@sveltejs/vite-plugin-svelteSvelte 4/5対応
Solidvite-plugin-solidSolidJS対応
Preact@preactjs/preset-vitePreact対応
Vanillaなし(プラグイン不要)フレームワークなし

各フレームワークの設定例:

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

export default defineConfig({
  plugins: [react()],
  // ... その他の設定
});
// Vue
import { defineConfig } from 'vite-plus';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  // ... その他の設定
});
// Svelte
import { defineConfig } from 'vite-plus';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
  plugins: [svelte()],
  // ... その他の設定
});

18.5 ブラウザサポート

Vite+のビルド出力は、build.target設定によりターゲットブラウザを指定できる。

build: {
  // モダンブラウザ(デフォルト)
  target: 'es2022',

  // 幅広いブラウザサポート
  // target: 'es2015',

  // 特定のブラウザバージョン
  // target: ['chrome100', 'firefox100', 'safari15', 'edge100'],
}

19. まとめ

19.1 Vite+の位置づけ

Vite+は、JavaScript/TypeScript開発エコシステムにおける「断片化」という根本的な課題に対する包括的な解答である。従来、開発者は複数の独立したツール(バンドラー、テストフレームワーク、リンター、フォーマッター、タスクランナー)を個別に選定、設定、管理する必要があった。Vite+はこれらすべてを単一のツールチェーンに統合し、以下の価値を提供する。

  1. 統一されたエントリーポイント: vpコマンドからすべての開発操作を実行
  2. 単一の設定ファイル: vite.config.tsでツールチェーン全体を設定
  3. 圧倒的なパフォーマンス: Rustベースのツールによる10x-100xの高速化
  4. 開発者体験の向上: プロジェクトのセットアップから日常の開発まで、すべてが簡素化
  5. コード品質の一貫性: vp checkによる統合的な品質チェック

19.2 導入の判断基準

Vite+の導入は、以下のようなプロジェクト・チームに特に適している。

導入が推奨されるケース:

  • 新規プロジェクトの立ち上げ
  • ツール設定の複雑さに悩んでいるチーム
  • CI/CDパイプラインのパフォーマンスを改善したいチーム
  • 複数のプロジェクト間でツールチェーンを標準化したい組織
  • モダンなJavaScript/TypeScript開発スタックを採用する意思があるチーム

慎重に検討すべきケース:

  • Node.js v24未満の環境に制約があるプロジェクト
  • ESLintの高度なカスタムルールに大きく依存しているプロジェクト
  • 既存のツールチェーンが安定して運用されており、変更コストが正当化しにくいプロジェクト

19.3 主要コマンドのリファレンス

本記事で解説したVite+の主要コマンドを一覧にまとめる。

コマンド内部ツール用途
vp create-プロジェクトの新規作成
vp devVite開発サーバーの起動
vp buildVite 8 + Rolldownプロダクションビルド
vp previewViteビルド結果のプレビュー
vp testVitestテストの実行
vp lintOxlintリンティング
vp fmtOxfmtフォーマッティング
vp checkOxfmt + Oxlint + tscフォーマット + リンティング + 型チェック
vp runVite Taskカスタムタスクの実行
vp packtsdownライブラリパッケージのビルド

19.4 今後の展望

Vite+は急速に進化するプロジェクトであり、以下の方向性が期待される。

  1. ツール統合の深化: Oxlint/Oxfmtのルールカバレッジの拡大、ESLintプラグインとの互換性向上
  2. パフォーマンスの更なる向上: Rolldownの成熟に伴うビルド速度の改善
  3. エコシステムの拡大: サードパーティプラグイン、テンプレート、統合ツールの充実
  4. エンタープライズ機能: モノレポスケールでのワークスペース管理、キャッシュ共有
  5. 開発者体験の向上: エラーメッセージの改善、ドキュメントの充実

19.5 結論

Vite+は、JavaScript/TypeScript開発の「次のスタンダード」となり得るツールチェーンである。Viteの成功を基盤としつつ、開発に必要なすべてのツールを統合し、Rustベースの実装で圧倒的なパフォーマンスを実現している。

単一の設定ファイル、単一のCLI、そして統一されたツールチェーン。Vite+がもたらすのは、開発者が「ツールの管理」ではなく「コードの開発」に集中できる環境である。プロジェクトの規模やフレームワークに関わらず、一貫した開発体験を提供するVite+は、現代のWeb開発者にとって有力な選択肢となるだろう。


本記事は2026年4月時点の情報に基づいている。Vite+は活発に開発が進められているプロジェクトであるため、最新の情報は公式ドキュメントを参照されたい。