현대 웹 개발에서는 수많은 도구들이 등장하고 있다.
이전 포스팅에서도 언급했지만 특히 자바스크립트 생태계는 빠르게 발전하고 있다.
이번 포스팅에서는 모던 자바스크립트 개발에서 필수적인 두 가지 도구인 모듈 번들러와 트랜스파일러에 대해서 간단하게 정리해보고자 한다.
모듈 번들러라는 개념을 들었을 때, 생각났던건 React Native로 졸업 프로젝트를 진행할 때 봤던 Bundle이었다.
이름에서 알 수 있다시피, 모듈 번들러는 여러 개의 파일을 하나의 파일로 묶어주는 도구이다.
위 사진에서도 진행하고 있는 Bundling 과정은 필자가 작성한 프로그램 리소스들을 하나로 묶어주는 작업을 진행하고 있는 것이다.
그렇다면 왜 이런 도구가 필요하게 되었을까?
현대 웹 애플리케이션은 알다시피 수많은 파일들로 구성된다.
사용되는 파일 예시
- JavaScript 소스 코드 파일
- CSS 스타일시트
- 이미지 파일
- 기타 리소스 파일
우리가 사용하는 웹 브라우저는 HTTP 요청/응답 구조로 리소스를 로드한다.
즉, 파일이 많을수록 HTTP 요청 횟수가 증가하여 성능 저하 발생하게 된다.
이해를 돕기 위해 간단한 예시를 살펴보자
<!-- 번들링 전 -->
<html>
<head>
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/css/sidebar.css">
<link rel="stylesheet" href="/css/buttons.css">
<script src="/js/app.js"></script>
<script src="/js/utils.js"></script>
<script src="/js/components.js"></script>
</head>
<body>
<img src="/images/logo.png">
</body>
</html>
해당 HTML은 CSS 파일 3개, JavaScript 파일 3개, 이미지 파일 1개를 로드해야 한다.
따라서 위 HTML에서는 총 7개의 개별 HTTP 요청이 발생하게 되는 것이다.
즉, DNS 조회, TCP 핸드셰이크 등의 네트워크 요청 과정을 7번 반복해야 하는 상황이 발생된다.
이러한 문제를 해결하기 위해 여러개의 파일을 하나의 파일로 묶어주는 Bundling이 필요하게 된다.
방금 살펴본 HTML을 Bundling한다면 아마 아래와 같이 바뀔 수 있을 것 같다.
<!-- 번들링 후 -->
<html>
<head>
<link rel="stylesheet" href="/dist/styles.bundle.css">
<script src="/dist/app.bundle.js"></script>
</head>
<body>
<img src="/images/logo.png">
</body>
</html>
(정확한 번들링 수행 결과는 아니다. 어떻게 수행되는지 감을 잡도록 하자!)
모듈 번들러는 다음과 같은 과정을 통해 파일들을 최적화한다.
1. 의존성 분석
- Entry File Path를 기반으로 프로젝트의 모든 파일 간의 의존성 관계를 파악
- 의존성 그래프(Dependency Graph) 생성
2. 번들링 처리
- 여러 파일을 하나의 파일로 병합
- 코드 최적화 및 압축
- 불필요한 공백과 주석 제거
3. 최적화된 산출물 생성
- 브라우저에서 실행 가능한 최적화된 파일 생성
여기서 언급한 2번째 번들링 처리 과정은 Webpack / Rollup등 사용하는 모듈 번들러에 따라 다르다는 것을 기억하자!
트랜스파일러는 한 프로그래밍 언어로 작성된 소스 코드를 다른 프로그래밍 언어로 변환하는 도구이다.
여기서 우리는 컴파일러와 트랜스파일러를 헷갈리지 말아야 한다.
그렇다면 트랜스파일러는 컴파일러와 어떻게 다를까?
컴파일러
- 사람이 이해하기 좋은 고수준 언어를 컴퓨터가 이해할 수 있는 기계어로 변환하는 도구
트랜스파일러
한 고수준 언어를 다른 고수준 언어로 변환하는 도구
TypeScript → JavaScript
최신 JavaScript(ES6+) → 구버전 JavaScript(ES5)
컴파일러와 트랜스파일러가 수행하는 목적이 아예 다르니 기억해두자
그렇다면 트랜스파일러는 왜 필요할까?
타입 안정성
- JavaScript는 동적 타입 언어로 대규모 프로젝트에서 오류 발생 가능성이 높음
- TypeScript와 같은 정적 타입 시스템 도입 필요
// TypeScript function greet(name: string): string { return `Hello, ${name}!`; } // 트랜스파일 후 JavaScript function greet(name) { return "Hello, " + name + "!"; }
TypeScript는 코드를 작성하면서 타입 오류를 실시간으로 확인할 수 있도록 도와준다.
하지만 TypeScript는 브라우저가 직접 실행할 수 없는데, 그 이유는 브라우저가 오직 JavaScript만 이해할 수 있기 때문이다.
즉, 개발자는 효용성때문에 TypeScript를 사용하길 원하지만 브라우저는 JavaScript만을 이해할 수 있다.
이러한 문제를 해결하기위해 사용하는 도구가 바로 트랜스파일러인 것이다!
브라우저 호환성
- 최신 JavaScript 문법을 구버전 브라우저에서도 실행 가능하도록 변환
- 개발자는 최신 문법으로 개발하고, 사용자는 호환성 보장
코드 품질 향상
- 더 안전하고 유지보수가 용이한 코드 작성 가능
- 개발 시점에서 오류 발견 가능
정리하자면 트랜스파일러는 버전 호환성, 플랫폼 호환성, 언어 간 변환, 언어 확장 ... 등의 기능을 제공해준다.
우리가 아마 들어본 트랜스파일러는 Babel정도가 있을 것이다.
모듈 번들러와 트랜스파일러는 현대 웹 개발에서 없어서는 안 될 중요한 도구가 되었다.
왜냐하면 이러한 도구들은 개발자의 생산성을 높이고, 최종 사용자에게는 더 나은 성능과 호환성을 제공하기 때문이다.
우리도 이러한 도구들의 필요성을 이해하고 어떤 역할을 수행하는지 알아둬야 할 필요가 있다고 생각하여 포스팅을 작성해봤다 🤣
참고