테마
Babel: JavaScript 컴파일러
Babel은 최신 자바스크립트 문법을 다양한 브라우저에서 동작하는 하위 호환 코드로 변환하는 트랜스파일러이며, 플러그인과 프리셋 기반의 확장 가능한 아키텍처를 갖추고 있다.
학습 목표
- Babel의 핵심 역할(최신 JS → 호환 JS 변환, JSX 변환)을 이해한다
- 플러그인과 프리셋의 개념과 차이를 설명할 수 있다
- Browserslist와 @babel/preset-env의 연동 원리를 파악한다
- babel.config.json 설정 파일을 작성할 수 있다
- 주요 프리셋(@babel/preset-env, @babel/preset-react, @babel/preset-typescript)의 역할을 구분한다
1. Babel이란?
Babel은 공식 사이트에서 스스로를 **"JavaScript Compiler"**라고 소개한다. 2014년에 처음 등장한 이후 프론트엔드 트랜스파일러의 사실상 표준으로 자리잡았다.
Babel의 핵심 원리:
- 개발자가 최신 문법(ES2024, JSX, TypeScript 등)으로 코드를 작성한다
- Babel이 설정에 따라 대상 브라우저가 이해할 수 있는 문법으로 변환한다
- 변환된 코드를 브라우저에서 실행한다
1.1 Babel의 3단계 처리 과정
| 단계 | 역할 | 담당 패키지 |
|---|---|---|
| 파싱(Parse) | 소스코드를 AST(추상 구문 트리)로 변환 | @babel/parser |
| 변환(Transform) | AST를 규칙에 따라 조작 | 각 플러그인 |
| 코드 생성(Generate) | 조작된 AST를 다시 소스코드로 출력 | @babel/generator |
이 과정에서 변환 단계를 담당하는 것이 플러그인이다. 플러그인 없이 Babel을 실행하면 입력과 출력이 동일하다. 어떤 문법을 어떻게 바꿀지는 전적으로 플러그인에 의해 결정된다.
2. 플러그인(Plugin)과 프리셋(Preset)
2.1 플러그인
Babel 플러그인은 하나의 변환 규칙을 정의한다. 예를 들어 @babel/plugin-transform-arrow-functions는 화살표 함수를 일반 function으로 변환하는 단일 규칙이다.
javascript
// 변환 전 (ES6+)
const add = (a, b) => a + b;
// 변환 후 (ES5) - @babel/plugin-transform-arrow-functions 적용
var add = function(a, b) {
return a + b;
};2.2 프리셋
프리셋은 여러 플러그인을 묶어놓은 세트이다. 최신 문법 하나하나에 대해 플러그인을 개별 설치하고 관리하는 것은 비현실적이므로, 목적에 맞게 미리 구성해 놓은 플러그인 세트를 프리셋이라 부른다.
2.3 주요 프리셋 정리
| 프리셋 | 역할 | 핵심 기능 |
|---|---|---|
| @babel/preset-env | 최신 JS → 호환 JS | Browserslist 기반 자동 플러그인 선택 |
| @babel/preset-react | JSX → JS | React.createElement 또는 jsx 런타임 변환 |
| @babel/preset-typescript | TS → JS | 타입 어노테이션 제거 (타입 검사는 하지 않음) |
3. Browserslist와 @babel/preset-env
3.1 문제 상황
모든 문법을 무조건 ES5로 변환하면 코드 크기가 불필요하게 커진다. 최신 브라우저는 이미 많은 ES6+ 문법을 지원하므로, 타깃 브라우저에 맞춰 필요한 변환만 수행하는 것이 효율적이다.
3.2 Browserslist
Browserslist는 지원할 브라우저 목록을 선언적으로 정의하는 도구이다. .browserslistrc 파일이나 package.json의 browserslist 필드에 작성한다.
# .browserslistrc 예시
last 2 Chrome versions
last 2 Firefox versions
last 2 Safari versions
not dead
> 0.5%3.3 preset-env + Browserslist 연동
@babel/preset-env는 Browserslist 설정을 참조하여 대상 브라우저를 확인하고, 해당 브라우저가 지원하지 않는 문법에 대한 플러그인만 활성화한다.
결과: 불필요한 변환을 줄여 번들 크기를 최소화하고, 최신 브라우저 사용자에게 더 효율적인 코드를 제공한다.
4. Babel 설정 파일
4.1 설정 파일 종류
| 파일명 | 형식 | 스코프 |
|---|---|---|
babel.config.json | JSON | 프로젝트 전체 (모노레포 루트에 적합) |
babel.config.js | JavaScript | 프로젝트 전체 (동적 설정 가능) |
.babelrc.json | JSON | 해당 디렉토리 이하 |
.babelrc.js | JavaScript | 해당 디렉토리 이하 |
package.json의 babel 필드 | JSON | 해당 패키지 |
모노레포에서는 babel.config.json(프로젝트 단위 설정)과 .babelrc.json(패키지 단위 오버라이드)을 조합하여 사용한다.
4.2 설정 예시
json
// babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": "> 0.5%, last 2 versions, not dead",
"useBuiltIns": "usage",
"corejs": 3
}
],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-proposal-decorators"
]
}주요 옵션 설명:
targets: Browserslist 쿼리 또는 구체적 브라우저 버전 지정useBuiltIns: 폴리필 삽입 방식 ("usage"= 사용하는 것만 자동 삽입)corejs: core-js 폴리필 버전 지정
4.3 CLI 사용법
bash
# 패키지 설치
npm install --save-dev @babel/core @babel/cli @babel/preset-env
# src 폴더를 dist 폴더로 컴파일
npx babel src --out-dir dist5. Babel의 한계와 미래
5.1 느린 속도
Babel은 JavaScript로 작성되어 있으며, 싱글 스레드로 동작한다. 대규모 프로젝트에서 빌드 시간이 수십 초에 달할 수 있다. 이 성능 한계가 esbuild와 SWC 같은 차세대 도구가 등장한 직접적 원인이다.
5.2 현재 위치
Babel은 여전히 가장 넓은 플러그인 생태계를 보유하고 있으며, 특수한 변환이 필요한 경우 Babel 플러그인이 유일한 선택지인 경우가 많다. 하지만 일반적인 트랜스파일 작업에서는 esbuild나 SWC로 대체되는 추세이다.
| 측면 | Babel | esbuild / SWC |
|---|---|---|
| 속도 | 느림 (JS 싱글 스레드) | 매우 빠름 (Go/Rust 멀티 스레드) |
| 플러그인 생태계 | 매우 넓음 | 제한적 |
| 특수 변환 | 커스텀 플러그인 작성 가능 | 제한적 지원 |
| 타입 검사 | 없음 | 없음 (tsc 필요) |
| 안정성 | 매우 안정적 | 안정화 진행 중 |
핵심 정리
| 개념 | 핵심 내용 |
|---|---|
| Babel | JavaScript 컴파일러. 최신 문법을 호환 가능한 문법으로 변환한다 |
| 3단계 처리 | Parse(파싱) → Transform(변환) → Generate(생성) |
| 플러그인 | 하나의 문법 변환 규칙. 변환의 최소 단위이다 |
| 프리셋 | 플러그인 묶음. 목적별로 구성된 플러그인 세트이다 |
| @babel/preset-env | Browserslist 기반으로 필요한 변환만 자동 선택한다 |
| 한계 | JavaScript 싱글 스레드 기반이라 느림. esbuild/SWC로 대체 추세 |
다음 단계
- 다음 문서 03-Rollup과-Terser.md에서 ES Module 기반 번들러인 Rollup과 코드 압축 도구 Terser의 원리와 사용법을 학습한다.