여러 개발 문서들을 보면 빌드, 번들링, 트랜스파일링 등의 용어가 빈번하게 사용되는 걸 보게 된다. 대충은 무슨 의미인지 알고 있지만, 정확한 이해가 없으니 문서의 내용 이해가 어려웠던 경험들이 있다. 실제로 사용해 보는 게 가장 좋겠지만, 아직 배포할 서비스가 없는 관계로, 문서를 읽는 데 이해를 높이는 정도로만 간단하게 공부해 봤다.
번들링(Bundling)
코드를 효과적으로 관리하기 위해선 적절한 방식으로 파일을 쪼개서(모듈화 해서) 관리하는 것이 필요하다. 이렇게 사용 목적이나 시점에 따라 자바스크립트 파일을 쪼개서 관리하는 것을 '모듈 시스템'이라고 한다. ES5까지는 언어 차원에서 모듈 시스템 지원이 없었지만, ES6로 넘어오면서 언어에서 모듈 시스템을 지원해 주게 됐다.
모듈로 파일을 나눠서 관리하면 독립적인 네임 스페이스가 생성되기 때문에 변수-함수명 사용에도 훨씬 자유롭고, 무엇보다도 함수-클래스 등을 사용 목적에 맞게 구분해서 작성할 수 있어 프로젝트의 구조를 설계하는 데 있어 훨씬 유리한 장점이 있다.
하지만 단점도 있다. 모듈 시스템에 기반하여 프로젝트를 진행하다 보면 하나의 프로젝트에도 수십-수백 개의 모듈 파일이 생성되고, 해당 파일들을 배포하는 것이 무거운 태스크가 돼버렸다.
웹이 배포되고 나면 클라이언트에서 서버에 정적 파일을 요청할 때 프로그램 동작에 필요한 파일들이 네트워크 통신을 타고 서버에서 클라이언트로 내려가게 된다. 그런데, 해당 통신에서 수십-수백 개로 쪼개진 모듈 파일들이 각각 낱개로 전달된다고 하면 http 네트워크 통신도 수십-수백 번 이뤄질 수밖에 없다. 이는 많은 시간과 자원의 낭비로 이어진다.
그래서 보통은, 여러 파일로 쪼개져있는 모듈들을 배포하는 시점에 하나의 자바스크립트 파일로 묶어주고, 실제 http 요청에 대해서는 그 하나의 파일만 주고받도록 해준다. 이 과정을 '번들링'이라고 한다. 여러 개의 모듈 파일들을 하나의 '번들'로 묶어주는 것이다.
번들링은 단순히 파일을 하나로 합쳐주기만 하는 작업은 아니다. 번들링 할 때 불필요한 코드들(예를 들어 선언만 되고 사용된 곳은 없는 함수-변수명 등)을 제거해 주고(Tree Shaking), http 통신 시 경제적으로 파일을 전달하기 위해 파일 크기를 최적화하는 과정들이 포함된다.
번들링을 위한 도구로는 Webpack이 대표적이며, 가장 오랜 기간 현업에서 번들링 도구로 활용됐다. 하지만 최근엔 Rollup, ESBuild 등 좀 더 다양한 번들러가 여러 이유로 각광을 받고 있는 중이다.
트랜스파일링(Transpiling)
자바스크립트는 버전에 따라 지원되는 문법 등에 차이가 있다. 특히, ES6 버전을 기점으로 모듈 시스템, let
const
키워드, 화살표 함수 등 기존에 없던 새로운 문법이 대거 등장하면서 큰 발전이 있었다.
그런데, 자바스크립트 언어가 돌아가야 하는 환경인 브라우저는 경우에 따라 자바스크립트 언어의 발전 속도를 제대로 따라가지 못하는 경우가 종종 있다. 벤더사에서 자바스크립트의 새로운 문법을 적극적으로 지원하기 위해 환경을 개선해주지 않는다던가, 또는 브라우저를 사용하는 사용자가 브라우저 버전 업데이트를 미루는 바람에 자바스크립트 새로운 문법의 지원을 받지 못하는 경우가 발생한다.
개발 환경에서 아무리 잘 동작하던 코드더라도 클라이언트의 브라우저에서 동작하지 않으면 이는 문제가 있는 코드이다. 이렇게, 브라우저의 버전이나 자바스크립트 문법 호환 등의 이슈로 한 곳에서 잘 돌아가는 코드가 다른 곳에서 문제가 되는 상황을 '크로스 브라우징 이슈(Cross-Browsing Issue)'라고 한다(JS 버전 이슈 말고도, 크로스 브라우징 문제를 발생시키는 다양한 원인이 존재한다).
이런 문제를 해소하기 위해, 보통은 최신 자바스크립트 문법으로 작성된 코드더라도, 실제 프로덕션에 배포되어 제공될 땐 의도적으로 이전 버전의 하위 호환 자바스크립트 문법으로 코드를 다운 그레이딩해서 배포하는 방식이 사용된다. 이를 '트랜스파일링'이라고 한다.
트랜스파일을 하면 설정해 둔 config 값에 따라 최신 자바스크립트 문법이 ES5 이하의 하위 버전 자바스크립트 문법으로 자동 변환된다. 따라서, 최신 버전을 지원받지 못하는 브라우저를 사용하는 사람에게도 동일한 동작을 하도록 해줄 수 있는 것이다.
트랜스파일이 적용되는 경우도 사실 더 다양하다. 예를 들어, React의 JSX 문법으로 작성된 구문을 자바스크립트 코드로 바꿔주거나, 타입스크립트로 작성된 타입 정의 문법들을 자바스크립트 코드로 바꿔주는 등의 작업도 트랜스파일 과정을 통해 이루어진다. 만약에 기존 자바스크립트 코드로 표현이 어려운 문법이 있다면 해당 부분은 개발자가 직접 채워주는 작업을 해주기도 한다. 이렇게 브라우저 지원이 안 되는 부분을 별도 구현해 주는 것을 폴리필(Pollyfill)이라고 한다.
트랜스파일링을 수행해 주는 대표적인 도구로는 Babel, SWC 등이 있다. 타입스크립트를 자바스크립트로 트랜스파일 해주는 데에는 타입스크립트의 자체 트랜스파일러가 사용되기도 한다.
빌드(Build)
개발자가 구현한 프로젝트가 사용자가 이용 가능한 형태로 배포되는 데에는 많은 절차와 설정이 필요하다. 위에서 살펴본 번들링, 트랜스파일링 등의 과정도 거쳐야 하고, 컴파일-최적화 등 다양한 절차를 거쳐야 한다. 이 모든 과정을 통칭하는 것이 '빌드'다.
주로 '프로젝트를 빌드한다'라는 식으로 많이 사용되는데, 크로스 브라우징 이슈-성능 최적화 등 다양한 문제를 해결하는 방식으로 실제 배포를 위한 파일을 준비해 주는 모든 과정을 관리하는 것이 특징이다. 빌드를 위한 도구로는 요새 각광받고 있는 Vite 등이 있다.
과거에는 Webpack(번들러 겸 빌드 도구), Babel(트랜스파일러) 등을 적절하게 조합해서 빌드 과정을 좀 더 수동?으로 조정했다(create-react-app
은 그 자체로 빌드 도구인 게 아니라, 빌드를 위해 필요한 여러 도구들을 설치해 주는 스타터 CLI 도구이다). Vite는 Rollup과 ESM을 활용해 개발 서버 속도를 개선하고, 빌드 과정도 더 효율적으로 최적화해 준 도구이다.
결론
헷갈리는 용어에 대해 진짜 간략하게 알아본 내용 정리해 둔다. 나중에 실제로 개발하다 보면 잘 신경 써서 관리해줘야 하는 부분일 거고, 더 상세하고 자세한 앎이 필요할 테니, 하나씩 차근차근 잘 배워가야겠다.