3월 12일에 Vite 8이 정식 릴리스됐다. 이번 메이저 업데이트의 핵심은 단 하나, Rolldown이다. esbuild와 Rollup을 동시에 대체하는 Rust 기반 번들러가 디폴트 옵션으로 탑재됐다. 사내 프로젝트에 바로 올려봤고, 결론부터 말하면 돌아갈 생각이 없다.

왜 이중 번들러 체제가 문제였나

Vite를 써본 사람이라면 이 구조의 불편함을 한 번쯤 겪었을 것이다. 개발 서버에선 esbuild가 코드를 트랜스파일하고, 프로덕션 빌드에선 Rollup이 번들링을 담당한다. 같은 소스코드를 두 개의 서로 다른 도구가 각자의 방식으로 처리하는 셈이다. "개발 환경에선 잘 되는데 빌드에서 터진다" — 이 말이 Vite 이슈 트래커에 얼마나 자주 올라왔는지 모른다. 특히 CommonJS와 ESM 경계에서 default import의 동작이 esbuild와 Rollup에서 달랐는데, 이걸 디버깅할 때마다 혈압이 올랐다.

Rolldown은 이 구조적 모순을 원천적으로 없앤다. 하나의 번들러가 개발 서버와 프로덕션 빌드를 모두 커버하니까 환경 간 동작 차이 자체가 소멸한다. Rust로 작성된 이 도구는 Rollup의 플러그인 API를 거의 그대로 물려받으면서도 속도는 esbuild에 견줄 만하다. 구조적 일관성과 속도, 두 마리를 한 번에 잡은 거다.

벤치마크: 25배라는 숫자

공식 벤치마크부터 보자. 19,000개 모듈 기준으로 Rolldown은 1.61초 만에 번들링을 끝냈고, 같은 조건에서 Rollup은 40.10초가 걸렸다. 25배 차이다.

합성 테스트 수치라 실무와 1:1로 대응되진 않는다. 그래서 실제 프로덕션 마이그레이션 사례를 모아봤다.

이전 빌드 시간 이후 빌드 시간 개선율
Linear 46초 6초 87%
Mercedes-Benz.io 미공개 미공개 38%
Beehiiv 미공개 미공개 64%

Linear의 46초에서 6초라는 수치는 처음 봤을 때 솔직히 의심부터 했다. 다만 모듈 수가 수천 단위를 넘어가는 대형 코드베이스에서는 Rolldown의 멀티스레드 병렬 처리가 극대화된다는 점을 감안하면 이해가 된다. 우리 팀 프로젝트는 모듈이 약 800개 정도인데, 그래도 22초에서 8초로 줄었다. CI에서 빌드 끝나길 기다리며 커피 한 모금 마시던 시간이 사라졌다. 이런 소소한 체감이 일상적인 DX를 확 바꿔놓는다.

다만 esbuild와의 직접 비교에서는 기대만큼 큰 차이가 나지 않는다. 500개 모듈 이상 구간에서 양쪽의 성능 격차는 10에서 15퍼센트 정도다. Rolldown이 esbuild를 압도하는 게 아니라, Rollup을 대체하면서 esbuild 수준의 성능을 확보했다는 게 정확한 표현이다. 이 미묘한 차이를 혼동하는 글이 제법 돌아다니더라.

마이그레이션은 순탄한데, CJS가 문제

대부분의 Vite 플러그인은 수정 없이 그대로 동작한다. 호환 레이어가 기존 rollupOptionsesbuild 설정을 Rolldown과 Oxc 등가 설정으로 자동 변환해주기 때문이다. 플러그인 생태계 호환성 면에서는 걱정할 게 거의 없다.

진짜 지뢰는 CommonJS 패키지 쪽에 묻혀 있다.

import dayjs from 'dayjs';

dayjs처럼 CJS로 배포된 패키지를 default import로 가져오면, Rolldown 환경에서 dayjs.default를 참조하게 되는 경우가 발생한다. 기존에 esbuild가 자동으로 해주던 CJS→ESM 변환 동작이 미묘하게 달라진 거다. 임시로 legacy.inconsistentCjsInterop: true를 설정하면 이전 동작을 복원할 수 있지만 이건 deprecated 옵션이다. 장기적으로는 해당 패키지가 ESM 빌드를 제공하기를 기다리거나, named import 방식으로 코드를 전환해야 한다.

Oxc — Rolldown이 내부적으로 사용하는 파서 겸 minifier — 도 Rollup의 모든 옵션을 지원하지는 않는다. mangleProps를 비롯한 프로퍼티 난독화 관련 옵션이 대표적이다. 프로퍼티 맹글링을 적극 활용하던 프로젝트라면 terser 같은 별도 minifier를 체인에 추가해야 한다.

Full Bundle Mode가 빌드보다 더 기대되는 이유

프로덕션 빌드 속도 개선도 물론 반갑다. 근데 개인적으로 더 눈이 가는 건 아직 실험 단계인 Full Bundle Mode다. Vite의 unbundled 개발 서버는 각 모듈을 개별 HTTP 요청으로 서빙한다. 소규모 프로젝트에선 빠르지만, 모듈이 수천 개를 넘는 모노레포에서는 브라우저가 그 수천 건의 네트워크 요청을 동시에 소화해야 하는 병목이 생긴다. 새 탭 열 때마다 로딩 스피너가 한참 돌아가는 거, 해본 사람은 알 것이다.

Full Bundle Mode의 예비 측정치를 보면 — 개발 서버 기동 시간 3배 단축, 풀 리로드 속도 40퍼센트 향상, 네트워크 요청 수 10분의 1 감소다. 프로덕션 빌드 최적화보다 이쪽이 매일 반복되는 개발 루프에 더 직접적으로 영향을 줄 수 있다.

갈아탈 타이밍인가

Vite 7 위에서 운영 중이고 빌드 대기 시간에 불만이 있다면, 올릴 이유는 충분하다. CJS 의존성이 두꺼운 레거시 코드베이스라면 좀 더 신중하게 접근할 필요가 있는데, rolldown-vite 패키지를 쓰면 Vite 7 환경에서 Rolldown만 먼저 격리 테스트할 수 있다. 문제 없으면 Vite 8로 올리고, 문제가 있으면 하나씩 잡으면 된다. 마이그레이션 가이드가 잘 정리돼 있으니 그것부터 훑어보길 권한다.

빌드 도구에 이렇게 흥분한 건 webpack에서 처음 탈출했을 때 이후로 처음이다.