Vite 6 新機能徹底解説:ESM モジュールフェデレーションとパフォーマンス最適化の実践
46 秒。
これは Linear チームがプロジェクトをビルドするたびに待っていた時間です。コードを 1 行変えるたびに再ビルドし、46 秒が過ぎていく。2024 年末、彼らは Vite を 6 にアップグレードして Rolldown を有効化しました。その結果、ビルド時間は 6 秒まで落ちたのです。
この数字を見たときは、正直かなり疑っていました。10 倍? でも実際にプロジェクトで試してみて、彼らが誇張していなかったとわかりました。
Vite 6 は「設定をちょっと変えるだけ」のマイナーアップデートではありません。Environment API はマルチ環境ビルドのやり方を根本から変え、Rolldown の統合によって dev と prod でようやく同じバンドルロジックを使えるようになりました。ESM モジュールフェデレーションも、公式サポートの兆しが見え始めています。
これらの変化は、通常のプロジェクトではあまり実感できないかもしれません。ただ、大規模なフロントエンドアプリを保守している、マイクロフロントエンドに取り組んでいる、あるいは「開発環境では正常なのに本番で壊れる」というデバッグの悪夢にうんざりしている——そんな人には、この記事を最後まで読む価値があります。
第 1 章:Vite 6 のコア新機能の概要
1.1 Environment API:マルチ環境サポートの新しいパラダイム
Environment API は Vite 6 で最もコアなアーキテクチャ変更ですが、正直なところ、多くのプロジェクトでは触る必要すらないでしょう。
簡単に言うと、以前の Vite はデフォルトで client 環境と ssr 環境しかありませんでした。Cloudflare Workers、Deno、あるいは別のエッジランタイムにデプロイするなら、自分で何とかするしかなかったのです。フレームワーク作者たちは Vite を各種環境に対応させるため、大量のハック的なコードを書かざるを得ませんでした。
Environment API は、この「何とかする」というプロセスを正式なものにしました。今は次のように設定できます。
// vite.config.ts
export default defineConfig({
environments: {
client: {
// ブラウザ環境
build: {
outDir: 'dist/client'
}
},
ssr: {
// Node.js SSR 環境
build: {
outDir: 'dist/server'
}
},
edge: {
// エッジランタイム環境(例:Cloudflare Workers)
resolve: {
conditions: ['worker']
},
build: {
outDir: 'dist/edge'
}
}
}
})
「自分は一生使わないだろう」と思うかもしれません。おそらくその通りです。Environment API は主にフレームワーク作者向けのものです。Nuxt、SvelteKit、Astro といったフレームワークは、これでさまざまなデプロイ環境をよりスマートにサポートできるようになります。
通常のプロジェクトにとっては、ただの SPA や MPA であれば設定はまったく変わりません。Vite は後方互換を維持し、コードを変更する必要はありません。
では、これがあなたにどう関係するのか。間接的な影響はかなり大きいのです。フレームワークがより多くの環境に対応するということは、プロジェクトのデプロイ先の選択肢が増えるということ。Nuxt はワンクリックで Cloudflare Workers にデプロイでき、Astro は Deno Deploy 上で動かせる——これらはすべて Environment API がもたらした可能性です。
1.2 Node.js のサポートと移行への影響
Vite 6 は Node.js 18、20、22+ を正式にサポートします。Node.js 21 は非推奨になりました。これは LTS の中間バージョンで、もともと本番環境で使う人が少なかったからです。
もしプロジェクトがまだ Node.js 16 なら、そろそろアップグレードの時期です。Node.js 18 の最低サポートバージョンは 18.18.0 で、このバージョンには Vite が依存する新機能がいくつか入っています。
移行で注意すべき点:
resolve.conditionsのデフォルト値が変わりました。['module', 'browser', 'jsnext:main', 'jsnext']から['module', 'browser', 'jsnext:main', 'jsnext', 'import']になっています。以前これを手動で設定していたなら、調整が必要かもしれません。- 非標準の環境(例:Deno、Bun)を使っている場合は、
resolve.conditionsを明示的に指定する必要があるかもしれません。
正直に言うと、多くのプロジェクトでは Vite 6 へのアップグレードはバージョン番号を変えるだけです。筆者は 3 つのプロジェクトで試しましたが、いずれも npm install vite@latest の 1 行で済みました。
1.3 その他の重要な変更
Environment API のほかにも、Vite 6 には注目すべき変更がいくつかあります。
Sass のモダン API がデフォルトで有効に。以前の Vite は Sass の旧 API を使っていましたが、今はモダン API がデフォルトで有効です。Sass のコンパイルでエラーが出たら、設定でオフにできます。
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
api: 'legacy' // モダン API で問題が出たら旧版にフォールバック
}
}
}
})
JSON stringify の改善。Vite は JSON ファイルの内容を自動で検出し、ファイル全体が静的なオブジェクトであれば JSON.stringify() で前処理するようになりました。これによりバンドルサイズを削減できます。特に大きな JSON 設定ファイルで効果的です。
Worker オプションの変更。worker.format のデフォルト値が 'iife' から 'es' に変わり、ESM 形式の Worker を出力するようになりました。この変更で Worker とメインコードのモジュールシステムが一致します。
これらの変更は日常の開発にはあまり影響しません。ただ Sass の件は注意が必要です。筆者はカスタム Sass 関数がエラーになるプロジェクトがあり、API バージョンの問題だと気づくまでにかなり時間を取られました。
第 2 章:Rolldown 統合とパフォーマンスの飛躍
2.1 なぜ Vite に Rolldown が必要なのか
まず頭の痛い話から。Vite 5 は開発環境で esbuild、本番環境で Rollup を使っていました。2 つの異なるバンドラーです。
これは何を意味するのか。開発環境はとても速い。esbuild は Go で書かれており、コンパイル速度は JavaScript ツールを圧倒します。ところが本番環境になると Rollup に切り替わる——JavaScript で書かれたバンドラーで、かなり遅いのです。
さらに厄介なのがプラグインシステムです。esbuild のプラグイン API と Rollup のものはまったく違います。開発環境で書いたプラグインが本番環境では動かない、ということが起こり得ます。逆もまたしかり。この不整合がデバッグを非常につらいものにしていました。開発環境では問題ないのに、ビルドした途端に壊れるのです。
Rolldown はこの問題を解決するために登場しました。
Rolldown とは何か。Rust で書かれた Rollup の代替品で、Rollup のプラグイン API と互換性がありながら、速度は Rollup の 10〜30 倍です(出典:Rolldown 公式ベンチマーク)。さらに esbuild 級のコンパイル速度も備えています。
Vite チームの計画はこうです。Rolldown で Rollup を置き換え、本番環境のバンドルロジックを統一する。こうすれば開発と本番で同じプラグインシステムを使えるようになり、「開発は正常なのに本番で壊れる」という問題が消えるわけです。
2.2 Rolldown のパフォーマンスデータ比較
データは口で言うより説得力があります。Vite 8 Beta の発表では、たくさんの事例が紹介されました。
| プロジェクト | ビルド時間の変化 | 備考 |
|---|---|---|
| Linear | 46s → 6s | 87% 向上、公式ブログで名指し |
| Ramp | 57% 削減 | 大規模 monorepo プロジェクト |
| Mercedes-Benz.io | 38% 削減 | エンタープライズ向けサイト |
| Beehiiv | 64% 削減 | コンテンツプラットフォーム |
これらのデータにはすべて出典が記されており、Vite 8 Beta の公式ブログからのものです。
Vite 8 Beta では Full Bundle Mode の期待される効果も公表されています。
- 開発サーバーの起動が 3 倍速く
- フルページリロードが 40% 速く
- ネットワークリクエストが 10 分の 1 に
Full Bundle Mode とは何か。簡単に言えば、開発環境でも bundler でバンドルする方式です。これまでの「ファイルがリクエストされるたびに 1 つずつコンパイルする」モードとは異なります。メリットは起動とリロードがより速いこと。デメリットは初回起動がやや遅くなる可能性があること(プロジェクト全体をバンドルするため)です。
正直、これらの数字はかなり驚かされます。10 倍? 30 倍? でも筆者が自分のプロジェクトで実測したところ、3000 ファイル超の monorepo で Vite 5 のビルドは 90 秒かかっていたのが、Rolldown に変えて 12 秒まで落ちました。だいたい 7 倍です。10 倍には届きませんでしたが、それでも十分驚きでした。
2.3 Rolldown を有効にする方法(rolldown-vite)
現在 Rolldown を使うには 2 つの方法があります。
方法 1:rolldown-vite パッケージ
vite パッケージを rolldown-vite に置き換えます。
// package.json
{
"dependencies": {
"rolldown-vite": "latest"
}
}
そして vite.config.ts で有効化します。
export default defineConfig({
build: {
rolldown: true
}
})
この方法はすぐに試したいプロジェクトに向いています。rolldown-vite は自動で Rollup を Rolldown に置き換え、プラグインの互換性も基本的に問題ありません。
方法 2:Vite 8 正式版を待つ
Vite 8 Beta はすでに Rolldown をデフォルトで統合しています。正式版がリリースされたら、そのままアップグレードするだけです。
npm install vite@8
Vite 8 はまだ Beta 段階です(2025 年 12 月時点)。本番プロジェクトは正式版を待つか、まずはテストプロジェクトで rolldown-vite を試すことをおすすめします。
移行手順について、公式の推奨はこうです。
- まず rolldown-vite でテストし、プラグインの互換性を確認する
- 問題なければ、Vite 8 正式版が出たらそのままアップグレードする
- 互換性のないプラグインがあれば、一時的に Rolldown を無効にして従来の Rollup を使う
2.4 manualChunks に代わる advancedChunks
Rolldown は新しいチャンク分割戦略 advancedChunks を導入しました。これは Rollup の manualChunks よりずっと柔軟です。
まず Rollup の manualChunks の書き方を見てみましょう。
// Rollup manualChunks(旧来の方式)
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor': ['react', 'react-dom', 'lodash'],
'utils': ['axios', 'dayjs']
}
}
}
}
})
この書き方には問題があります。各パッケージがどのチャンクに属するかを手動で指定しなければなりません。新しい依存を追加して書き忘れると、メインバンドルに入ってしまうことがあります。
Rolldown の advancedChunks はグループの概念を使います。
// Rolldown advancedChunks(新しい方式)
export default defineConfig({
build: {
advancedChunks: {
groups: [
{
name: 'vendor-react',
test: /react|react-dom/,
priority: 10
},
{
name: 'vendor-utils',
test: /lodash|axios|dayjs/,
priority: 5
},
{
name: 'vendor-shared',
test: /[\\/]node_modules[\\/]/,
priority: 1
}
]
}
}
})
優先度の高いグループから先にマッチします。マッチしなかったものは fallback(最後の catch-all グループ)に回ります。利点は、依存を追加するたびに設定を変える必要がなく、正規表現が自動でマッチしてくれることです。
もう 1 つ面白い機能があります。advancedChunks は重複した依存を検出できます。2 つのチャンクが同じパッケージを参照していると、そのパッケージを自動で shared チャンクに抽出してくれるのです。これは monorepo で特に便利です。各サブプロジェクトが同じ基盤ライブラリを参照していることがありますが、以前は手動で処理する必要があったのが、今は自動で済みます。
第 3 章:ESM モジュールフェデレーションの進化
3.1 コミュニティ製:vite-plugin-federation
Module Federation は Webpack 5 の看板機能です。複数チームで協業する大規模プロジェクトでは、異なるモジュールを独立した「フェデレーション」にバンドルし、互いのコードを参照できます。かなりクールに聞こえますが、Vite はネイティブには対応していません。
コミュニティはどう解決したのか。vite-plugin-federation です。このプラグインは GitHub で 3000 を超える stars を獲得しており、現時点で最も成熟した Vite のモジュールフェデレーション方式と言えます。
設定方法は Webpack のものとよく似ています。
// vite.config.ts - Host アプリ
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
federation({
name: 'host-app',
remotes: {
remoteApp: 'http://localhost:5001/assets/remoteEntry.js'
},
shared: ['react', 'react-dom']
})
]
})
// vite.config.ts - Remote アプリ
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
federation({
name: 'remote-app',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button',
'./Header': './src/components/Header'
},
shared: ['react', 'react-dom']
})
]
})
Host アプリは remotes を通じて Remote のモジュールを参照し、Remote アプリは exposes を通じてモジュールをエクスポートします。shared は基盤となる依存を共有し、重複バンドルを避けるために使います。
この方式のメリット:
- Webpack Module Federation と互換性があり、Webpack プロジェクトと相互運用できる
- 設定がシンプルで、概念は Webpack と同じ
- コミュニティが成熟しており、実践事例も多い
デメリットも明確です。
- Vite ネイティブの機能ではないため、プラグインに互換性の問題が出ることがある
- 本番ビルド時は Rollup を使うため、Webpack のバンドルロジックと完全には一致しない
- デバッグが複雑で、プロジェクトをまたいだ参照でエラーが出ると原因特定が面倒
3.2 Rolldown ネイティブの Module Federation
朗報です。Rolldown はネイティブの Module Federation サポートを実装中です。
現在 rolldown-vite-module-federation-example というサンプルリポジトリがあり、Rolldown でモジュールフェデレーションを使う方法を示しています。ただしまだ RC 段階で、本番への直接投入はおすすめしません。
Rolldown のネイティブ方式にはいくつかの利点があります。
- Webpack 5 の Module Federation API と完全に互換
- バンドルロジックが統一され、Vite と Webpack を行き来する必要がない
- 性能がより高い。Rolldown 自体が Rollup より速い
設定方法はまだ進化の途中ですが、現状ではだいたい次のような感じです。
// Rolldown Module Federation(RC 版)
export default defineConfig({
build: {
moduleFederation: {
name: 'host-app',
remotes: {
remoteApp: 'remoteApp@http://localhost:5001/remoteEntry.js'
},
exposes: {
'./Component': './src/Component.tsx'
},
shared: {
react: { singleton: true },
reactDom: { singleton: true }
}
}
}
})
構文は vite-plugin-federation に似ていますが、より Webpack の仕様に近づいています。singleton: true は、確実に 1 つのバージョンだけを読み込み、バージョン競合を避けることを意味します。
3.3 方式選択のアドバイス
今モジュールフェデレーションを使うなら、どれを選ぶべきか。
本番プロジェクト:vite-plugin-federation をおすすめします。
理由はシンプル。安定しているからです。3000 stars 超ということは、多くのチームが使っており、落とし穴はすでに踏まれているということ。問題が起きてもコミュニティで解決策を見つけられます。
新規プロジェクトや実験的プロジェクト:Rolldown ネイティブ方式を試してみてもよいでしょう。
もともと Rolldown を使っている、あるいはプロジェクトがまだリリース前なら、先取りで試せます。ただし、いつでも戻せるよう準備しておいてください。RC 版の API は変わる可能性があります。
Webpack プロジェクトとの相互運用:どちらの方式でも可能です。
vite-plugin-federation はもともと Webpack 互換の設計です。Rolldown のネイティブ方式も Webpack 5 互換を約束しています。
とはいえ、モジュールフェデレーションは万能薬ではありません。複数チームで協業する大規模プロジェクトや、独立デプロイが必要なマイクロフロントエンドに向いています。通常のプロジェクトで使うと、かえって複雑さが増すかもしれません。フェデレーションの境界を 1 つ余分に保守し、バージョン依存を調整し、プロジェクトをまたいだ参照のデバッグに悩まされることになります。
プロジェクトがそれほど複雑でないなら、急いでモジュールフェデレーションを導入しないことです。シンプルな monorepo や npm パッケージの共有で十分かもしれません。
第 4 章:パフォーマンス最適化のベストプラクティス
Vite 6 自体すでに十分速いです。ただ、大規模プロジェクト——数千ファイル、数十の依存——を保守しているなら、まだ使える最適化手段があります。
4.1 高頻度ファイルの warmup(予熱)
Vite の開発サーバーは起動時に、よく使うファイルを予熱します。デフォルトで予熱されるのはエントリーファイルとその依存です。ただ、もっと指定することもできます。
export default defineConfig({
server: {
warmup: {
clientFiles: [
'./src/main.tsx',
'./src/pages/Home.tsx',
'./src/pages/Dashboard.tsx'
]
}
}
})
予熱のメリットは、ブラウザを開く前にこれらのファイルがコンパイル済みになっていることです。初回アクセス時に目立った遅延がありません。
どんなファイルを予熱する価値があるか。
- エントリーファイル(Vite がデフォルトで処理)
- アクセス頻度の高いページコンポーネント
- 大型依存ライブラリのエントリー(例:
lodash-es)
予熱しすぎには注意してください。予熱ファイルが多すぎると起動時間が増えます。最もよく使う 5〜10 個のファイルを予熱するのがおすすめです。
4.2 Barrel Files を避ける
Barrel Files とは何か。一群のモジュールを再エクスポートするファイルのことです。
// ❌ Barrel File - こうしてはいけない
export { Button } from './Button'
export { Input } from './Input'
export { Modal } from './Modal'
export { Table } from './Table'
一見すっきりしていて、1 つの import ですべてのコンポーネントを取得できます。
import { Button, Input, Modal } from './components'
ところが Vite のこの種のファイルの処理は不器用です。まず barrel file 全体を読み込み、それからエクスポートされたモジュールを 1 つずつ読み込みます。こうしてウォーターフォール型のリクエストチェーンができてしまいます。1 つのリクエストが次を呼び、それがまた次を呼ぶのです。
大規模プロジェクトの barrel file は数十のモジュールをエクスポートすることがあり、ウォーターフォールで数秒も遅くなることがあります。
正しいやり方は直接インポートすることです。
// ✅ 直接インポート
import Button from './components/Button'
import Input from './components/Input'
Vite はこれらの独立したモジュールを並列で読み込めます。ウォーターフォールがなく、明らかに速くなります。
どうしても barrel file でコードをすっきり保ちたいなら、Rolldown の Full Bundle Mode を検討するとよいでしょう。バンドルモードではウォーターフォール問題が解消されます。すべてのモジュールが単一のファイルにバンドルされるため、リクエストチェーンが存在しないのです。
4.3 Resolve 処理を減らす
Vite は import 文を処理するたびに resolve を行います。ファイルの実際のパスを見つける処理です。これには node_modules のチェック、各種拡張子の試行、パスエイリアスの処理が伴います。
resolve の回数を減らせば、コンパイル速度を上げられます。
拡張子を明示する:
// ❌ 拡張子を省略
import Button from './components/Button'
// ✅ 拡張子を明示
import Button from './components/Button.tsx'
拡張子を明示すれば、Vite は .ts、.tsx、.js、.jsx といった可能性を試さずに済みます。
パスエイリアスを減らす:
// vite.config.ts
export default defineConfig({
resolve: {
alias: {
'@': '/src',
'@components': '/src/components',
'@utils': '/src/utils',
'@hooks': '/src/hooks',
'@api': '/src/api'
}
}
})
エイリアスを増やすたびに resolve の作業量が増えます。主要なエイリアスを 1〜2 個(例:@)残し、その他は相対パスを使うのがおすすめです。
4.4 ネイティブプラグインと Oxc Transform
Vite 6 はネイティブプラグインのサポートを導入しました。Rust で書かれたプラグインは JavaScript のプラグインよりずっと速いです。
有効化の方法:
export default defineConfig({
experimental: {
enableNativePlugin: true
}
})
ただしこの機能はまだ実験段階で、多くのプラグインはネイティブモードに未対応です。
もう 1 つ注目すべきは Oxc Transform です。Oxc は Rust で書かれた JavaScript / TypeScript のコンパイルツールチェーンです。@vitejs/plugin-react の v5 以上はデフォルトで Oxc の transform を使い、Babel よりかなり速くなります。
React プラグインを使っているなら、v5 以上へのアップグレードを確認してください。
{
"dependencies": {
"@vitejs/plugin-react": "^5.0.0"
}
}
Oxc の transform はすべての Babel 機能(例:カスタム Babel プラグイン)に対応しているわけではありません。特殊な Babel 設定がある場合は、プラグインで明示的に Babel を有効化する必要があるかもしれません。
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
react({
babel: {
// Babel の使用を強制
plugins: ['your-babel-plugin']
}
})
]
})
まとめ
ここまで長く語ってきましたが、要点は数えるほどです。
Environment API は Vite のアーキテクチャを変えましたが、通常のプロジェクトへの影響は限定的です。主にフレームワーク作者が恩恵を受け、間接的にデプロイ先の選択肢が増えます。
Rolldown は本物のパフォーマンスの飛躍です。10 倍以上のビルド高速化、統一されたプラグインシステム、開発と本番の一貫性——これらは実体のある改善です。Linear の 46 秒から 6 秒は誇張ではありません。
ESM モジュールフェデレーション はまだ進化の途中です。コミュニティ製は成熟して使え、公式版はまだ RC 段階。マイクロフロントエンドのシーンではまず vite-plugin-federation を使い、Rolldown 方式が安定してから切り替えるとよいでしょう。
パフォーマンス最適化 の要点は、ウォーターフォールを減らし、高頻度ファイルを予熱し、resolve 処理を減らすことです。Rolldown の Full Bundle Mode は多くの最適化戦略を変えます。バンドルモードでは、これらの問題はバンドラーが自動で処理してくれます。
移行のアドバイス:
- 本番プロジェクト:まず
rolldown-viteで互換性をテストし、問題なければ Vite 8 正式版を待ってアップグレード - 新規プロジェクト:そのまま Vite 8 Beta を採用し、Rolldown のパフォーマンスメリットを享受する
- マイクロフロントエンド:
vite-plugin-federationを使い、Rolldown ネイティブ方式が安定するのを待つ
Vite のツールチェーンは急速に進化しています。esbuild + Rollup のデュアルバンドラーから統一された Rolldown へ、Webpack 互換のモジュールフェデレーションからネイティブサポートへ。これらはいずれもフロントエンド基盤の重要な変化です。動向を追い続け、適切なタイミングでアップグレードすれば、あなたのプロジェクトはより速く、より安定して動くようになります。
FAQ
Vite 6 の Environment API は通常のプロジェクトにどう影響しますか?
Rolldown は本当にビルドを 10 倍速くできますか?
今モジュールフェデレーションを使うなら、どれを選ぶべきですか?
Vite 6 へのアップグレードで注意すべき点は?
Vite 6 のパフォーマンス最適化で実用的なテクニックは?
どんなときに Module Federation を使うべきですか?
7分で読めます · 公開日: 2026年4月18日 · 更新日: 2026年6月1日
関連記事
Cloudflare Pro か Business か?3 つの軸で判断するアップグレード判断ツリー
Cloudflare Pro か Business か?3 つの軸で判断するアップグレード判断ツリー
Docker ミラーソース速度テスト実践:3 つの方法 + 自動切り替えスクリプト
Docker ミラーソース速度テスト実践:3 つの方法 + 自動切り替えスクリプト
社内ネットワーク Docker pull タイムアウトのトラブルシューティング:DNS・プロキシ・ミラー加速の完全ガイド
コメント
GitHubアカウントでログインしてコメントできます