Pre-bundling은 Vite가 개발 서버 시작 시 node_modules의 의존성을 사전에 번들링하는 전략이다. esbuild를 사용하여 수행되며, 자동으로 투명하게 동작한다.
해당 개념이 필요한 이유
두 가지 핵심 문제를 해결한다:
1. CommonJS/UMD → ESM 변환
Vite의 개발 서버는 Native ESM으로 코드를 제공하므로, CommonJS나 UMD로 작성된 의존성을 ESM으로 변환해야 한다.
// React는 CommonJS로 배포됨
// Pre-bundling이 이것을 ESM으로 변환해줌
import React, { useState } from 'react'; // ← 이 문법이 동작하도록2. HTTP 요청 수 최적화
lodash-es의 경우:
import { debounce } from 'lodash-es';
내부적으로 lodash-es는 600개 이상의 개별 모듈로 구성됨
Pre-bundling 없이: 600+ HTTP 요청 발생 → 브라우저 네트워크 정체
Pre-bundling 후: 1개 HTTP 요청 → 즉시 로드
AS-IS (Pre-bundling 없이)
import { debounce } from 'lodash-es';
브라우저:
GET lodash-es/debounce.js
→ GET lodash-es/isObject.js
→ GET lodash-es/isSymbol.js
→ GET lodash-es/...
→ ... (600+ 요청이 폭포처럼 발생)
→ 네트워크 탭이 수백 개의 요청으로 가득 참
TO-BE (Pre-bundling 후)
import { debounce } from 'lodash-es';
Vite가 사전에:
[600+ 개별 모듈] → esbuild → [단일 ESM 파일]
브라우저:
GET /node_modules/.vite/deps/lodash-es.js?v=abc123
→ 단 1개 요청으로 완료
동작 방식
자동 발견
- Vite가 소스 코드를 크롤링하여 bare import 감지 (예:
import xx from 'react') - 이 import들을 pre-bundling 진입점으로 사용
- esbuild로 빠르게 번들링
- 서버 시작 후 새로운 의존성 발견 시 → 재번들링 + 리로드
캐싱 전략
파일 시스템 캐시 (node_modules/.vite):
- 다음 조건이 변경될 때만 재실행:
- lockfile (package-lock.json 등) 변경
- vite.config.js 관련 필드 변경
- NODE_ENV 값 변경
브라우저 캐시:
max-age=31536000,immutable헤더로 강력 캐싱- 패키지 버전이 변경되면 자동 무효화
강제 재번들링
vite --force # CLI 플래그
# 또는
rm -rf node_modules/.vite # 캐시 디렉토리 삭제커스터마이징
// vite.config.js
export default {
optimizeDeps: {
include: ['large-cjs-package'], // 강제로 pre-bundling에 포함
exclude: ['tiny-esm-package'], // pre-bundling에서 제외
}
}- include: 내부 모듈이 많은 패키지나 CommonJS 패키지를 명시적으로 포함
- exclude: 작고 유효한 ESM 패키지를 제외하여 브라우저가 직접 로드하게 함
Pre-bundling은 개발 모드에서만 동작한다. 프로덕션 빌드에서는
@rollup/plugin-commonjs가 같은 역할을 수행한다.