번들러와 빌드 도구에 대해서
번들러 개념과 빌드 도구의 이해
- 웹팩
- 번들러
- 런타임
프론트엔드 개발자라면 한 번쯤 들어봤을 용어들이다.
이들은 현대적인 웹 개발을 위한 필수적인 개념들인데, 특히 대규모 애플리케이션을 효율적으로 관리하고 배포하기 위해 중요한 역할을 한다.
최근에는 번들러를 직접 사용하는 것보다 Vite 같은 빌드 도구나 Next.js 같은 프레임워크를 통해 간접적으로 사용하는 경우가 많아졌다.
그러나 번들러의 개념과 동작 원리를 이해하는 것은, 프레임워크나 빌드 도구를 사용할 때 발생할 수 있는 문제를 해결하고, 더 나은 성능과 효율성을 갖춘 애플리케이션을 개발하는 데 중요한 밑바탕이 되므로, 이 글에서 번들러의 기본 개념과 함께 동작 원리를 이해하기 위한 간단한 예제를 살펴보고, 추가로 빌드 도구에 대해서도 알아보자.
번들러의 이해
bundle - 묶다.
웹 개발 초기에는 웹의 규모가 작았기 때문에, JavaScript 파일을 단순히 HTML의
문제점
- 중복된 파일 이름으로 인한 충돌
- 페이지를 구성하는 파일 수 증가에 따른 네트워크 요청 증가로 인한 성능 저하
이러한 문제를 해결하기 위해 모듈이라는 개념이 등장했다. 모듈은 코드를 기능 단위로 나누어 재사용성과 유지보수성을 높이는 방식이다. CommonJS와 AMD(Asynchronous Module Definition)와 같은 모듈 시스템은 코드 구조화와 관리의 용이성을 제공하였다. 하지만 모듈 시스템을 사용하면 파일이 늘어나고, 이를 브라우저에서 효율적으로 로드하는 것이 또 다른 문제가 되었다.
위 문제를 해결하기 위해 번들러가 탄생했다. 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미한다. 또한, 파일 수를 줄여 네트워크 요청을 최소화하고, 성능을 향상시킬 수 있다.
즉, 코드의 모듈성을 유지하면서도 최적화된 형태로 배포할 수 있게 해준다.
[주요 기능]
- 파일 병합: 여러 개의 JavaScript, CSS 파일을 하나의 파일로 병합하여 네트워크 요청 수를 줄인다.
- 의존성 관리: 모듈 간의 의존성을 분석하고, 이를 효율적으로 해결하여 코드의 로딩 순서를 관리한다.
- 코드 압축 및 최적화: 불필요한 공백, 주석을 제거하고 코드의 크기를 줄여 배포용 파일을 최적화한다.
- 소스 맵 생성: 디버깅을 용이하게 하기 위해 원본 코드와 번들된 코드 간의 매핑을 제공한다.
- 트리 쉐이킹(Tree Shaking): 사용하지 않는 코드를 제거하여 최종 번들 파일의 크기를 줄인다.
코드 예시
// 모든 배열 유틸리티들을 가져온다.
import arrayUtils from "array-utils";
// 유틸의 일부만 가져온다.
import { unique, implode, explode } from "array-utils";
이 외에도 babel을 통한 문법 변환, postCSS를 이용한 autoprefixer 등 다양한 작업을 수행할 수 있다.
- POST CSS: CSS를 더 현대적으로 바꾸고 개선해주는 플러그인
- Autoprefixer: PostCSS 플러그인 중 하나. -webket- -ms-등 CSS 속성의 벤더 프리픽스(vendor prefix)를 사용자의 브라우저에 따라 자동으로 붙여주는 플러그인
- 벤더 프리픽스: 주요 웹 브라우저가의 공급자가 새로운 실험적인 기능을 제공할 때 이전 버전의 웹 브라우저에 그 사실을 알려주기 위해 사용하는 접두사를 의미. 아직 CSS 권고안에 포함되지 못하거나, 포함은 되었으나 완전히 제정된 상태가 아닌 기능을 사용할 때 사용
웹팩이란
웹팩은 가장 널리 사용되는 번들러 중 하나로, 최신 자바스크립트 표준을 따라 ES6 모듈, CommonJS, AMD 등 다양한 모듈 시스템을 지원하며, 다양한 플러그인을 제공해 코드 최적화, 환경 변수 설정, 파일 압축, 번들 분석 등 다양한 기능을 수행할 수 있다.
웹팩은 프론트 프레임워크에서 가장 널리 사용되는 모듈 번들러다. 모듈 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 병합하여 하나의 결과물을 만드는 도구를 의미한다.
웹팩에서 모듈이란 개념은 위와 같이 JS 모듈에만 국한되지 않고, 웹 애플리케이션을 구성하는 모든 자원을 의미한다.
Webpack v5부터 Module Federation을 지원하여, 단일 Webpack 빌드의 모듈뿐만 아니라 여러 서버에 배포된 원격 모듈도 하나의 애플리케이션에서 사용할 수 있다.
또한 웹팩은 기본적으로 필요한 자원은 미리 로딩하는 게 아니라 그때마다 요청하자는 철학을 갖고 있다.
중요 속성
- entry: 번들링을 시작할 파일을 지정하는 진입점
- output: 번들링된 파일의 이름과 경로 지정
- loader: 모듈을 어떻게 처리할 지 정의. 여러 파일을 Webpack이 이해할 수 있는 형식으로 변환
- plugin: 특정 유형의 모듈을 변환하는 데 사용되지만, 번들을 최적화하거나, 애셋을 관리하고, 또 환경 변수 주입등과 같은 광범위한 작업을 수행 할 수 있다.
Vite란
Vite는 ES 모듈 기반의 HMR(Hot Module Replacement)을 활용하여 사전 번들링을 수행하는 도구이다. 로컬 개발 환경에서 변경된 모듈만을 번들링하여 즉시 반영할 수 있는 방식이다.
전통적인 번들러인 Webpack의 경우, 초기 콜드 스타트 시 전체 모듈을 번들링한 후 메모리에 적재하는 시간이 필요하다. 반면, Vite는 사전 번들링을 통해 서버를 즉시 실행할 수 있으며, 명령어를 입력하는 순간 서버가 바로 구동된다.
Vite는 내부적으로 ESBuild를 사용하여 사전 번들링을 수행한다. Webpack은 자바스크립트로 작성되었지만, ESBuild는 Go라는 네이티브 언어로 작성되어 빌드 속도가 약 10배에서 100배 정도 더 빠르다. 이로 인해 Vite는 빠른 개발 경험을 제공할 수 있다.
ES 모듈이란?
ES 모듈은 JavaScript의 공식 모듈 시스템으로, ES6(ECMAScript 2015)에서 도입되었다. 이를 통해 JavaScript 파일 간에 모듈을 보다 효율적으로 관리할 수 있다.
Vite의 특징
Vite는 빠른 빌드 속도 외에도 여러 가지 장점을 제공한다. 첫째, 코드 스플리팅과 같은 최신 JavaScript 기능을 기본적으로 지원한다. 둘째, 플러그인 시스템을 통해 다양한 기능을 확장할 수 있으며, React, Vue, Svelte 등의 프레임워크와 쉽게 통합할 수 있다. 마지막으로, Vite는 개발 서버에서 자동으로 필요한 모듈을 가져오고, 의존성을 실시간으로 처리하므로 더 빠른 피드백 루프를 제공한다.
이러한 특징들 덕분에 Vite는 현대적인 프론트엔드 개발 환경에서 점점 더 널리 사용되고 있다.
Babel이란
Babel is a JavaScript compiler.
공식 사이트에 의하면 바벨은 JavaScript 컴파일러이다.
Babel은 주로 ECMAScript 2015+ (ES6 ~ ) 코드를 현재 및 이전 브라우저나 환경에서 이전 버전과 호환되는 JavaScript 버전으로 변환하는 데 사용되는 툴체인으로 크로스 브라우징 이슈를 해결해준다.
크로스 브라우징: 웹 애플리케이션 다양한 버전에서 개발자의 의도대로 작동하도록 하는 기술을 말한다. (호환성)
babel-polyfill
구형 브라우저에서 기본적으로 지원하지 않는 최신 JavaScript 기능(예: Promise, Array.includes)을 제공하기 위한 코드다. Babel은 최신 ES6+ 문법을 ES5로 변환하여 구형 브라우저에서도 작동할 수 있게 해주지만, 최신 기능 지원이 부족하다. 이때 polyfill이 필요한데, polyfill은 해당 브라우저가 이해하지 못하는 최신 API나 기능을 구현하여 브라우저가 이를 지원할 수 있도록 도와주는 역할을 한다.
모듈
- @babel/core: Babel의 핵심 모듈로, 자바스크립트 코드를 변환하는 역할.
babel/polyfill의 전역 오염 문제와, 바벨 런타임 플러그인의 인스턴스 메소드 문제를 모두 해결했다. - @babel/cli: 명령행 인터페이스(Command Line Interface)를 제공하여 CLI에서 Babel을 사용할 수 있게 하는 역할
- @babel/preset-env: 다양한 브라우저와 환경에서 사용 가능한 자바스크립트 코드를 생성할 수 있도록 환경 설정 제공
- @babel/plugin-transform-react-jsx: JSX 문법을 변환할 수 있도록 해주는 플러그인