📚 목차
[React] Webpack에서 ts-loader 대신 babel를 선택한 이유
최근 프로젝트에서 Webpack을 사용하여 React + TypeScript 환경을 설정하는 과정에서 ts-loader
대신 babel-loader
를 선택했다.
원래 Webpack에서 TypeScript를 사용하려면 ts-loader
를 사용하는 것이 일반적이다. 하지만 최근에 ts-loader
대신 babel
를 사용해서 Typescript를 컴파일하는 것이 더 효율적인 것을 알게됐다.
이 글에서 ts-loader
대신 babel-loader
를 사용한 이유와 그 장점을 살펴보자.
TypeScript는 JavaScript에 타입 시스템을 추가한 언어이다. 하지만 브라우저는 TypeScript를 직접 실행할 수 없기 때문에, TypeScript 코드는 반드시 JavaScript로 변환(컴파일)해야 한다.
Webpack은 기본적으로 .js와 .json만 이해할 수 있다.
그래서 .ts나 .scss, .png 같은 파일을 처리하려면 loader
라는 도구가 필요하다. loader가 webpack에게 통역사 역할을 해주는 것이다.
ts-loader
라는 loader가 TypeScript
(.ts)파일을 Webpack이 이해할 수 있는 JavaScript로 변환해준다.
babel 이란?
바벨은 최신 JavaScript 코드를 이전 버전의 JavaScript로 변환해 주는 도구이다. 예를 들어, ES6+ 문법을 ES5로 변환해서 오래된 브라우저에서도 동작하게 만들어준다.
// 변환 전 (ES6+)
const sum = (a, b) => a + b;
// 변환 후 (ES5)
var sum = function(a, b) {
return a + b;
};
바벨은 코드를 다음과 같이 바꿔준다.
- 화살표 함수 → function 키워드를 사용하는 일반 함수
- 클래스 문법 → 프로토타입 기반 생성자 함수
- 템플릿 리터럴 → 문자열을 + 기호로 이어 붙여 연결
- 구조 분해 할당 → 하나씩 값을 꺼내는 일반 변수 할당
- JSX 문법 → React.createElement() 함수 호출 코드
React에서는 JSX를 일반 JavaScript로 변환하는 데 바벨이 필수적이다.
ts-loader 대신 babel-loader를 선택한 이유
React + TypeScript 프로젝트를 Webpack으로 설정할 때 가장 먼저 고민하는 것 중 하나는 TypeScript 파일을 어떻게 변환할 것인가이다.
1. 빌드 속도 최적화
ts-loader
는 TypeScript의 전체 타입 검사 과정을 거치며 컴파일을 수행한다. 따라서 규모가 커질수록 타입 체크 + 트랜스파일로 인해 빌드 속도가 느려질 수 있다.
반면 babel-loader
는 타입 검사를 하지 않고 코드만 빠르게 JavaScript로 변환한다. 타입 검사는 별도로 tsc
나 fork-ts-checker-webpack-plugin
을 통해 처리하면 되기 때문에, 트랜스파일과 타입 체크를 병렬화하여 속도를 개선할 수 있다.
2. React와의 강력한 호환성
React 17 이상부터는 JSX를 자동으로 변환하는 automatic runtime
기능이 도입됐다. Babel은 이와 같은 최신 기능을 빠르게 반영하며, @babel/preset-react
를 통해 JSX 변환을 효율적으로 수행할 수 있다.
따라서 React의 최신 문법, 실험적 기능을 빠르게 적용하려면 Babel 환경이 더 적합하다.
3. 다양한 Babel 플러그인 생태계
Babel은 방대한 플러그인 생태계를 가지고 있다. 예를 들어 아래와 같은 기능들을 플러그인으로 손쉽게 추가할 수 있다:
- async/await 트랜스파일
- class properties, decorators 등 실험적 문법
- styled-components 최적화
- polyfill 자동 주입
이런 기능을 Webpack 빌드 단계에서 유연하게 커스터마이징하고 싶다면 Babel 기반 설정이 더 적합하다.
babel을 사용하여 설정 방법
먼저, babel-loader
와 필요한 패키지를 설치한다:
npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/preset-typescript
- @babel/core: JavaScript 코드를 변환해 주는 도구
- babel-loader: Webpack에서 바벨을 사용할 수 있도록 연결해 주는 역할.
- @babel/preset-react: 바벨에게 JSX를 어떻게 변환할지 알려주는 설정.
- @babel/preset-typescript: 바벨에게 타입스크립트를 어떻게 변환할지 알려주는 설정.
- @babel/preset-env: 최신 JavaScript 문법을 구버전 브라우저에서도 작동하게 변환해준다. React를 해석하는데 필수는 아니지만, 최신 JavaScript 문법을 쓸 계획이 있다면 넣는 걸 추천한다.
Webpack에 바벨 로더 설정 추가하기
webpack.config.js 파일의 entry, module.rules, resolve를 다음과 같이 수정하자.
module.exports = {
// ... 기존 설정 유지
entry: './main.tsx', // 웹팩이 읽기 시작할 파일을 .tsx로 변경
module: {
rules: [
{
test: /\.(ts|tsx)$/, // .ts와 .tsx 파일을 대상으로
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env', // 최신 JS 문법을 변환
'@babel/preset-react', // JSX를 변환
'@babel/preset-typescript' // 타입스크립트를 변환
]
}
}
],
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js'] // .tsx 확장자도 처리할 수 있게 한다
}
};
modules.rules와 resolve은 언제 수정해야 할까?
-
module.rules
: "이런 파일도 웹팩이 이해했으면 좋겠는데?" 싶을 때- .scss, .tsx 같은 새로운 파일을 추가했는데 웹팩이 못 읽을 때
- 로더를 새로 추가할 때 (예: 이미지, 폰트, SVG 등 처리용)
-
resolve
: import, require문을 썼을 때 어떤 파일을 가리키는지 알려주고 싶을 때import A from './A.tsx'
→import A from './A'
처럼 확장자를 생략하고 싶을 때src/components/...
이런 긴 경로를@components/...
처럼 짧게 쓰고 싶을 때- 모듈을 찾는 기준 경로를 바꾸고 싶을 때 (
node_modules
말고src
도 보게 만들기 등)
fork-ts-checker-webpack-plugin
타입 검사를 별도로 처리하기 위해 fork-ts-checker-webpack-plugin
을 사용할 수 있다.
fork-ts-checker-webpack-plugin을 사용하는 가장 큰 장점은 타입 검사(Type Checking)와 Linting을 Webpack 번들링과 병렬
로 수행할 수 있다는 것이다. 이를 통해 빌드 속도를 크게 향상시킬 수 있다.
정리해보면
-
Webpack과 타입 체크를 병렬 처리
- 기본적으로 ts-loader는 **타입 검사 + 트랜스파일(코드 변환)**을 동시에 처리
- 하지만 이 경우 빌드 속도가 느려질 수 있다.
- babel-loader는 타입 검사를 생략하고 빠르게 트랜스파일만 수행
- 이때 fork-ts-checker-webpack-plugin을 사용하면, 타입 체크는 별도의 프로세스에서 병렬로 수행되므로 Webpack 빌드 속도는 빨라지고, 타입 안전성도 유지
-
빠른 핫 리로딩 (HMR) 유지
- Webpack 개발 서버에서는 빠른 HMR(Hot Module Replacement)이 중요한데,
- 타입 체크 때문에 매번 전체 빌드를 기다리면 개발 생산성이 떨어진다.
- 이 플러그인은 타입 검사를 백그라운드에서 하므로 빠른 HMR을 유지할 수 있다.
HMR이란 코드 변경 시 전체 페이지를 새로고침하지 않고, 변경된 부분만 업데이트하는 기능이다. 이를 통해 개발 중에 빠르게 결과를 확인할 수 있다.
fork-ts-checker-webpack-plugin 설정
먼저, fork-ts-checker-webpack-plugin
을 설치한다.
npm install --save-dev fork-ts-checker-webpack-plugin
그 다음, webpack.config.js
에 플러그인을 추가한다.
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
module.exports = {
// ... 기존 설정 유지
plugins: [new ForkTsCheckerWebpackPlugin()],
};
이제 Webpack 빌드 시 타입 검사를 별도의 프로세스에서 병렬로 수행하게 된다.
결론
ts-loader
는 TypeScript의 변환과 타입 검사를 동시에 수행하는 반면, babel-loader
는 빠른 트랜스파일에 집중하여 빌드 속도를 개선할 수 있다.
이번 프로젝트에서는 생산성, 유연성, React 최신 기능 지원 측면에서 babel-loader를 선택했다. 타입 검사는 별도의 도구로 수행하면서 빌드와 검증을 분리하니, 결과적으로 더 빠르고 유연한 개발 환경을 구축할 수 있었다.