Back

バンドラーもリンターも全部Rustに置き換わりつつある件

最近のフロントエンド界隈、Rustの話題ばかりですよね。バンドラー、リンター、トランスパイラー、ミニファイア——毎日使っているツールが次々とRustで書き直されています。

「ちょっと速い」程度じゃないんです。10倍から100倍。

Rolldownが1.0 RCに到達して、Vite 8ベータのデフォルトバンドラーになりました。Oxlintはすでにeslintの50〜100倍高速。Rspack 2.0プレビューも今月出ます。

まだWebpackやBabel使ってるなら、そろそろ本気で検討したほうがいいかもしれません。


そもそもなぜRustなのか

JSで作ったビルドツールが遅いのは構造的な問題

考えてみれば当然なんですよね。JavaScriptはブラウザで動かすために作られた言語で、それでCPUをゴリゴリ使うコンパイル処理をやっている。遅くて当たり前です。

npm run build を叩くと内部で何が起きているかというと:

  1. BabelがコードをASTにパース→変換→シリアライズ
  2. ESLintが同じコードをまたパース→ルールチェック
  3. Webpack/Rollupがまたまたパース→モジュール解決→バンドル
  4. Terserが出力結果をまたまたまたパース→圧縮

同じコードを4回以上、バラバラのAST形式で、全部シングルスレッドで、GCに邪魔されながら。冷静に考えると、おかしな構造ですよね。

Rustは何を解決するのか

問題JavaScriptRust
速度JITコンパイル、V8のオーバーヘッドネイティブバイナリ、ゼロコスト抽象化
メモリGCがいつ止まるか分からない所有権モデルでGC自体がない
並列処理Worker threadでも直列化コストあり本物のマルチスレッド
パースツールごとに別々のASTAST一つを全ツールで共有

結果:ビルド30秒→2秒。リント10秒→0.1秒。合成ベンチマークじゃなくて実測値です。


いま誰が何を作っているのか

┌─────────────────────────────────────────────────────────────┐
│                     VoidZero (Evan You)                       │
│               Rust製 統合JSツールチェイン                      │
│                                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────────┐ │
│  │   Vite   │  │ Rolldown │  │   Oxc    │  │   Vitest    │ │
│  │ 開発サーバ│  │ バンドラー│  │パーサー  │  │テストランナー│ │
│  │          │  │          │  │リンター  │  │             │ │
│  │          │  │          │  │ミニファイア│  │             │ │
│  └──────────┘  └──────────┘  └──────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────┘

┌──────────────────────┐  ┌──────────────────────┐
│  Rspack (ByteDance)  │  │  Biome (コミュニティ)  │
│  Webpack互換バンドラー │  │  フォーマッター+リンター│
└──────────────────────┘  └──────────────────────┘

この流れの中心にいるのがVoidZero。Vue.jsとViteの生みの親Evan Youが設立した会社です。発想はシンプルで、「なんでツールごとにコードをパースし直すの?一回でよくない?」というもの。


Rolldown — Viteのバンドラーがやっと一本化されます

どういうツール?

Viteで使っていたesbuild(開発用)とRollup(本番用)を、Rust製バンドラー1つで置き換えるプロジェクトです。今年1月に1.0 RCがリリースされ、API安定しました。

なぜこれが大きいのか

Viteユーザーなら分かると思いますが、今まで開発サーバはesbuild、本番ビルドはRollupという二刀流でした。これが地味に面倒で:

  • プラグインを両方に対応させないといけない
  • 開発では動くのに本番ビルドでコケることがある
  • どっちが原因か追うのがだるい

Rolldown一本になれば、この問題がまるごとなくなります。

どれくらい速いの?

Rolldownチーム公式のベンチマーク:

Reactアプリ(JSX 10,000コンポーネント):
  Rollup 14.0秒 → Rolldown 3.7秒(3.8倍)

GitLabモノレポ:
  Webpack 45.2秒 → Rolldown 12.1秒(3.7倍)

Excalidraw:
  Webpack 24.6秒 → Rolldown 1.5秒(16.4倍)

試すには

Vite使ってるなら、ほぼ何もしなくていいです:

npm install vite@next # これだけ。Rolldownがデフォルトバンドラーになります。

単体でも使えます:

// rolldown.config.js import { defineConfig } from 'rolldown'; export default defineConfig({ input: './src/index.ts', output: { dir: 'dist', format: 'esm', sourcemap: true }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }, });

プラグインAPIはRollup互換なので、既存のプラグインもほぼそのまま動きます:

import { defineConfig } from 'rolldown'; import react from '@vitejs/plugin-react'; export default defineConfig({ input: './src/main.tsx', plugins: [react()], output: { dir: 'dist', format: 'esm' }, });

Oxc — パーサー、リンター、トランスフォーマー、ミニファイアを一体化

VoidZeroスタックで一番野心的なプロジェクトです。単体ツールではなく、言語ツールチェインまるごと:

  • パーサー:SWCの3倍高速
  • リンター(Oxlint):ESLintの50〜100倍高速
  • トランスフォーマー:Babelの40倍高速
  • ミニファイア:Terser級の圧縮率をネイティブ速度で

ポイントはASTを一度だけ作って使い回すこと。今までツールごとにAST作り直してた無駄を全部なくしたわけです。

Oxlint、本当にESLintの代わりになる?

まず数字を見てください:

TypeScriptプロジェクト(2,000ファイル):
  ESLint 9: 12.4秒 → Oxlint: 0.13秒(95倍)
  メモリ:ESLint ~450MB → Oxlint ~28MB(16倍少ない)

打ち間違いじゃないです。12秒 vs 0.13秒。

npm install -D oxlint npx oxlint .

ESLintを消さずに併用もできます:

{ "scripts": { "lint": "oxlint . && eslint .", "lint:fast": "oxlint ." } }

よくあるルールはOxlintに任せて、ESLintはカスタムプラグインが必要なルールだけ残すのがおすすめです。


Rspack — Webpack設定をそのまま活かしたい場合

RolldownがVite系の選択肢なら、Rspackはwebpack.config.jsをほぼそのまま使って高速化する方向です。ByteDance製で、5年分のWebpack設定が蓄積されたチームに向いています。

正直な話、本番でWebpackを使っているアプリは今でも膨大にあります。全部Viteに作り直すのが現実的じゃないチームも多い。Rspackはそういうチームのためのツールです。

どれくらい速いの?

ByteDance社内プロジェクト:
  Webpack 5: 120秒 → Rspack 1.7: 36秒(コールドビルド70%短縮)
  HMR:8.2秒 → 1.6秒(80%短縮)

試すには

// rspack.config.js — webpack.config.jsとほぼ同じですよね const { defineConfig } = require('@rspack/cli'); module.exports = defineConfig({ entry: './src/index.tsx', output: { path: __dirname + '/dist', filename: '[name].[contenthash].js', }, module: { rules: [ { test: /\.tsx?$/, use: { loader: 'builtin:swc-loader', // babel-loaderの代わりに組み込みSWC options: { jsc: { parser: { syntax: 'typescript', tsx: true }, transform: { react: { runtime: 'automatic' } }, }, }, }, }, { test: /\.css$/, type: 'css' }, ], }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }, optimization: { splitChunks: { chunks: 'all' } }, });

Rspack 2.0プレビュー(2月中)

  • 永続キャッシュ:ビルド間でキャッシュを保持
  • Module Federation 2.0:マイクロフロントエンド強化
  • ツリーシェイキング改善:Rolldownレベルに近づく
  • Oxc統合:パースと変換をOxcで処理

結局どれを選べばいいのか

状況別おすすめ

今使っているもの               →    移行先
────────────────────────────────────────────────
Webpack + Babel + ESLint      →    Rspack + Oxlint(設定ほぼそのまま)
                              →    Vite 8 + Rolldown(構成変更できるなら)
Vite + Rollup + ESLint       →    Vite 8 + Rolldown + Oxlint(アプグレのみ)
esbuild単体構成               →    Rolldown
Create React App             →    Vite 8(CRAはそろそろ卒業を)

機能比較

RolldownRspackesbuildWebpack
コールドビルド⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
HMR⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
プラグイン⭐⭐⭐⭐(Rollup互換)⭐⭐⭐⭐⭐(Webpack互換)⭐⭐⭐⭐⭐⭐⭐
ツリーシェイキング⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
今使えるかRC1.7安定安定安定

移行はこの順番で

ステップ1:リンターから(一番安全で効果が大きい)

npm install -D oxlint
{ "scripts": { "lint": "oxlint . && eslint .", "lint:ci": "oxlint ." } }

既存コードに触らずCIに追加するだけ。リスクゼロです。

ステップ2:バンドラーの入れ替え

Viteなら:

npm install vite@next npm run build && npm run preview # ステージングで確認

Webpackなら:

npm install -D @rspack/core @rspack/cli # webpack.config.js → rspack.config.js にリネーム # babel-loader → builtin:swc-loader に差し替え npx rspack build

ステップ3:数値で確認

移行前後のビルド時間は必ず記録しておきましょう:

// build-benchmark.mjs import { performance } from 'perf_hooks'; import { execSync } from 'child_process'; const runs = 5; const times = []; for (let i = 0; i < runs; i++) { execSync('rm -rf dist .cache node_modules/.cache'); const start = performance.now(); execSync('npm run build', { stdio: 'pipe' }); times.push(performance.now() - start); } const avg = times.reduce((a, b) => a + b) / times.length; console.log(`平均: ${(avg / 1000).toFixed(2)}s`);

移行時の注意点

プラグイン互換性

まだRust版がないWebpackローダーもあります:

  • sass-loader → Rspack組み込みsassサポートかbuiltin:lightningcss-loaderで代替
  • 社内製Babelプラグイン → 書き直しが必要なケースあり

バンドル出力の違い

微妙に異なる場合があるので、サイズと動作確認は必ずやりましょう。

CIキャッシュ

ツールが変わればキャッシュキーも更新が必要です:

- uses: actions/cache@v4 with: path: | node_modules/.cache .rspack-cache key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}

今後のスケジュール

いま(2026 Q1)

  • ✅ Rolldown 1.0 RC
  • ✅ Vite 8ベータにRolldownデフォルト搭載
  • 🔜 Rspack 2.0プレビュー

2026 Q2

  • Rolldown 1.0正式リリース予定
  • OxlintのルールがESLintコアレベルまで拡充

2026下半期

  • VoidZeroフルスタック統合(Vite + Rolldown + Oxc + Vitest)
  • TypeScript対応バンドリング(tscステップ不要に)

最終的には vite build 一発でパース→リント→変換→バンドル→ミニファイ→テスト。ASTひとつ、ワンパス、無駄ゼロ。


まとめ

JSビルドツールのRust化は、一時的な流行じゃなくて構造的な転換です:

  • ビルド速度:4〜16倍
  • リント速度:50〜100倍
  • メモリ使用量:1/10〜1/16

今日からやれること:

  1. 今日:Oxlintを入れてみる(2分で完了)
  2. 今週:Viteならvite@nextにアップグレード
  3. 今月:Webpackならサイドプロジェクトでrspackを試す
  4. 今四半期:チームで移行ロードマップを策定

WebpackもBabelもすぐには消えません。でもパフォーマンス差が圧倒的すぎて、現状維持はCI費用が余計にかかるし、開発ループも遅くなる。同じ時間でもっと作れるのに、変えない理由がないんですよね。

タイミングは今です。

RustJavaScriptViteRolldownOxcRspackBuild ToolsWeb DevelopmentPerformance

関連ツールを見る

Pockitの無料開発者ツールを試してみましょう