Vite 8 + Rolldown: 이중 번들러 통합으로 프로덕션 빌드 시간을 87% 단축한 원리
(Vite 8 Rolldown migration | build speed)
46초짜리 빌드가 6초로 줄었다는 말을 처음 들었을 때 솔직히 반신반의했습니다. 벤치마크 숫자는 늘 현실보다 좋으니까요. 그런데 Linear, GitLab, Ramp 같은 실제 프로덕션 코드베이스에서 속속 같은 결과가 나오기 시작했습니다. Linear의 경우 19,000개 모듈 규모의 코드베이스에서 46초 → 6초로 줄어든 것이 공개 사례입니다. 2026년 3월에 정식 출시된 Vite 8은 단순한 버전 업그레이드가 아닙니다. 빌드 파이프라인의 구조 자체를 바꿨고, 그 변화가 숫자로 고스란히 드러나고 있습니다.
이 글은 Vite를 이미 사용하고 있는 프론트엔드 개발자가 주요 독자입니다. 빌드 속도 문제에 관심 있는 분이라면 개념 섹션까지도 충분히 읽을 수 있습니다. 마이그레이션을 고민 중이거나 CI 빌드 비용이 부담되는 분들께 도움이 됩니다.
핵심 개념
이중 번들러 구조, 왜 문제였나
Vite 7까지의 구조를 간단히 그려보면 이렇습니다.
개발 서버 → esbuild (의존성 사전 번들) + Vite 자체 ESM 서버
프로덕션 빌드 → Rollup개발 중에는 esbuild가 node_modules를 미리 번들하고, 프로덕션 빌드는 Rollup이 담당했습니다. 두 도구는 동작 방식이 달라서 "개발에서는 멀쩡했는데 빌드하면 터진다"는 상황이 종종 생겼습니다. 저도 이런 상황을 실무에서 몇 번 겪었는데, 원인을 추적하다 보면 결국 esbuild와 Rollup의 트리 쉐이킹 동작 차이였던 경우가 꽤 있었습니다.
Vite 8은 이 두 역할을 Rolldown 하나로 통합했습니다. 속도뿐 아니라 오랜 구조적 약점이었던 dev/prod 번들러 불일치도 함께 해결됩니다.
Rolldown은 무엇인가
Rolldown은 Evan You(Vue.js 창시자)가 창립한 VoidZero가 Rust로 개발한 JavaScript/TypeScript 번들러입니다. Rollup과 호환되는 플러그인 API를 유지하면서 Rust 네이티브 속도를 구현합니다.
내부 파이프라인을 보면 파싱 → 트랜스파일 → 코드 최적화까지 전 과정을 Oxc가 처리합니다. Oxc는 단순한 컴파일러가 아니라 파서·린터·트랜스파일러·최소화기를 하나로 묶은 Rust 기반 툴킷입니다. CSS 최소화는 기존 esbuild에서 Lightning CSS(역시 Rust)로 교체됐습니다.
Rolldown 내부 파이프라인
──────────────────────────────────────
소스 코드 입력
└─▶ Oxc 파서 (AST 생성)
└─▶ Oxc 트랜스파일러 (TS/JSX → JS)
└─▶ Rolldown 링커 (청크 분할·트리 쉐이킹)
└─▶ Oxc 최소화기
└─▶ Lightning CSS (CSS 처리)
└─▶ 최종 번들 출력
──────────────────────────────────────VoidZero 팀이 Rolldown과 Oxc를 직접 개발하고, Vite 핵심 기여자 다수가 VoidZero 소속이라는 점이 중요합니다. 이전에는 esbuild, Rollup, Babel이 각각 별도 팀에 의해 운영됐고, 이 파편화된 구조가 통합과 최적화의 걸림돌이었습니다. Vite 8은 이 수직 통합 툴체인 전략의 가장 가시적인 결실입니다.
얼마나 빠른가
| 번들러 | 빌드 시간 | 비고 |
|---|---|---|
| Rolldown | 1.61초 | 공식 벤치마크, 19,000 모듈 기준 |
| Rollup | 40.10초 | 동일 조건 |
| 개선 배율 | 약 25배 |
기업 실측 사례도 비슷한 추세입니다.
| 기업 | 이전 | 이후 | 개선율 |
|---|---|---|---|
| Linear | 46초 | 6초 | 87% 단축 |
| GitLab | 2분 30초 | 22초 | ~85% 단축 |
| Ramp | — | — | 57% 단축 |
| Beehiiv | — | — | 64% 단축 |
수치마다 측정 조건이 다르니 직접 비교는 어렵지만, 규모 있는 코드베이스일수록 효과가 두드러진다는 공통점은 분명합니다.
실전 적용
예시 1: Vite 7 상태에서 Rolldown 먼저 검증하기
Vite 8로 바로 올리기 부담스럽다면 rolldown-vite 패키지를 통해 Vite 7 설정을 유지하면서 Rolldown 번들러만 먼저 테스트해볼 수 있습니다. 번들러 이슈가 생겼을 때 Vite API 변경 탓인지 Rolldown 탓인지 헷갈리지 않으려면 이 단계를 거치는 것이 훨씬 편합니다. 저도 처음에 이 단계를 건너뛰었다가 플러그인 이슈와 번들러 이슈가 뒤섞여서 꽤 고생했습니다.
가장 간단한 방법은 vite를 rolldown-vite로 alias 처리하는 것입니다.
# 가장 간단한 방법: alias 설치
pnpm add vite@npm:rolldown-vite조금 더 명시적으로 관리하고 싶다면 pnpm.overrides를 활용할 수 있습니다.
pnpm remove vite
pnpm add -D rolldown-vite// package.json
{
"devDependencies": {
"rolldown-vite": "^8.0.0"
},
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@*"
}
}
}이 상태로 pnpm build를 돌려보면 Rolldown이 번들러 역할을 하면서 Vite 7 설정이 그대로 유지됩니다. 빌드 결과물과 런타임에서 이상이 없다면 Vite 8 업그레이드로 넘어가는 것을 권장합니다.
예시 2: Vite 8 정식 업그레이드
Rolldown 검증이 끝났다면 Vite 8로 올리는 작업은 생각보다 간단합니다.
pnpm add -D vite@^8.0.0주요 변경 사항 중 가장 손이 많이 가는 건 설정 키 이름 변경입니다.
// vite.config.ts — Vite 7
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
})// vite.config.ts — Vite 8
export default defineConfig({
build: {
rolldownOptions: { // ← rollupOptions에서 변경
output: {
advancedChunks: { // ← manualChunks보다 패턴 기반 매칭이 유연
groups: [
{ name: 'vendor', test: /node_modules/ },
{ name: 'ui', test: /src\/components/ },
],
},
},
},
},
})advancedChunks는 manualChunks보다 패턴 기반 매칭이 유연합니다. 수백 개의 청크를 관리하던 프로젝트에서는 설정 코드 자체가 줄어드는 효과도 있습니다.
| 변경 항목 | Vite 7 | Vite 8 | 비고 |
|---|---|---|---|
| 번들러 | esbuild + Rollup | Rolldown | 자동 전환 |
| CSS 최소화 | esbuild | Lightning CSS | 명시적 재설정 가능 |
| 청크 설정 키 | rollupOptions |
rolldownOptions |
자동 변환 지원 |
import.meta.hot.accept |
URL 전달 가능 | id로 변경 필요 | 수동 수정 |
제가 마이그레이션에서 가장 신경 썼던 건 CSS 최소화 출력 변경이었습니다. Lightning CSS와 esbuild의 CSS 처리 결과가 미묘하게 다를 수 있어서, 기존 동작을 유지하고 싶다면 아래처럼 명시적으로 설정할 수 있습니다.
// vite.config.ts — Lightning CSS 대신 esbuild CSS 최소화 유지
export default defineConfig({
css: {
transformer: 'postcss', // Lightning CSS 비활성화
},
build: {
cssMinify: 'esbuild',
},
})예시 3: Full Bundle Mode — dev/prod 불일치 원천 차단
Rolldown 통합 덕분에 새롭게 쓸 수 있게 된 기능 중 하나가 Full Bundle Mode입니다. 개발 서버에서도 Rolldown이 번들을 생성하도록 해서 dev/prod 결과물 간 불일치를 원천 차단할 수 있습니다.
// vite.config.ts — Full Bundle Mode 활성화
export default defineConfig({
dev: {
bundleMode: 'bundle', // 기본값: 'module' (기존 ESM 방식)
},
})공식 발표 기준으로 기존 ESM 방식 대비 네트워크 요청이 크게 감소합니다. 수천 개 모듈을 가진 모노레포에서 dev 서버 첫 화면 로딩이 체감상 빨라지는 것을 느낄 수 있습니다.
다만 몇 가지 특성 변화는 미리 알아두면 좋습니다. HMR 응답 방식이 ESM 개별 모듈 교체 방식과 달라지고, 첫 번들 생성 시 초기 빌드 부하가 약간 증가합니다. dev와 prod 결과를 최대한 일치시키고 싶은 팀에게 적합하고, 빠른 HMR 피드백 루프가 중요한 팀은 기본값(module)을 유지하는 것도 충분한 선택입니다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| 빌드 속도 | 공식 벤치마크(19,000 모듈) 기준 Rollup 대비 약 25배; Linear 사례(46초 → 6초) 기준 87% 단축 |
| 번들러 일관성 | dev/prod 동일 번들러 → 빌드 불일치 버그 구조적 제거 |
| 플러그인 호환성 | Rollup/Vite 플러그인 API와 거의 완전 호환, 생태계 충격 최소화 |
| HMR 개선 | 대형 프로젝트 dev 서버 시작 3배 빠름, 전체 리로드 40% 단축 |
| 신규 기능 | Module Federation, 모듈 수준 영속 캐시, 유연한 청크 분할(advancedChunks) |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| API 명칭 변경 | rollupOptions → rolldownOptions |
자동 변환 후 장기적으로 수동 업데이트 |
| Extglob 패턴 미지원 | 기존 rollupOptions에서 glob 확장 패턴을 쓰고 있었다면 Rolldown에서 조용히 실패할 수 있음 |
일반 정규식 패턴으로 대체 |
| TypeScript legacy namespace | 오래된 엔터프라이즈 코드베이스나 Angular 레거시처럼 namespace 문법을 광범위하게 쓰는 경우 부분적으로 영향 받을 수 있음 |
릴리즈 노트 확인 후 우회 패턴 적용 |
import.meta.hot.accept |
URL 전달 불가, id 기반으로 변경 필요 | id 기반으로 교체 |
| CSS 최소화 변경 | Lightning CSS 기본값 전환으로 출력이 미묘하게 달라질 수 있음 | 기존 동작 유지 시 명시적 설정 |
| 소규모 프로젝트 | 빌드가 이미 수 초 미만인 경우 체감 효과 제한적 | 속도보다 dev/prod 일관성 이점에 집중 |
Lightning CSS: Mozilla가 개발하고 Parcel 팀이 기여한 Rust 기반 CSS 파서/변환기/최소화기입니다. autoprefixer, CSS Modules, 최신 CSS 문법 다운레벨링을 하나의 도구로 처리합니다.
Module Federation: 여러 독립 빌드된 앱이 런타임에 서로의 모듈을 공유하는 마이크로 프론트엔드 기법입니다. Webpack 5에서 처음 주목받았고, Rolldown 1.0 stable에서 공식 지원이 추가됐습니다.
실무에서 가장 흔한 실수
저는 처음에 격리 단계를 건너뛰었다가 플러그인 이슈랑 번들러 이슈가 뒤섞여서 이틀을 날렸습니다. 그 경험을 바탕으로 자주 만나는 함정 세 가지를 정리해봤습니다.
rolldown-vite중간 단계를 건너뛰고 Vite 8 직행하기 — 번들러 이슈와 Vite API 변경 이슈가 뒤섞이면 원인 추적이 어려워집니다. 규모가 크거나 플러그인이 많은 프로젝트일수록 격리 단계가 빛을 발합니다.- CSS 최소화 출력 검증 없이 배포하기 — Lightning CSS와 esbuild의 CSS 처리 결과가 미묘하게 다를 수 있습니다.
pnpm build후 주요 페이지 스타일을 시각적으로 확인해보시면 좋습니다. - Extglob 패턴을
rolldownOptions에 그대로 옮기기 — 기존rollupOptions에서 glob 확장 패턴을 쓰고 있었다면 마이그레이션 전 패턴 목록을 점검해보시면 좋습니다. 지원되지 않는 패턴은 에러 없이 조용히 무시될 수 있습니다.
마치며
당신의 다음 PR이 CI 파이프라인에서 수십 초를 돌려줄 수 있습니다. Vite 8 + Rolldown의 진짜 의미는 속도 숫자 그 자체보다, 오랫동안 Vite의 구조적 약점이었던 이중 번들러 불일치를 제거하면서 동시에 극적인 성능 향상까지 이뤄냈다는 데 있습니다.
지금 바로 시작해볼 수 있는 3단계입니다.
- Rolldown 격리 테스트: 기존 프로젝트에서
pnpm add vite@npm:rolldown-vite로 번들러만 교체한 뒤pnpm build를 돌려봅니다. Vite 7 설정을 그대로 두고 빌드 결과와 속도만 먼저 비교해볼 수 있습니다. - Vite 8 업그레이드: 격리 테스트에서 이상이 없다면
pnpm add -D vite@^8.0.0으로 업그레이드한 뒤rollupOptions→rolldownOptions키 변경과import.meta.hot.accept코드를 점검합니다. - 빌드 시간 전후 비교: CI 파이프라인 로그에서 빌드 시간을 미리 기록해두고, 업그레이드 후 수치를 비교해봅니다. 미들~라지 규모 프로젝트에서 체감 가능한 차이가 납니다.
참고 자료
- Vite 8.0 is out! | vite.dev
- Vite 8 Beta: The Rolldown-powered Vite | vite.dev
- Vite 8.1 is out! | vite.dev
- Migration from v7 | vite.dev
- Announcing Rolldown 1.0 | voidzero.dev
- Announcing Rolldown-Vite | voidzero.dev
- Introduction | rolldown.rs
- Vite team claims 10-30x faster builds with Rolldown | The Register
- Vite Version 8: Unified Rust-Based Bundler and Up to 30x Faster Builds | InfoQ
- Testing out Vite 8 on SPA: Vite 8 is 5x faster | Peterbe.com
- Rust Is Eating the JavaScript Toolchain | DEV Community
- rolldown/rolldown | GitHub
- vitejs/rolldown-vite | GitHub