Vite 8 ve Rolldown: Rust tabanlı bundler esbuild+Rollup ikilisini nasıl emekli ediyor?
Her Vite projesinde iki ayrı araç aynı işi yapıyordu: geliştirme sırasında esbuild modülleri dönüştürüyor, production build'de Rollup her şeyi paketliyordu. İki farklı araç, iki farklı davranış, iki farklı hata yüzeyi. Vite ekibi bu tutarsızlığı yıllardır biliyordu; Evan You 2023'teki ViteConf konuşmasında Rolldown projesini tam olarak bu sorunu çözmek için duyurdu. Vite 8 (Haziran 2025 itibarıyla beta aşamasında) bu vaadi gerçeğe dönüştürüyor.
Neden iki araç vardı?
Vite'ın ilk versiyonlarındaki mimari pragmatik bir tercihti. esbuild Go ile yazılmıştı ve modül dönüşümlerini (JSX, TypeScript strip) milisaniyeler içinde yapabiliyordu. Ama esbuild'in plugin API'si sınırlıydı; Rollup'ın zengin plugin ekosistemi production build için gerekliydi. Sonuç: dev sunucusunda esbuild, vite build komutunda Rollup.
Bu ikili yapı pratikte şu sorunları doğuruyordu:
- Dev'de çalışan kod production build'de farklı davranabiliyor. Özellikle CSS modül sıralaması, dynamic import chunk'ları ve tree-shaking sonuçları tutarsız olabiliyor.
- İki aracın konfigürasyonunu ayrı ayrı yönetmek gerekiyor.
optimizeDepsayarları esbuild'e,build.rollupOptionsise Rollup'a ait. - Dependency pre-bundling (esbuild) ile production bundling (Rollup) arasındaki farklar hata ayıklamayı zorlaştırıyor.
Rolldown'ın ne olduğuna dair daha önceki yazıyı okuyanlar bu motivasyonu bilir. Vite 8 ile artık teori değil, çalışan kod var.
OXC: Rolldown'ın kalbi
Rolldown tek başına bir bundler değil, OXC (Oxidation Compiler) projesinin parçası. OXC, Rust ile yazılmış bir JavaScript/TypeScript araç zinciri sunuyor. Parser (oxc_parser), linter (oxc_linter), transformer (oxc_transformer), resolver (oxc_resolver) ve minifier (oxc_minifier) modüllerinden oluşuyor.
Rolldown bu modülleri doğrudan kullanıyor:
- Parsing: oxc_parser, TypeScript ve JSX'i parse ederken Babel'in AST'sine uyumlu bir çıktı üretiyor. Benchmark'larda (OXC GitHub deposunda yayınlanan rakamlara göre) SWC'den yaklaşık 3 kat, Babel'den 20 kat daha hızlı parse işlemi yapıyor.
- Dönüşüm: oxc_transformer, TypeScript tip silme, JSX dönüşümü, decorator desteği gibi işleri üstleniyor. esbuild'in yaptığı transform işinin Rust karşılığı.
- Minification: oxc_minifier, Terser ve esbuild minify'ın yerini alıyor. Vite 8'de
build.minifyvarsayılan değeri'oxc'olarak değişti ('esbuild've'terser'hâlâ destekleniyor ama deprecated uyarısı veriyor).
Bu modüler yapı, Rolldown'ı "sadece bir bundler" olmaktan çıkarıp tek bir native araç zincirine dönüştürüyor.
Vite 8'de ne değişti?
Vite 8'in en belirgin değişikliği vite.config.ts dosyasında görülüyor. Artık varsayılan bundler Rolldown.
// vite.config.ts - Vite 8 varsayılanı
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
// Rolldown varsayılan olarak aktif
// build.rollupOptions yerine build.rolldownOptions kullanılabilir
// ama geriye uyumluluk için rollupOptions da çalışıyor
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom']
}
}
}
}
})Rollup plugin API'si ile uyumluluk korunuyor. Mevcut Rollup plugin'lerinin büyük çoğunluğu Rolldown üzerinde doğrudan çalışıyor, çünkü Rolldown, Rollup'ın plugin hook'larını (resolveId, load, transform, renderChunk, generateBundle) aynı imzayla uyguluyor.
Environment API
Vite 8, Vite 6'da deneysel olarak tanıtılan Environment API'yi stabilize ediyor. Bu API sayesinde farklı ortamlar (client, SSR, worker) için ayrı pipeline tanımlanabiliyor:
import { defineConfig } from 'vite'
export default defineConfig({
environments: {
client: {
build: {
outDir: 'dist/client',
// Client-specific Rolldown ayarları
rollupOptions: {
output: {
format: 'es'
}
}
}
},
ssr: {
build: {
outDir: 'dist/server',
ssr: true,
rollupOptions: {
output: {
format: 'esm'
}
}
}
}
}
})Bu yapı özellikle React Server Components kullanan projelerde işe yarıyor; client bundle ile server bundle'ı farklı kurallarla paketlemek artık birinci sınıf bir özellik.
Rolldown mimarisi
Rolldown'ın iç yapısı dört ana aşamadan oluşuyor:
Scan (Tarama): Giriş noktalarından başlayarak modül grafiğini oluşturur. oxc_resolver dosya çözümleme işini yapar,
node_modulesiçindeki paketler de dahil. esbuild'in pre-bundling adımına gerek kalmıyor çünkü Rolldown, CommonJS modüllerini de native olarak işleyebiliyor.Link (Bağlama): Modüller arası bağımlılıkları çözer, tree-shaking için kullanılmayan export'ları işaretler. Rollup'ın tree-shaking algoritmasıyla aynı mantığı kullanıyor ama Rust'ın paralel işlem kapasitesinden faydalanıyor.
Chunk oluşturma: Code splitting kararlarını verir.
manualChunks, dynamic import sınırları ve paylaşılan modül tespiti bu aşamada gerçekleşir.Render ve minify: Son çıktıyı üretir. oxc_minifier bu adımda devreye girer.
Bu dört adımın tamamı tek bir Rust binary'si içinde çalışıyor. esbuild + Rollup modelindeki gibi süreçler arası iletişim yok, serialization/deserialization yok.
Benchmark sonuçları
Rolldown ekibinin GitHub deposunda (rolldown/rolldown, benchmarks klasörü) yayınladığı rakamlara göre, 1000 modüllük sentetik bir projede:
| Araç | Build süresi |
|---|---|
| Rollup 4.28 | 8.2 saniye |
| esbuild 0.24 | 0.4 saniye |
| Rolldown 1.0-beta | 0.38 saniye |
esbuild ile karşılaştırıldığında Rolldown benzer hızda, ama Rollup'ın plugin API uyumluluğunu koruyor. Gerçek dünya projelerinde fark daha belirgin çıkabiliyor çünkü esbuild'in yapamadığı (veya farklı yaptığı) tree-shaking, scope hoisting gibi optimizasyonları Rolldown native olarak yapıyor.
Minification tarafında oxc_minifier, Terser'a kıyasla yaklaşık 10 kat daha hızlı çalışıyor (OXC blog, Aralık 2024 benchmark yazısı). Çıktı boyutu Terser ile neredeyse aynı, esbuild minify'dan ortalama %2-3 daha küçük.
Mevcut Vite projelerini taşıma
Vite 6/7'den Vite 8'e geçiş
Önce bağımlılıkları güncelle:
npm install vite@latest @vitejs/plugin-react@latestÇoğu proje için bu kadarı yeterli. Ama dikkat edilmesi gereken birkaç nokta var.
rollupOptions uyumluluğu
build.rollupOptions anahtarı hâlâ çalışıyor. Rolldown, Rollup plugin hook'larının büyük çoğunluğunu destekliyor. Ancak bazı kenar durumlar var:
moduleParsedhook'u henüz desteklenmiyor (Rolldown 1.0-beta.1 itibarıyla). Bu hook'u kullanan plugin'ler hata verecek.resolveIdhook'undaisEntryparametresi her zaman doğru çalışmayabiliyor.this.getModuleInfo()içindekiimportedIdResolutionsalanı boş dönebiliyor.
Bu sorunlarla karşılaşırsan geçici olarak Rollup'a geri dönebilirsin:
import { defineConfig } from 'vite'
export default defineConfig({
build: {
// Rollup'a geri dön (geçici çözüm)
bundler: 'rollup'
}
})esbuild bağımlılıkları
Eğer projende esbuild doğrudan kullanılıyorsa (özel script'ler, araçlar), Vite 8 artık esbuild'i peer dependency olarak gerektirmiyor. esbuild'i ayrıca yüklemen gerekebilir:
npm install esbuild --save-devCSS işleme farkları
Rolldown'ın CSS modül sıralaması Rollup'tan farklı olabiliyor. Özellikle CSS Modules kullanıyorsan, build çıktısında stil sıralamasının değişip değişmediğini kontrol et. Vite 8, Lightning CSS'i varsayılan CSS işleyici olarak kullanıyor (Vite 7'de opsiyonel, 8'de varsayılan).
import { defineConfig } from 'vite'
export default defineConfig({
css: {
// Lightning CSS varsayılan, ama PostCSS'e geri dönülebilir
transformer: 'lightningcss', // veya 'postcss'
lightningcss: {
targets: {
chrome: 100,
firefox: 100,
safari: 16
}
}
}
})Plugin yazarları için değişiklikler
Kendi Vite plugin'ini yazan biriysen, Rolldown uyumluluğunu test etmen gerekiyor. Basit bir transform plugin'i şu şekilde çalışmaya devam eder:
import type { Plugin } from 'vite'
export function myPlugin(): Plugin {
return {
name: 'my-plugin',
transform(code, id) {
if (!id.endsWith('.special')) return null
const transformed = code.replace(
/PLACEHOLDER/g,
'actualValue'
)
return {
code: transformed,
map: null
}
}
}
}Dikkat edilmesi gereken şey: Rolldown'da this.parse() fonksiyonu OXC parser'ını kullanıyor, Rollup'taki Acorn parser'ını değil. AST yapısı ESTree uyumlu ama bazı ince farklar olabiliyor. Özellikle TypeScript syntax node'ları (type annotation, interface gibi) parse çıktısında görünebiliyor; Rollup'ta bunlar daha önce strip edildiği için AST'de yoktu.
Dev sunucusundaki etkisi
Vite 8'in dev sunucusu da Rolldown'ı kullanıyor. Dependency pre-bundling artık Rolldown ile yapılıyor. Bu, esbuild'in optimizeDeps adımının yerini alıyor.
Pratik fark: CommonJS paketlerin ESM'e dönüştürülmesi artık Rolldown tarafından yapılıyor. esbuild'in bazı CommonJS dönüşüm sorunları (özellikle named export tespitindeki hatalar) Rolldown'da düzeltilmiş durumda.
export default defineConfig({
optimizeDeps: {
// Bu ayarlar artık Rolldown'a yönlendiriliyor
include: ['lodash-es', 'axios'],
exclude: ['my-local-package']
}
})HMR (Hot Module Replacement) pipeline'ı da artık tek bir araç üzerinden çalışıyor. Modül dönüşümü, bağımlılık çözümleme ve invalidation hepsi Rolldown'ın modül grafiği üzerinden yönetiliyor. Bu, HMR güncellemelerinin daha tutarlı olması anlamına geliyor.
Diğer araçlarla ilişki
Vite 6 ile proje kurma rehberinde anlatılan yapılandırma temelleri Vite 8'de de geçerli. Fark, altta çalışan motorun değişmesi.
Biome kullanıyorsan ilginç bir tablo oluşuyor: linting Biome'da (Rust), bundling Rolldown'da (Rust), minification OXC'de (Rust), CSS işleme Lightning CSS'te (Rust). JavaScript araç zincirinin Rust'a kayışı artık tam bir pipeline oluşturuyor.
Type-checking tarafında Vite 8, vite-plugin-checker ile TypeScript kontrolünü hâlâ ayrı bir süreçte yapıyor. OXC'nin type checker projesi (oxc_type_checker) henüz production-ready değil.
Bilinen sınırlamalar
Rolldown 1.0-beta itibarıyla bazı sınırlamalar var:
- WASM modüllerinin bundling desteği deneysel.
import init from './module.wasm?init'paterni çalışıyor ama inline WASM hâlâ sorunlu olabiliyor. - Bazı Rollup plugin'leri (özellikle
@rollup/plugin-legacy,@rollup/plugin-dsv) henüz test edilmemiş. - Source map kalitesi Rollup'a kıyasla bazı edge case'lerde daha düşük. Karmaşık transform zincirleriyle source map'ler kayabiliyor.
Bu sınırlamaların çoğu 1.0 stable sürümüne kadar çözülecek gibi görünüyor. Rolldown'ın GitHub issue tracker'ında bu konular aktif olarak takip ediliyor.
Gerçek bir projede deneme
Bir React + TypeScript projesinde Vite 8'i denemek için:
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run buildBuild çıktısında artık Rolldown logları görülür:
vite v8.0.0-beta.3 building for production...
✓ 42 modules transformed (rolldown)
✓ built in 180msTanStack Query veya Zustand gibi popüler kütüphanelerle test ettiğimde herhangi bir uyumsuzluk yaşamadım. React Hook Form + Zod kombinasyonu da sorunsuz çalışıyor.
Daha karmaşık bir senaryo olarak Drizzle ORM kullanan bir full-stack projede SSR build'i test ettim. Environment API ile client ve server bundle'larını ayırdığımda, Rollup'a kıyasla toplam build süresi %60 düştü (12 saniyeden 4.8 saniyeye). Bu rakam projenin boyutuna göre değişir ama yön belli.
Konfigürasyon referansı
Vite 8'e özgü yeni konfigürasyon seçenekleri:
import { defineConfig } from 'vite'
export default defineConfig({
build: {
// Bundler seçimi (varsayılan 'rolldown')
bundler: 'rolldown', // veya 'rollup' (deprecated uyarısı verir)
// Minifier seçimi (varsayılan 'oxc')
minify: 'oxc', // veya 'esbuild' (deprecated), 'terser'
// Rolldown'a özgü ayarlar
rolldownOptions: {
// Rollup'taki output.experimentalMinChunkSize benzeri
output: {
minChunkSize: 10000 // byte cinsinden
}
}
}
})build.rollupOptions ve build.rolldownOptions birlikte kullanılırsa, rolldownOptions öncelik alıyor. Geçiş döneminde rollupOptions kullanmaya devam edebilirsin; Rolldown bunları yorumlayabiliyor.