Vite vs webpack — 2024年版 徹底比較ガイド
1. 結論
新規プロジェクトであれば Vite を第一候補にしてください。 Native ESM ベースの開発サーバーにより圧倒的な開発体験(DX)が得られ、設定もミニマルで済みます。一方、大規模な既存プロジェクトや高度にカスタマイズされたビルドパイプラインを持つ場合は、webpack が依然として堅実な選択肢です。エコシステムの厚みとプラグイン・ローダーの豊富さでは webpack に一日の長があります。
2. 比較表
| 観点 | Vite | webpack |
|---|---|---|
| バージョン(2024年時点) | v5.x | v5.x |
| 開発サーバー起動 | ⚡ ミリ秒〜数秒(Native ESM) | 🐢 数秒〜数十秒(バンドル後に配信) |
| HMR(Hot Module Replacement) | ⚡ ほぼ即時(モジュール単位) | 🔄 プロジェクト規模に比例して遅延 |
| 本番ビルド | Rollup ベース | 独自バンドラー |
| 設定ファイル | vite.config.ts(最小限で動く) | webpack.config.js(詳細な設定が必要) |
| TypeScript 対応 | ゼロコンフィグで対応 | ts-loader / babel-loader 等が必要 |
| CSS / PostCSS | ゼロコンフィグで対応 | css-loader + style-loader 等が必要 |
| JSON インポート | ゼロコンフィグ(Named Export 対応) | ゼロコンフィグ(v5 以降) |
| コード分割 | Rollup のチャンク戦略 | 高度な splitChunks 設定が可能 |
| Tree Shaking | Rollup ベースで優秀 | v5 で大幅改善済み |
| プラグイン数 | 増加中(Rollup 互換 + Vite 専用) | 圧倒的に豊富(10年以上の蓄積) |
| ローダー概念 | なし(プラグインに統一) | ローダー + プラグインの二層構造 |
| SSR サポート | 組み込み(実験的→安定化中) | 設定次第で可能 |
| レガシーブラウザ対応 | @vitejs/plugin-legacy で対応 | Babel + browserslist で柔軟に対応 |
| Module Federation | コミュニティプラグインで対応 | v5 で公式サポート(マイクロフロントエンド) |
| 学習コスト | 🟢 低い | 🔴 高い |
| npm 週間DL数(目安) | 約 1,500 万 | 約 2,800 万 |
| 主な採用フレームワーク | Vue, Nuxt 3, SvelteKit, Astro, Remix (対応) | Next.js (※Turbopack移行中), Angular (※esbuild移行中), CRA |
3. それぞれの強み
⚡ Vite の強み
-
開発サーバーの起動が爆速 ブラウザの Native ESM を活用し、ソースコードを事前バンドルしません。依存パッケージのみ esbuild で事前バンドル(Dependency Pre-Bundling)するため、プロジェクト規模が大きくなっても起動速度が劣化しにくい設計です。
-
設定がミニマル TypeScript、JSX、CSS Modules、PostCSS、静的アセットなどがゼロコンフィグで動作します。
vite.config.tsは数行で済むケースも珍しくありません。 -
統一されたプラグイン API Rollup のプラグインインターフェースを拡張した形で設計されており、ローダーとプラグインを区別する必要がありません。
-
フレームワーク公式サポート Vue(Evan You 自身が開発)、Svelte、Astro など多くのモダンフレームワークがデフォルトのビルドツールとして採用しています。
-
SSR の組み込みサポート
vite.ssrLoadModule()など SSR 向けの API が組み込まれており、フレームワーク作者がその上に構築しやすい設計です。
📦 webpack の強み
-
圧倒的なエコシステム 10年以上の歴史で蓄積されたローダー・プラグインの数は他の追随を許しません。ニッチな要件にも対応するローダーが見つかることが多いです。
-
Module Federation マイクロフロントエンドを実現する Module Federation が公式サポートされています。複数チームが独立してデプロイ可能なアーキテクチャを構築する場合、webpack は最も成熟した選択肢です。
-
高度なコード分割
splitChunksの設定は複雑ですが、それだけ細かい粒度でチャンク戦略を制御できます。大規模アプリケーションでのキャッシュ効率の最適化に威力を発揮します。 -
レガシー環境への対応力 CommonJS モジュール、AMD、古いブラウザなど、レガシーな要件への対応は長年の実績があります。
-
安定性と実績 Fortune 500 企業を含む膨大な本番環境での稼働実績があり、エッジケースへの対処も十分にテストされています。
4. コード例で比較
4-1. プロジェクトの初期セットアップ
Vite
# プロジェクト作成(対話式で React + TypeScript を選択)
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev # ← 数百ミリ秒で起動
生成される vite.config.ts:
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
たったこれだけで TypeScript + React + HMR が動作します。
webpack
mkdir my-app && cd my-app
npm init -y
npm install --save-dev webpack webpack-cli webpack-dev-server \
typescript ts-loader html-webpack-plugin \
@types/react @types/react-dom
npm install react react-dom
// webpack.config.ts
import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import type { Configuration } from 'webpack'
import 'webpack-dev-server' // DevServer の型を拡張
const config: Configuration = {
mode: 'development',
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
devServer: {
port: 3000,
hot: true,
open: true,
},
}
export default config
// tsconfig.json(別途必要)
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist"
},
"include": ["src"]
}
webpack では設定ファイルだけで 40 行以上、追加パッケージも多数必要です。
4-2. 環境変数の扱い
Vite
// .env
// VITE_API_URL=https://api.example.com
// src/api.ts
const apiUrl: string = import.meta.env.VITE_API_URL
console.log(apiUrl) // "https://api.example.com"
VITE_プレフィックスの変数のみクライアントに公開(安全設計)import.meta.envで型安全にアクセス可能
// src/vite-env.d.ts(型定義を拡張)
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
}
webpack
// webpack.config.ts(追加設定)
import { DefinePlugin } from 'webpack'
import dotenv from 'dotenv'
dotenv.config()
// plugins 配列に追加
new DefinePlugin({
'process.env.API_URL': JSON.stringify(process.env.API_URL),
})
// src/api.ts
declare const process: { env: { API_URL: string } }
const apiUrl: string = process.env.API_URL
console.log(apiUrl)
dotenv+DefinePluginの組み合わせが必要- 公開する変数を明示的に列挙する必要がある
4-3. CSS Modules の利用
Vite
/* src/Button.module.css */
.primary {
background-color: #3b82f6;
color: white;
padding: 8px 16px;
border-radius: 4px;
}
// src/Button.tsx — 追加設定不要
import styles from './Button.module.css'
export const Button = ({ label }: { label: string }) => (
<button className={styles.primary}>{label}</button>
)
.module.css という命名規則だけで CSS Modules が有効になります。
webpack
// webpack.config.ts の rules に追加
{
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
},
],
},
// src/Button.tsx — コード自体は同じ
import styles from './Button.module.css'
export const Button = ({ label }: { label: string }) => (
<button className={styles.primary}>{label}</button>
)
webpack では css-loader の modules オプションを明示的に設定する必要があります。
4-4. プロキシ設定(開発時の API プロキシ)
Vite
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
})
webpack
// webpack.config.ts の devServer に追加
devServer: {
port: 3000,
hot: true,
proxy: [
{
context: ['/api'],
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
],
},
この部分は両者ともほぼ同等の設定量です(内部的にどちらも http-proxy を使用しています)。
5. どちらを選ぶべきか — ユースケース別の推奨
✅ Vite を選ぶべきケース
| ユースケース | 理由 |
|---|---|
| 新規の SPA / SSR プロジェクト | ゼロコンフィグに近い状態で最速の DX が得られる |
| Vue / Svelte / Astro を使う場合 | フレームワーク公式が Vite を前提としている |
| プロトタイピング・PoC | セットアップ時間がほぼゼロ |
| 中小規模のプロジェクト | 設定の複雑さに悩まされずに済む |
| ライブラリ開発 | vite build --lib でライブラリモードが使える |
| DX を最優先したいチーム | HMR の速さが開発効率に直結する |
✅ webpack を選ぶべきケース
| ユースケース | 理由 |
|---|---|
| 既存の大規模 webpack プロジェクト | 移行コストが高く、安定稼働しているなら無理に変えない |
| Module Federation が必要 | マイクロフロントエンドの成熟した実装は webpack が最有力 |
| 特殊なローダーに依存している | Vite/Rollup に対応するプラグインがない場合がある |
| **IE11 |