라떼군 이야기
Vite 프로젝트 생성 시 TypeScript vs TypeScript + SWC 선택 가이드 및 성능 차이 분석
Problem
Vite를 사용하여 새로운 React 프로젝트를 생성(npm create vite@latest)할 때, 프레임워크로 React를 선택하면 TypeScript와 TypeScript + SWC라는 두 가지 변형(Variant) 옵션을 마주하게 됩니다. 두 옵션 모두 TypeScript를 지원하는 것은 동일해 보이지만, 구체적으로 내부 동작 방식에 어떤 차이가 있는지, 빌드 성능이나 호환성 면에서 무엇을 선택하는 것이 내 프로젝트에 유리한지 명확하지 않아 혼란을 겪을 수 있습니다.
Background
이 차이를 이해하기 위해서는 **트랜스파일러(Transpiler)**의 역할을 알아야 합니다. 브라우저는 TypeScript나 최신 JSX 문법을 직접 실행할 수 없으므로, 이를 일반 JavaScript로 변환해주는 도구가 필요합니다.
전통적으로 이 역할은 JavaScript로 작성된 Babel이 담당해왔습니다. 하지만 최근 Rust라는 시스템 프로그래밍 언어로 작성되어 압도적인 성능을 자랑하는 **SWC(Speedy Web Compiler)**가 등장했습니다. Vite는 빠른 개발 경험을 지향하므로, 프로젝트 생성 시 이 두 컴파일러 중 어떤 것을 기반으로 빌드 시스템을 구성할지 선택권을 제공합니다.
Solution
두 옵션의 핵심 차이는 **‘코드를 변환할 때 어떤 도구를 사용하는가’**에 있습니다. 각 옵션의 특징과 설정 차이를 상세히 알아보겠습니다.
1. TypeScript (Babel 사용)
이 옵션은 전통적인 방식인 Babel을 사용합니다. Vite 내부적으로 @vitejs/plugin-react 플러그인을 사용합니다.
- 장점:
- 성숙한 생태계: 수년 동안 쌓인 방대한 플러그인과 프리셋을 사용할 수 있습니다.
- 커스터마이징: 매우 세밀한 설정이 가능하며, 특정 Babel 플러그인(예: CSS-in-JS 라이브러리용 플러그인)이 필요한 경우 필수적입니다.
- 안정성: 오랜 기간 검증되어 버그가 적고 문서화가 잘 되어 있습니다.
- 단점:
- 속도: JavaScript로 작성되어 있어 SWC에 비해 컴파일 속도가 느립니다.
설정 예시 (vite.config.ts):
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// Babel 기반의 플러그인 사용
export default defineConfig({
plugins: [react()],
})
2. TypeScript + SWC (SWC 사용)
이 옵션은 Rust로 작성된 SWC를 사용합니다. Vite 내부적으로 @vitejs/plugin-react-swc 플러그인을 사용합니다.
- 장점:
- 압도적인 성능: Rust의 병렬 처리 능력을 활용하여 Babel보다 훨씬 빠른 빌드 및 HMR(Hot Module Replacement) 속도를 제공합니다.
- 간편함: 초기 설정이 거의 필요 없으며 기본적으로 최적화되어 있습니다.
- 단점:
- 생태계: Babel에 비해 아직 플러그인 생태계가 작습니다.
- 호환성: 아주 드물게 특정 엣지 케이스에서 버그가 발생할 수 있거나, 일부 최신 기능 구현이 늦을 수 있습니다.
설정 예시 (vite.config.ts):
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// SWC 기반의 플러그인 사용
export default defineConfig({
plugins: [react()],
})
선택 가이드
- TypeScript + SWC 추천: 새로운 프로젝트를 시작하거나, 빌드 속도가 중요한 중대형 애플리케이션인 경우.
- TypeScript (Babel) 추천: Babel 전용 플러그인(예:
babel-plugin-styled-components의 고급 기능 등)을 반드시 사용해야 하거나, 레거시 브라우저 지원을 위한 복잡한 커스텀 변환이 필요한 경우.
Deep Dive
SWC의 성능 우위와 한계
SWC는 단일 스레드인 JavaScript 기반의 Babel과 달리, 멀티 코어를 활용하여 병렬 처리를 수행합니다. 벤치마크에 따르면 SWC는 Babel보다 20배에서 최대 70배까지 빠를 수 있습니다. 이는 프로젝트 규모가 커질수록 개발 생산성(빌드 대기 시간 단축)에 큰 영향을 미칩니다.
하지만 주의할 점은 **‘Babel 매크로’**나 커스텀 Babel 설정을 사용하는 라이브러리와의 호환성입니다. 예를 들어, 일부 라이브러리는 빌드 타임에 코드를 변환하기 위해 특정 Babel 플러그인을 요구하는데, SWC용으로 포팅된 플러그인이 없다면 해당 기능을 사용할 수 없습니다. 따라서 프로젝트의 기술 스택이 특정 Babel 플러그인에 강하게 의존하는지 미리 확인해야 합니다.
Conclusion
Vite 프로젝트 생성 시 TypeScript + SWC 옵션은 Rust 기반의 빠른 컴파일 속도를 제공하므로, 특별한 이유가 없다면 기본값으로 선택하는 것을 권장합니다. 반면, TypeScript 옵션은 Babel의 방대한 생태계와 세밀한 설정이 필요한 특수한 경우에 선택하는 것이 좋습니다.