모노레포 라이브러리 번들러 7종 비교
React UI 컴포넌트 라이브러리를 대상으로 7가지 번들러를 비교한 결과를 공유합니다. 각 번들러의 빌드 시간과 번들 크기 그리고 설정 복잡도를 실측하여 라이브러리 번들링에 가장 적합한 도구를 찾아보았습니다.
테스트 환경
| 패키지 | React UI 컴포넌트 라이브러리 |
| Entry | src/index.ts |
| Output Format | ESM + CJS |
| External | React, MUI, Emotion, 내부 패키지들 |
빌드 결과 요약
번들 크기 비교
번들 크기는 최종 배포물의 용량에 직접적인 영향을 미칩니다. 작을수록 좋습니다.
| 번들러 | ESM | CJS | 총 크기 | 순위 |
|---|---|---|---|---|
| vite | 14 KB | 9 KB | 23 KB | 1위 |
| rollup | 17 KB | 18 KB | 35 KB | 2위 |
| tsup | 18 KB | 21 KB | 39 KB | 3위 |
| rolldown | 17 KB | 23 KB | 40 KB | 4위 |
| tsdown | 17 KB | 23 KB | 40 KB | 5위 |
| esbuild | 20 KB | 25 KB | 45 KB | 6위 |
| rspack | 52 KB | 57 KB | 109 KB | 7위 |
빌드 시간 비교
개발 생산성에 직접적인 영향을 미치는 빌드 시간입니다. 총 시간에는 tsc를 통한 DTS 생성 시간이 포함됩니다.
| 번들러 | 총 시간 | JS 빌드 | 순위 |
|---|---|---|---|
| esbuild | 1.58s | ~10ms | 1위 |
| tsdown | 1.84s | 853ms (DTS 포함) | 2위 |
| vite | 2.21s | 75ms | 3위 |
| rspack | 2.29s | 119ms | 4위 |
| rolldown | 2.37s | 18ms | 5위 |
| tsup | 2.88s | 113ms + 1.8s (DTS) | 6위 |
| rollup | 5.46s | 3.3s | 7위 |
📌 참고
tsup과 tsdown은 DTS(타입 선언 파일) 생성을 내장 지원합니다. 다른 번들러는 별도로 tsc를 실행해야 합니다.
번들러별 상세 비교
1. tsup
| 기반 기술 | esbuild |
| 설정 복잡도 | 매우 낮음 |
| DTS 생성 | 내장 지원 |
| ESM/CJS 동시 출력 | format: ['esm', 'cjs'] |
✅ 장점
- 설정이 가장 간단함
- DTS 생성 내장
- 라이브러리 번들링에 최적화
❌ 단점
- DTS 생성이 느림
// tsup.config.ts
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
external: ['react', '@mui/material'],
});
2. esbuild
| 기반 기술 | Go |
| 설정 복잡도 | 낮음 |
| DTS 생성 | 별도 tsc 필요 |
| ESM/CJS 동시 출력 | 2번 빌드 필요 |
✅ 장점
- 가장 빠른 빌드 속도
- 간단한 API
❌ 단점
- DTS 미지원
- ESM/CJS 각각 빌드 필요
// esbuild.config.mjs
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
format: 'esm',
external: ['react', '@mui/material/*'],
});
3. rollup
| 기반 기술 | JavaScript |
| 설정 복잡도 | 중간 |
| DTS 생성 | 플러그인 필요 |
| ESM/CJS 동시 출력 | Multi-config |
✅ 장점
- 작은 번들 크기
- 풍부한 플러그인 생태계
- 라이브러리 번들링의 표준
❌ 단점
- 빌드 속도가 느림
- 설정이 복잡함
// rollup.config.mjs
export default {
input: 'src/index.ts',
output: { format: 'esm' },
external: [/^react/, /^@mui\/material/],
plugins: [typescript(), resolve(), commonjs()],
};
4. vite (library mode)
| 기반 기술 | rollup (프로덕션) |
| 설정 복잡도 | 낮음 |
| DTS 생성 | 별도 설정 필요 |
| ESM/CJS 동시 출력 | formats: ['es', 'cjs'] |
✅ 장점
- 가장 작은 번들 크기
- 간단한 설정
- rollup의 장점 + 더 나은 DX
❌ 단점
- 라이브러리 모드 설정 필요
// vite.config.ts
export default defineConfig({
build: {
lib: {
entry: 'src/index.ts',
formats: ['es', 'cjs'],
},
rollupOptions: {
external: [/^react/, /^@mui\/material/],
},
},
});
5. rspack
| 기반 기술 | Rust (webpack 호환) |
| 설정 복잡도 | 높음 |
| DTS 생성 | 별도 tsc 필요 |
| ESM/CJS 동시 출력 | Multi-config |
✅ 장점
- 빠른 빌드 속도
- webpack 플러그인 호환
❌ 단점
- 가장 큰 번들 크기 (런타임 코드 포함)
- 라이브러리 번들링에 최적화되지 않음
// rspack.config.ts
export default defineConfig({
entry: { index: './src/index.ts' },
output: { library: { type: 'module' } },
externals: [/^react/, /^@mui\/material/],
});
6. rolldown
| 기반 기술 | Rust (rollup 호환) |
| 설정 복잡도 | 낮음 |
| DTS 생성 | 별도 tsc 필요 |
| ESM/CJS 동시 출력 | Multi-config |
✅ 장점
- 매우 빠른 JS 빌드 (18ms)
- rollup 호환 API
- 작은 번들 크기
❌ 단점
- 아직 베타 버전
- DTS 미지원
// rolldown.config.mjs
import { defineConfig } from 'rolldown';
export default defineConfig([
{
input: 'src/index.ts',
output: { file: 'dist/index.mjs', format: 'esm' },
external: [/^react/, /^@mui\/material/],
},
]);
7. tsdown
| 기반 기술 | rolldown |
| 설정 복잡도 | 매우 낮음 |
| DTS 생성 | 내장 지원 |
| ESM/CJS 동시 출력 | format: ['esm', 'cjs'] |
✅ 장점
- tsup과 동일한 간단한 설정
- DTS 생성 내장
- rolldown 기반으로 빠름
- tsup 대체제로 적합
❌ 단점
- 아직 초기 버전
// tsdown.config.ts
import { defineConfig } from 'tsdown';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
external: ['react', /^@mui\/material/],
outDir: 'dist',
});
종합 비교표
각 번들러의 특성을 5점 만점으로 정리했습니다. 별이 많을수록 좋습니다.
| 기준 | tsup | esbuild | rollup | vite | rspack | rolldown | tsdown |
|---|---|---|---|---|---|---|---|
| 빌드 속도 | ★★★☆☆ | ★★★★★ | ★★☆☆☆ | ★★★★☆ | ★★★★☆ | ★★★★★ | ★★★★☆ |
| 번들 크기 | ★★★★☆ | ★★★☆☆ | ★★★★☆ | ★★★★★ | ★★☆☆☆ | ★★★★☆ | ★★★★☆ |
| 설정 간편함 | ★★★★★ | ★★★★☆ | ★★★☆☆ | ★★★★☆ | ★★☆☆☆ | ★★★★☆ | ★★★★★ |
| DTS 지원 | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ★★★☆☆ | ★★☆☆☆ | ★★☆☆☆ | ★★★★★ |
| 안정성 | ★★★★★ | ★★★★★ | ★★★★★ | ★★★★★ | ★★★★☆ | ★★★☆☆ | ★★★☆☆ |
권장 사항
용도별 추천
| 용도 | 추천 번들러 | 이유 |
|---|---|---|
| 라이브러리 번들링 (안정성) | tsup | 간단한 설정과 DTS 내장 그리고 검증된 도구 |
| 라이브러리 번들링 (성능) | tsdown | tsup 호환과 rolldown 기반 빠른 빌드 |
| 최소 번들 크기 | vite | 가장 작은 출력물 |
| 최고 빌드 속도 | esbuild / rolldown | 압도적으로 빠름 |
| webpack 마이그레이션 | rspack | 플러그인 호환성 |
| 복잡한 빌드 파이프라인 | rollup | 풍부한 플러그인 |
실무 권장안
🎯 현재: tsup 유지 권장
라이브러리 번들링에 가장 적합합니다. DTS 생성이 내장되어 있어 추가 설정이 불필요하며 안정적이고 검증된 도구입니다.
🔮 향후: tsdown 고려
rolldown이 정식 릴리즈되면 tsdown으로 마이그레이션을 고려해볼 만합니다. tsup과 거의 동일한 설정으로 더 빠른 빌드가 가능합니다.
마이그레이션 가이드
tsup → tsdown 마이그레이션
설정 변경 난이도: ★☆☆☆☆ (매우 쉬움)
tsdown은 tsup의 drop-in replacement를 목표로 설계되어 설정이 거의 동일합니다.
- import { defineConfig } from 'tsup';
+ import { defineConfig } from 'tsdown';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
- splitting: true, // tsdown에서는 기본 내장
sourcemap: true,
clean: true,
external: [
'react',
'react-dom',
- '@mui/material', // 문자열 → 정규식 권장
+ /^@mui\/material/, // 하위 경로 포함을 위해 정규식 사용
'@emotion/react',
'@emotion/styled',
],
- treeshake: true, // tsdown에서는 기본 내장
+ outDir: 'dist', // 출력 디렉토리 명시 (선택사항)
});
주요 차이점
| 항목 | tsup | tsdown | 마이그레이션 |
|---|---|---|---|
| import | from 'tsup' |
from 'tsdown' |
변경 필요 |
| splitting | 옵션으로 설정 | 기본 내장 | 옵션 제거 |
| treeshake | 옵션으로 설정 | 기본 내장 | 옵션 제거 |
| external | 문자열/정규식 | 정규식 권장 | 하위 경로용 정규식 변환 |
| 출력 파일명 | .js, .mjs | .cjs, .mjs | package.json 수정 필요할 수 있음 |
rollup → rolldown 마이그레이션
설정 변경 난이도: ★★☆☆☆ (쉬움)
rolldown은 rollup 호환 API를 제공하며 플러그인 없이 TypeScript를 기본 지원합니다.
- import typescript from '@rollup/plugin-typescript';
- import resolve from '@rollup/plugin-node-resolve';
- import commonjs from '@rollup/plugin-commonjs';
+ import { defineConfig } from 'rolldown';
const external = [
- 'react',
- 'react-dom',
+ /^react/, // 정규식으로 통합 가능
/^@mui\/material/,
- '@emotion/react',
+ /^@emotion\/react/,
];
- export default [
+ export default defineConfig([
{
input: 'src/index.ts',
output: {
file: 'dist/index.mjs',
format: 'esm',
sourcemap: true,
},
external,
- plugins: [
- resolve(),
- commonjs(),
- typescript({ tsconfig: './tsconfig.json' }),
- ],
},
- ];
+ ]);
주요 차이점
| 항목 | rollup | rolldown | 마이그레이션 |
|---|---|---|---|
| TypeScript | @rollup/plugin-typescript 필요 |
기본 내장 | 플러그인 제거 |
| Node resolve | @rollup/plugin-node-resolve 필요 |
기본 내장 | 플러그인 제거 |
| CommonJS | @rollup/plugin-commonjs 필요 |
기본 내장 | 플러그인 제거 |
| defineConfig | 없음 (선택) | 제공 | 타입 지원 향상 |
마이그레이션 리스크 평가
| 마이그레이션 | 난이도 | 리스크 | 권장 시점 |
|---|---|---|---|
| tsup → tsdown | 매우 낮음 | 낮음 | rolldown 1.0 정식 출시 후 |
| rollup → rolldown | 낮음 | 중간 | rolldown 1.0 정식 출시 후 |
⚠️ 주의사항
1. rolldown/tsdown은 아직 베타입니다.
프로덕션 사용 전 충분한 테스트가 필요하며 1.0 정식 릴리즈까지 대기를 권장합니다.
2. 출력물 차이를 확인하세요.
번들 크기와 내용이 약간 다를 수 있습니다. 기존 번들과 diff 비교를 권장합니다.
3. 플러그인 호환성을 검토하세요.
rolldown은 일부 rollup 플러그인과 호환되지 않을 수 있습니다.
'je개발 회고' 카테고리의 다른 글
| [ CI/CD ] 모노레포 Gitlab CI/CD 전략 (0) | 2025.12.22 |
|---|---|
| [ Git ] 회사에 맞는 브랜치 전략 (0) | 2025.12.22 |
| [ 번들러 ] Monorepo 모노레포 번들러 비교 (0) | 2025.12.16 |
| [ 데이터 품질 관리 ] (4) Frontend : Batching (4) | 2025.08.19 |
| [ 데이터 품질 관리 ] (3) Frontend : Zod 스키마와 API 검증 (3) | 2025.08.18 |