Babel vs tsc


타입스크립트를 사용한 프로젝트를 만들때 공식인 tsc 대신 babel@babel/preset-typescript을 사용하는 경우가 많습니다. 하지만 babel의 주요 목표인 polyfill은 tsconfig.jsontarget 옵션을 이용하면 달성이 가능합니다. 그래서 tscbabel의 차이에 대해 좀 더 알아봤습니다.

이 글은 babel 7.16.0을 기준으로 작성되었습니다

Polyfill

Babel의 기능은 정말 다양하지만 가장 대표적인 사용 목적은 polyfill에 있습니다. 이는 공식 문서를 봐도 명시되어있습니다. 하지만 타입스크립트도 compilerOptionstarget 옵션을 사용하면 어느정도의 하위 호환성을 보장할 수 있어서 굳이 babel이 필요하지는 않을 것 같습니다. 이는 개인적으로 어느정도 맞다고 생각합니다. 하지만 babelbrowserslist query를 통해 훨씬 더 커스터마이징이 가능한 polyfill을 지원하기 때문에 조금 더 세분화된 하위 호환성을 설정하고 싶다면 babel을 써야 합니다.

타입 체킹

잘 알려져있듯이 @babel/preset-typescript은 ts를 js로 트랜스파일하는 과정에서 타입을 단순히 제거합니다. 이 경우 트랜스파일링이 tsc를 사용한 경우보다 훨씬 빨라지는 장점이 있지만, 타입을 제거하면 애초에 타입스크립트를 사용하는 의미가 퇴색된다는 문제가 있습니다. 그래서 보통 바벨을 이용해 트랜스파일링을 하고 tsc를 병렬로 사용해 타입체킹을 하는 경우가 많습니다.

만약 단순히 빠른 트랜스파일링이 필요해 babel을 쓴다면 ts-node--transpile-only 옵션을 사용한 프로젝트 세팅을 고려해보는 것을 추천합니다.

workflow의 확장성

개인적으로 babel을 썼을 때 가장 큰 이득은 확장성이라고 생각합니다. Babel이 제공하는 기능은 단순히 polyfill에만 있지 않기 때문인데, 예를 들어 babel-plugin-lodash라는 바벨 플러그인의 기능을 사용하고 싶은 경우 바벨 세팅이 되어 있는 경우에는 단순히 플러그인을 추가해주면 해당 기능을 사용할 수 있습니다. 이는 tsc를 이용해 프로젝트를 구성했을 경우 가질 수 없는 이점입니다. 만약 프로젝트가 대형 프로젝트이고, 새로운 워크플로우를 추가할 가능성이 있다면 처음부터 babel을 사용하는걸 추천합니다.

기타

추가로 예전 글들을 보면 @babel/preset-typescripttypescriptnamespace, const enum의 기능을 트랜스파일하지 못한다고 되어있는 경우가 많은데 babel 7.16.0을 기준으로 namespaceconst enum 전부 지원되고 있습니다.

참고 자료