je개발 회고

[ 번들러 ] 모노레포 번들러 비교

Je-chan 2025. 12. 22. 17:13

모노레포 라이브러리 번들러 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 플러그인과 호환되지 않을 수 있습니다.