概要
web開発で使う複数のツールを vp という単一のCLIにまとめるためのツールチェーン。
これまではlinterやformatterなどを個別に導入し、個別に設定ファイルが必要だったが、vite+はこれをvite.config.ts ファイルに一元管理している。
「Vite + Vitest + formatter + linter + runtime/package manager管理」をまとめてやるのがvite+というイメージ。
内部使用技術
- Vite / Rolldown:開発サーバー・ビルド
- Vitest:テスト
- Oxc(Oxlint / Oxfmt):Lint・Format
- tsgo:高速なTypeScriptチェック
- tsdown:ライブラリのパッケージ化
vp コマンド例
よく使うコマンドは基本的にvpから実行できる。
vp dev # 開発サーバー
vp build # 本番ビルド
vp check # format / lint / 型チェック
vp test # テスト
vp run # package.json のスクリプト実行
vp pack # ライブラリのパッケージ化
従来のviteとの違い
従来のvite(~7)は、開発時esbuild、本番時はRollupというバンドラーを使っていた。
esbuildとRollupでは得意領域が異なり、それゆえに2つを併用する運用になっていた。
- 開発時はesbuild
- TypeScript / JSX の変換
- 依存パッケージの事前バンドル
- とにかく速く変換する
- (× 複雑なchunk分割は苦手…)
- 本番ビルド時Rollup
- 依存グラフを解析する
- tree-shaking(avaScript のバンドルサイズを削減するための技術)
- chunk 分割(1つの大きなjsファイルを複数のファイルに分割する)
- 出力ファイルを最適化する
- Rollup / Vite プラグインを動かす
- (× 大量のモジュールを高速で変換することは苦手…)
だがviteの8になって、バンドラーはRolldownに一本化された。
RolldownはesbuildとRollupの両方のいいとこどり。esbuildの高速なモジュール変換とRollupのTree-shakingを併せ持つ。
vite+もこれを引き付き、Rolldownを使っている。
ちなみにesbuildはGO製、Rollupはjs製, RolldownはRust製。
Next.jsでの利用
vite+はNext.jsのプロジェクトでも利用できる。
vp create create-next-appでNext.jsのプロジェクトを作成すると、vp devでnext devが実行される(参照)。
| コマンド | React + Vite+ | Next.js + Vite+ |
|---|---|---|
vp dev |
Vite dev server | next dev |
vp build |
Rolldown | next build |
vp check |
Oxlint + Oxfmt | Oxlint + Oxfmt |
vp test |
Vitest | Vitest |
表まとめ
| 対象 | 従来の構成 | Vite+での構成 | 高速化の本質 |
|---|---|---|---|
| 開発サーバー | ViteのネイティブESM配信 |
vp dev → Vite |
仕組みは基本的にViteを継承 |
| 本番ビルド | Vite 7以前はesbuild + Rollup | Vite 8 + Rolldown | Rust製バンドラへの統合 |
| Lint | ESLint | Oxlint | Rust製解析器 |
| Format | Prettier | Oxfmt | Rust製整形器 |
| 型チェック |
tsc --noEmit を別実行 |
vp check に統合可能 |
型付きLintとの重複処理を減らす |
| テスト | Vitestを別導入・別実行 |
vp test → Vitest |
主に設定と運用の統一 |
| CI / モノレポ | scripts + 別タスクランナー | Vite Task | 依存追跡・キャッシュ・並列実行 |
使ってみる
環境構築
vite+のインストール
curl -fsSL https://vite.plus | bash
実行結果
~/Desktop/study/vite-plus ⌚ 15:55:42
$ curl -fsSL https://vite.plus | bash
Setting up VITE+...
Would you like Vite+ to manage your Node.js versions?
It adds `node`, `npm`, `npx`, and `corepack` shims to ~/.vite-plus/bin/ and automatically uses the right version.
Opt out anytime with `vp env off`.
Press Enter to accept (Y/n): Y
✔ VITE+ successfully installed!
The Unified Toolchain for the Web.
Get started:
vp create Create a new project
vp env Manage Node.js versions
vp install Install dependencies
vp migrate Migrate to Vite+
Vite+ is now managing Node.js via vp env.
Run vp env doctor to verify your setup, or vp env off to opt out.
Run vp help to see available commands.
Shell configuration:
- zsh: updated ~/.zshenv, ~/.zshrc
- bash: skipped (no existing rc files)
- fish: skipped (not installed)
- nushell: skipped (not installed)
Note: Restart your terminal to load updated shell configuration.
ターミナルを開き直して、vp helpでエラーにならなければOK。
React + TypeScript プロジェクトを作成
vp create vite -- shopping-list --template react-ts
実行結果(選択項目はひとまずすべてそれっぽいもの)
~/Desktop/study/vite-plus ⌚ 15:58:53
$ vp create vite -- shopping-list --template react-ts
cd shopping-list
VITE+ - The Unified Toolchain for the Web
◇ Which package manager would you like to use?
npm
◇ npm@11.17.0 installed
◇ Which coding agent instruction files should Vite+ create?
AGENTS.md
◇ Which editors are you using?
Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations.
VSCode
◇ Initialize a git repository with an initial commit?
Yes
◇ Set up pre-commit hooks to run formatting, linting, and type checking with auto-fixes?
Yes
Generating project…
Running: npx create-vite shopping-list --template react-ts --no-immediate --no-rolldown
Need to install the following packages:
create-vite@9.0.7
Ok to proceed? (y) y
│
◇ Scaffolding project in /Users/<USER>/Desktop/study/vite-plus/shopping-list...
│
└ Done. Now run:
cd shopping-list
npm install
npm run dev
Wrote agent instructions to AGENTS.md
Wrote editor config to .vscode/settings.json
Wrote editor config to .vscode/extensions.json
◇ Dependencies installed
Migrating ESLint config to Oxlint...
ESLint config migrated to .oxlintrc.json
Replacing ESLint comments with Oxlint equivalents...
ESLint comments replaced
✔ Removed shopping-list/eslint.config.js
✔ Rewrote types in shopping-list/tsconfig.app.json
✔ Merged shopping-list/.oxlintrc.json into shopping-list/vite.config.ts
Rewrote imports in one file
shopping-list/vite.config.ts
✔ Wrapped inline Vite plugins with lazyPlugins in shopping-list/vite.config.ts
✔ Merged staged config into shopping-list/vite.config.ts
✔ Git hooks configured
◇ Dependencies installed
◇ Code formatted
Initial commit failed
⚠ Skipping backup because there’s no initial commit yet. This might result in data loss.
[STARTED] Preparing lint-staged...
[COMPLETED] Preparing lint-staged...
[STARTED] Running tasks for staged files...
[STARTED] Config object — 22 files
[STARTED] * — 22 files
[STARTED] vp check --fix
[FAILED] vp check --fix [FAILED]
[FAILED] vp check --fix [FAILED]
[COMPLETED] Running tasks for staged files...
[STARTED] Applying modifications from tasks...
[COMPLETED] Applying modifications from tasks...
✖ vp check --fix:
error: Lint or type issues found
x typescript(TS2321): Excessive stack depth comparing types '() => Plugin<any>[][]' and '() => PluginOption[]'.
,-[vite.config.ts:132:12]
131 | },
132 | plugins: lazyPlugins(() => [react()]),
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
133 | });
`----
x typescript(TS2769): No overload matches this call.
,-[vite.config.ts:132:30]
131 | },
132 | plugins: lazyPlugins(() => [react()]),
: ^^^^^^^^^
133 | });
`----
Found 2 errors and 0 warnings in 3 files (1.3s, 8 threads)
pass: Formatting completed for checked files (2.5s)
VITE+ - pre-commit script failed (code 1)
◇ Scaffolded shopping-list with React + TypeScript
• Node 24.17.0 npm 11.17.0
✓ Dependencies installed in 19s
→ Next: cd shopping-list && vp run
vite.config.ts の plugins: lazyPlugins(() => [react()]) でエラーになる場合
lazyPlugins は、vp check やエディタ連携時に重い Vite プラグインを読み込まないための最適化。
学習用の小さな React アプリでは、lazyPlugins は必須ではないので、vite.config.tsから一旦削除。あるいは以下のように型アサーションを使っても解決できる。
// PluginOption を新たにimport
import { defineConfig, lazyPlugins, type PluginOption } from "vite-plus";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
staged: {
"*": "vp check --fix",
},
...,
// こうする
plugins: lazyPlugins(() => react() as unknown as PluginOption[]),
結果のログからも分かる通り、create時に
- 使用するパッケージマネージャー
- どのAIエージェントのファイルを作成するか
- どのエディタを使うか
- Gitリポジトリを最初のコミットで初期化するか
- フォーマット、リンティング、型チェック、自動修正を実行するためのプリコミットフックを設定するか
を選択できる。
createが完了したら、作成したディレクトリに移動しておく。
cd shopping-list
Node.jsバージョンを固定
vp env pin lts
実行結果
$ vp env pin lts
VITE+ - The Unified Toolchain for the Web
✓ Pinned Node.js version to 24.17.0 (resolved from lts)
Updated devEngines.runtime in /Users/<USER>/Desktop/study/vite-plus/shopping-list/package.json
✓ Node.js 24.17.0 installed
このディレクトリで Vite+ が最終的に採用した Node.js 環境を確認する。
vp env current
実行結果
$ vp env current
VITE+ - The Unified Toolchain for the Web
Environment:
Version 24.17.0
Source devEngines.runtime
Source Path /Users/<USER>/Desktop/study/vite-plus/shopping-list/package.json
Project Root /Users/<USER>/Desktop/study/vite-plus/shopping-list
Tool Paths:
node /Users/<USER>/.vite-plus/js_runtime/node/24.17.0/bin/node
npm /Users/<USER>/.vite-plus/js_runtime/node/24.17.0/bin/npm
npx /Users/<USER>/.vite-plus/js_runtime/node/24.17.0/bin/npx
Package Manager:
Name npm
Version 11.17.0
Source devEngines.packageManager
Source Path /Users/<USER>/Desktop/study/vite-plus/shopping-list/package.json
Project Root /Users/<USER>/Desktop/study/vite-plus/shopping-list
Bin Path /Users/<USER>/.vite-plus/package_manager/npm/11.17.0/npm/bin/npm
| 項目 | 意味 |
|---|---|
Version |
実際に使われる Node.js のバージョン |
Source |
そのバージョンがどの設定から決まったか |
Source Path |
Source の設定ファイルの場所 |
Project Root |
Vite+ がプロジェクトルートと認識した場所 |
Tool Paths |
実際に Vite+ が使う node / npm / npx の実体パス |
依存関係の確認
依存関係をインストールする。使われるpackageManagerはpackage.jsonに記載されている。
vp install
開発サーバーの起動
vp dev
localhostで起動する。
ビルド
vp build
実行結果
$ vp build
VITE+ - The Unified Toolchain for the Web
vite v8.0.16 building client environment for production...
✓ 20 modules transformed.
computing gzip size...
dist/index.html 0.46 kB │ gzip: 0.29 kB
dist/assets/react-CHdo91hT.svg 4.12 kB │ gzip: 2.06 kB
dist/assets/vite-BF8QNONU.svg 8.70 kB │ gzip: 1.60 kB
dist/assets/hero-CLDdwZDr.png 13.05 kB
dist/assets/index-D64VDMd1.css 4.10 kB │ gzip: 1.47 kB
dist/assets/index-DfKp6xNp.js 193.35 kB │ gzip: 60.67 kB
✓ built in 769ms
ルートにdistフォルダが生成される。
ビルド結果をローカルで確認する場合は以下のコマンドを実行。
vp preview
確認
vp check
コード品質に関する静的チェックをまとめで実行する。
- formatチェック(Oxfmt)
- Lintチェック(Oxlint)
- TypeScript型チェック
-
defineConfigでlint設定が必要
export default defineConfig({ lint: { options: { typeAware: true, typeCheck: true, }, }, });
-
vp checkコマンドのオプションは以下のようなものがある。
- vp check --fix
- フォーマットと自動修正可能なLintを修正
- vp check --no-fmt
- Format確認を飛ばし、Lint・型チェックだけを実行
- vp check --no-lint
- Lintルールは飛ばし、型チェックは残す
- vp check --no-fmt --no-lint
- 型チェックだけを実行。lintの設定が必要
作ってみたアプリ
仕様設計〜実装まで全てcodexにやってもらった、ほどほどのコード量があるアプリです。
UIや機能はかなり雑な作りですが、vp checkなどがどれくらいの時間で完了するのかなどは確認できるかと思います。
所感
作成したプロジェクトの規模が小さいこともあるが、vp check実行から完了までが早く感じる。 LinterやFormatterの設定が不要なのはとても快適。vp checkを実行すればまとめて実行できるのも良い。学習目的、Poc作成などにいいかもしれない。
とはいえ、ESLint / Prettierの設定は、最近はAIに丸っとやってもらうとかもできると思うし、Vite+で採用されているOxlint / Oxfmtではできない設定がESLint / Prettierではできる設定もある。
現在アルファ版ということで、vp create 実行時に早速エラーが出るなどもあったが、今後の発展がとても楽しみ。
参考