테마
트랜스파일러와 번들러 개요
트랜스파일러는 소스코드를 다른 형태의 소스코드로 변환하고, 번들러는 분산된 모듈을 하나의 파일로 묶어 브라우저에서 실행 가능한 산출물을 만드는 도구이다.
학습 목표
- 트랜스파일러(Transpiler)와 컴파일러(Compiler)의 개념과 차이를 이해한다
- 번들러(Bundler)의 역할과 필요성을 설명할 수 있다
- 대표적인 트랜스파일러(Babel, TypeScript, esbuild, SWC)를 분류할 수 있다
- 대표적인 번들러(Webpack, Rollup, esbuild, Vite)의 포지셔닝을 파악한다
- 트랜스파일러와 번들러가 협력하는 전체 빌드 파이프라인을 설명할 수 있다
1. 왜 이 도구들이 필요한가?
1.1 브라우저 호환성 문제
자바스크립트는 매우 다양한 환경에서 실행된다. 브라우저(Chrome, Safari, Firefox, Samsung Internet 등), Node.js, Deno, Electron 등 각 런타임이 이해하는 자바스크립트 문법의 범위가 다르다.
개발자가 최신 ES2024 문법으로 작성한 코드가 모든 브라우저에서 동일하게 실행되리라는 보장이 없다. 우리가 작성한 코드는 더 이상 브라우저에서 직접 실행되지 않는다. 반드시 중간에 변환 과정을 거쳐야 한다.
1.2 모듈 시스템과 파일 분리
현대 프론트엔드 개발에서는 코드를 기능별로 모듈화하여 작업한다. 수백, 수천 개의 파일이 서로를 import/export하며 의존 관계를 형성한다. 이렇게 분리된 파일들을 브라우저가 효율적으로 로드할 수 있는 형태로 묶는 작업이 필요하다.
2. 트랜스파일러(Transpiler)란?
트랜스파일러는 소스코드를 다른 형태의 소스코드로 변환하는 도구이다. 컴퓨터공학에서 전통적인 컴파일러는 고수준 언어를 저수준 기계어로 변환하지만, 프론트엔드에서의 트랜스파일러/컴파일러는 같은 추상화 수준의 다른 형태로 변환한다는 점이 다르다.
프론트엔드 커뮤니티에서는 "컴파일러"와 "트랜스파일러"를 혼용해서 사용한다. Babel은 스스로를 "JavaScript Compiler"라고 부르고, SWC는 "Speedy Web Compiler"의 약자이다.
2.1 트랜스파일러가 하는 일
| 변환 유형 | 예시 | 설명 |
|---|---|---|
| 최신 문법 → 호환 문법 | Arrow Function → Function | ES2024 문법을 ES5로 변환 |
| TypeScript → JavaScript | const x: number = 1 → const x = 1 | 타입 어노테이션 제거 |
| JSX → JavaScript | <App /> → React.createElement(App) | JSX 문법을 함수 호출로 변환 |
| CSS-in-JS | styled.div\...`` → CSS 문자열 | CSS 전처리 |
2.2 대표적인 트랜스파일러
핵심 포인트:
- Babel: 가장 오래되고 넓은 생태계. 플러그인으로 모든 변환을 제어한다.
- TypeScript (tsc): 언어이자 컴파일러. 타입 검사 기능이 핵심 차별점이다.
- esbuild: Go 기반으로 Babel의 100배 이상 빠르다. 번들링과 압축도 겸한다.
- SWC: Rust 기반으로 Babel을 완전히 대체하는 것이 목표이다. Vercel(Next.js)이 지원한다.
3. 번들러(Bundler)란?
번들러는 모듈화된 여러 파일을 하나 또는 소수의 파일로 묶어주는 도구이다. 단순히 파일을 합치는 것이 아니라, 의존성 분석, Tree Shaking, 코드 분할, 압축 등의 최적화를 함께 수행한다.
3.1 번들러가 필요한 이유
- 네트워크 효율성: 수백 개의 파일을 개별 요청하면 HTTP 오버헤드가 크다
- 의존성 해결: 모듈 간 import/export 관계를 분석하여 올바른 순서로 합친다
- 최적화: 사용하지 않는 코드 제거(Tree Shaking), 코드 압축(Minification)
- 코드 분할: 초기 로딩에 필요한 코드만 먼저 전달(Code Splitting)
3.2 대표적인 번들러
| 번들러 | 출시 | 기반 언어 | 특화 영역 | 비고 |
|---|---|---|---|---|
| Webpack | 2012 | JavaScript | 애플리케이션 | 가장 넓은 생태계, Module Federation 지원 |
| Rollup | 2015 | JavaScript | 라이브러리 | ES Module 기반, Tree Shaking 선구자 |
| esbuild | 2020 | Go | 범용 | 트랜스파일 + 번들 + 압축 올인원 |
| Vite | 2020 | JavaScript | 개발 환경 | ESM 개발 서버 + Rollup 프로덕션 빌드 |
4. 트랜스파일러와 번들러의 관계
트랜스파일러와 번들러는 독립적인 도구이지만, 빌드 파이프라인에서 긴밀히 협력한다. 번들러가 파일을 묶는 과정에서 트랜스파일러를 로더(Loader) 또는 **플러그인(Plugin)**으로 호출하는 구조가 일반적이다.
4.1 도구 간 역할 관계
| 시나리오 | 트랜스파일러 | 번들러 | 압축 도구 |
|---|---|---|---|
| Webpack + Babel | Babel | Webpack | Terser |
| Webpack + SWC | SWC | Webpack | SWC (minify) |
| Rollup + Babel | Babel | Rollup | Terser (rollup-plugin-terser) |
| Vite (개발) | esbuild | 없음 (ESM) | 없음 |
| Vite (프로덕션) | esbuild | Rollup | esbuild (minify) |
| esbuild 단독 | esbuild | esbuild | esbuild |
5. 도구 생태계 전체 지도
프론트엔드 빌드 도구는 크게 세 세대로 구분할 수 있다.
| 세대 | 시기 | 특징 | 대표 도구 |
|---|---|---|---|
| 1세대 | 2012~2017 | JavaScript로 작성, 설정 복잡 | Webpack, Babel, Rollup |
| 2세대 | 2018~2020 | 네이티브 언어(Go, Rust) 기반, 속도 혁신 | esbuild, SWC |
| 3세대 | 2020~현재 | 네이티브 ESM 활용, 종합 도구화 | Vite, Turbopack, Rspack |
5.1 속도 비교 (참고)
Babel과 esbuild/SWC의 속도 차이는 극적이다. 대규모 프로젝트에서 트랜스파일 시간이 수십 초에서 1초 이내로 줄어든다. 이 속도 차이의 근본 원인은 구현 언어에 있다. JavaScript는 인터프리터 언어인 반면, Go와 Rust는 네이티브 컴파일 언어로서 본질적으로 빠르며 멀티스레드 병렬 처리가 가능하다.
핵심 정리
| 개념 | 핵심 내용 |
|---|---|
| 트랜스파일러 | 소스코드를 다른 형태의 소스코드로 변환. 최신 문법을 호환 가능한 문법으로 바꾼다 |
| 번들러 | 여러 모듈 파일을 하나 또는 소수의 파일로 묶어 최적화한다 |
| 필요한 이유 | 브라우저 호환성 확보 + 네트워크 효율성 + 코드 최적화 |
| 협력 관계 | 번들러 내부에서 트랜스파일러를 로더/플러그인으로 호출하는 구조 |
| 트렌드 | JavaScript 기반 → 네이티브 언어(Go, Rust) 기반으로 전환 중 |
| 올인원 도구 | esbuild처럼 트랜스파일 + 번들 + 압축을 한 도구로 수행하는 흐름 |
다음 단계
- 다음 문서 02-Babel.md에서 가장 기본적인 트랜스파일러인 Babel의 원리, 플러그인/프리셋 시스템, 설정 방법을 상세히 학습한다.