테마
esbuild: Go 기반 초고속 번들러
esbuild는 Go 언어로 작성된 차세대 번들러로, 트랜스파일링 + 번들링 + 압축을 단일 도구에서 극도로 빠른 속도로 수행하며 빌드 도구 성능의 새로운 기준을 제시했다.
학습 목표
- esbuild의 설계 철학과 Go 언어 기반의 성능 우위를 이해한다
- esbuild가 Babel + Rollup + Terser의 역할을 어떻게 통합하는지 설명할 수 있다
- esbuild의 주요 기능(번들링, 트랜스파일, 미니파이, Tree Shaking)을 활용할 수 있다
- esbuild의 제한사항과 적절한 사용 시나리오를 판단할 수 있다
- esbuild API(CLI, JS API)를 사용하여 빌드 스크립트를 작성할 수 있다
1. esbuild란?
esbuild는 **"An extremely fast bundler for the web"**이라는 슬로건을 내세우는 차세대 빌드 도구이다. Figma의 CTO인 Evan Wallace가 개발했으며, 빌드 도구 성능의 새로운 시대를 열겠다는 목표를 갖고 있다.
1.1 esbuild의 핵심 특성
| 특성 | 설명 |
|---|---|
| 구현 언어 | Go (네이티브 컴파일, 멀티스레드 병렬 처리) |
| 올인원 | 트랜스파일 + 번들링 + 압축을 단일 도구로 수행 |
| 속도 | 기존 도구 대비 10~100배 빠름 |
| 버전 | 아직 0.x 버전 (1.0 미출시, API 변경 가능성) |
| 개발자 | Evan Wallace (Figma CTO) |
2. 왜 이렇게 빠른가?
esbuild가 기존 도구보다 압도적으로 빠른 이유는 구현 언어와 아키텍처에 있다.
2.1 속도 차이의 근본 원인
| 요인 | JavaScript 도구 | esbuild (Go) |
|---|---|---|
| 실행 방식 | V8 인터프리터/JIT | 네이티브 기계어 |
| 병렬 처리 | 싱글 스레드 (Worker 제한적) | 모든 CPU 코어 활용 |
| 메모리 | GC 의존, 오버헤드 존재 | 수동 관리, 최적화 |
| AST 처리 | 다단계 변환 (JSON 직렬화 등) | 단일 패스, 공유 메모리 |
| 캐시 의존도 | 캐시 없으면 매우 느림 | 캐시 없이도 충분히 빠름 |
3. esbuild의 주요 기능
3.1 기능 총괄
esbuild는 단일 도구로 기존에 여러 도구가 담당하던 역할을 모두 수행한다.
3.2 지원 기능 목록
| 기능 | 설명 |
|---|---|
| JavaScript/TypeScript 트랜스파일 | 최신 문법 변환, JSX 변환, TS 타입 제거 |
| ES Module / CommonJS 번들링 | 두 모듈 시스템 모두 지원 |
| CSS / CSS Modules 번들링 | CSS 파일도 번들링 가능 |
| Tree Shaking | bundle: true일 때 자동 활성화 |
| Minification | 코드 압축 (Terser 대체) |
| Source Map | 디버깅용 소스맵 생성 |
| 개발 서버 / Watch 모드 | 파일 변경 감지 및 자동 재빌드 |
| 플러그인 시스템 | 변환 로직 확장 가능 |
4. esbuild 사용법
4.1 CLI 사용
bash
# 설치
npm install --save-dev esbuild
# 기본 번들링
npx esbuild src/index.ts --bundle --outfile=dist/bundle.js
# Node.js용 번들링
npx esbuild src/index.ts --bundle --platform=node --outfile=dist/bundle.js
# 브라우저용 + 압축 + 소스맵
npx esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/bundle.min.js
# 여러 포맷 출력
npx esbuild src/index.ts --bundle --format=esm --outfile=dist/index.esm.js
npx esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.cjs.js4.2 JavaScript API 사용
빌드 스크립트를 JS 파일로 작성하면 더 유연한 설정이 가능하다.
javascript
// build.js
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.ts'], // 진입점 (여러 개 가능)
outfile: 'dist/index.js', // 출력 파일
bundle: true, // 번들링 활성화
platform: 'node', // 대상 플랫폼: node, browser, neutral
minify: true, // 코드 압축
sourcemap: true, // 소스맵 생성
target: ['es2020'], // 타깃 환경
treeShaking: true, // Tree Shaking (bundle: true면 자동)
external: ['react'], // 외부 의존성 제외
}).catch(() => process.exit(1));4.3 주요 옵션 설명
| 옵션 | 값 | 설명 |
|---|---|---|
entryPoints | 문자열 배열 | 번들링 시작점 |
outfile / outdir | 경로 | 단일 파일 출력 / 디렉토리 출력 |
bundle | boolean | true면 import를 따라가며 합침 |
platform | node / browser | 대상 런타임 |
format | esm / cjs / iife | 출력 모듈 형식 |
minify | boolean | Terser 역할 (압축) |
target | 배열 | 대상 JS 버전 (es2020, chrome100 등) |
treeShaking | boolean | 미사용 코드 제거 |
external | 문자열 배열 | 번들에서 제외할 패키지 |
5. TypeScript와 esbuild
esbuild는 TypeScript 파일을 직접 처리할 수 있지만, 타입 검사(type checking)는 수행하지 않는다. esbuild는 타입 어노테이션을 단순히 제거할 뿐이다.
bash
# esbuild만 사용하면 타입 오류가 있어도 빌드 성공
npx esbuild src/index.ts --bundle --outfile=dist/bundle.js
# 올바른 워크플로: tsc로 타입 검사 후 esbuild로 빌드
npx tsc --noEmit && npx esbuild src/index.ts --bundle --outfile=dist/bundle.js실무 패턴: package.json의 build 스크립트에서 tsc --noEmit(타입 검사만, 출력 없음)을 먼저 실행한 후 esbuild로 빌드하는 것이 일반적이다. 타입 정의 파일(.d.ts)이 필요하면 tsc --emitDeclarationOnly로 별도 생성한다.
6. esbuild의 제한사항
esbuild는 빠르지만 모든 상황에 적합한 것은 아니다.
| 제한사항 | 설명 |
|---|---|
| 타입 검사 미지원 | tsc를 별도로 실행해야 한다 |
| HMR 미지원 | Hot Module Replacement가 내장되어 있지 않다 |
| 일부 Babel 플러그인 미호환 | 특수한 변환은 Babel이 필요하다 |
| 0.x 버전 | API가 변경될 수 있다 |
| 복잡한 설정 어려움 | Webpack 수준의 정교한 설정은 어렵다 |
| Module Federation 미지원 | 마이크로프론트엔드 런타임 통합 불가 |
6.1 esbuild의 적절한 사용 시나리오
| 적합한 경우 | 부적합한 경우 |
|---|---|
| 소규모 라이브러리 번들링 | 대규모 SPA 애플리케이션 개발 |
| Babel/Terser 대체 (다른 번들러의 로더) | Module Federation 필요 시 |
| CI/CD 빌드 속도 개선 | 복잡한 HMR이 필요한 개발 환경 |
| Vite 내부 엔진으로 사용 | 매우 특수한 Babel 플러그인이 필요한 경우 |
7. 다른 도구에서의 esbuild 활용
esbuild는 단독으로 사용하기보다 다른 도구의 내부 엔진으로 활용되는 경우가 많다.
| 도구 | esbuild 활용 방식 |
|---|---|
| Vite | 개발 시 의존성 사전 번들링 + TypeScript/JSX 트랜스파일 |
| Webpack (esbuild-loader) | babel-loader 대체로 트랜스파일 속도 향상 |
| Rollup (rollup-plugin-esbuild) | Babel + Terser 대체 |
| Jest (esbuild-jest) | 테스트 파일 트랜스파일 속도 향상 |
핵심 정리
| 개념 | 핵심 내용 |
|---|---|
| esbuild | Go 기반 초고속 빌드 도구. 트랜스파일 + 번들 + 압축 올인원 |
| 속도 비결 | 네이티브 컴파일 + 멀티스레드 병렬 처리 + 효율적 메모리 관리 |
| 3가지 대체 | Babel(트랜스파일) + Rollup(번들) + Terser(압축) 역할을 한 도구로 |
| TypeScript | 타입 제거만 수행. 타입 검사는 tsc가 별도로 해야 한다 |
| 제한사항 | HMR 미지원, Module Federation 미지원, 0.x 버전 |
| 실무 활용 | 단독보다는 Vite, Webpack, Rollup 등의 내부 엔진으로 많이 활용된다 |
다음 단계
- 다음 문서 05-SWC.md에서 Rust 기반의 초고속 웹 컴파일러 SWC의 원리, Babel과의 호환성, 그리고 Next.js에서의 채택 사례를 학습한다.