번들러에 대해서 이야기 하기 전에 번들러가 나오게 된 배경에 대해 먼저 알아보자.
예전에는 HTML,CSS,JS 파일을 각각 만들어서 서버에 올리는 방식으로 웹개발을 했다.
그런데 이 방식은 의존성이 있는 코드 사이에 순서를 보장하기는 어렵고,
여러 개의 파일을 로드할 때 일부 파일의 문제로 전체 스크립트를 실행하지 못할 수도 있다는 문제가 있었다.
그래서 이런 문제를 해결하기 위해 모듈 단위의 개발 방식이 등장하게 되었다.
그렇게 JS 라이브러리들이 생겨났고, 이를 쉽게 설치할 수 있게 도와주는 NPM을 사용하기 시작했다.
NPM은 많이들 알고 있듯이, JS 라이브러리를 모아놓은 플랫폼이고, 명령어를 이용해서 라이브러리 설치가 가능하다. 패키지를 설치하게 되면 node_modules
라는 폴더가 생성되는데 여기에는 라이브러리 소스코드가 전부 들어오게 된다. 그럼 우리는 라이브러리를 import
만 한다면 라이브러리를 쉽게 사용할 수 있게 된다.
그런데 이 과정에서 문제 2가지가 있다.
1. node_modules 폴더 용량이 너무 큼
첫번째는 패키지를 설치하면 나오게 되는node_modules
폴더의 용량이 몇 10MB 정도로, 너무 크다는 점이다. 이렇게 용량이 큰 폴더를 그대로 서버에 배포하면 너무 비효율적일 것이다.
2. import/require 문법은 브라우저 친화적이지 않음
두번째 문제는 라이브러리를 불러오기 위해 사용하는 import/require 문법을 브라우저 상에서 사용하기 힘들다는 것이었다. (그 당시)
그래서 이런 문제들을 해결하기 위해 우리는 번들링 이라는 과정을 거친다
우리가 의존하고 있는 라이브러리 파일, 즉 JS 파일을 하나로 합쳐주는 과정을 번들링이라고 한다.
번들러는 이러한 의존성이 있는 모듈 코드를 브라우저 환경에서 잘 실행될 수 있도록 가공 및 조합해서 병합된 하나의 결과물을 만들어준다.
번들러란?
웹 어플리케이션을 개발하기 위해 필요한 HTML, CSS, JS 등의
모듈화된 자원들을 모아서 하나의 파일로 결합(번들링)하는 도구
번들러를 사용하면 위의 두가지 문제를 해결할 수 있을 뿐만 아니라 추가적인 장점도 있다.
결국 npm을 이용한다면 반필수적으로 번들링 툴도 같이 이용해야 한다.
이런 번들링 툴 중 가장 유명한게 webpack 인데 아래의 예시처럼 사용하기는 너무 쉽다.
ex) 웹팩을 사용해서 번들링 해보자
- 번들링 :
npm run build
(dist 번들 파일 생성)- 실시간 번들링 :
npx webpack serve
(브라우저로 실시간 미리보기 생성)
그렇지만 라이브러리를 많이 필요로 하는 큰 프로젝트를 개발하게 된다면
웹팩은 번들링 시간이 굉장히 오래 걸린다는 문제가 있다.
그래서 이런 문제를 해결하기 위해 2세대 번들링 툴들, Vite와 Snowpack 등 이 나왔다.
이중에서 이번에는 많이 사용하는 번들링 툴인 Webpack, Rollup, Parcel, 그리고 Vite에 대해 알아보고 비교해보자.
웹팩은 번들링과 컴파일을 결합하는 정적 모듈 번들러
Node.js 기반의 JavaScript 모듈 번들러
2017년에 나온 웹 어플리케이션 번들러로, 웹팩에 비해 매우 늦게 나왔지만 웹팩보다 빠르고 설정이 필요없다는 점이 큰 특징이다.
Vue.js의 창시자인 Evan You가 만든 FrontEnd build tool
Node.js를 기반으로 하는 JavaScript 모듈 번들러
ESBuild의 단점을 보완시킨 라이브러리
개발 서버 구동 시간이 거의 0에 가까울 정도로 빠른 속도가 특징이다
프로젝트가 아무리 커져도 엄청 빠르게 번들링이 가능한데
npm create vite
로 CRA를 대신함<link>
태그를 이용해 분리된 CSS 코드를 불러오게끔 하며, CSS가 모두 계산된 후에 청크를 렌더링<link ref="modulepreload">
디렉티브를 이용해 미리 모듈을 캐싱하도록 자동으로 변환A
를 가져올 때 C
청크를 병렬적(Parallel)으로 가져올 수 있도록 Dynamic Import 구문을 자동으로 재작성이제 이 네가지 bundler 들을 비교해보자.
결론을 먼저 이야기 하자면 이렇게 된다.
- 빠른 빌드 속도를 원한다면, Vite
- 복잡한 설정을 피하고 간단한 애플리케이션을 빠르게 만들고 싶다면, Parcel
- 최소한의 서드파티로 라이브러리를 만들고 싶다면, Rollup
- 많은 서드파티를 필요로 하는 복잡한 애플리케이션에는 Webpack 을 추천한다.
Webpack | Rollup | Parcel | Vite | |
---|---|---|---|---|
빌드 속도 | 느린편 (3) | 빠른편 (2) | 매우 빠름 (1) | 매우 빠름 (1) |
Configuration | 복잡한 설정 필요 | 간단한 설정 | 매우 쉬움 (Zero-configuration) | 쉬움 (기본설정 제공) |
Polyfill 지원 | △ 플러그인, 로더 필요 | △ 플러그인 필요 | O 자동 제공 | △ 플러그인 필요 |
상대경로 지원 | X | O | O | O |
Transformations | loader 사용 | 때때로 많은 Plugin 필요 | zero-config 로 별도 설정 필요 없음 | |
Tree-shaking | △ (ES6 모듈에서만 지원) | O 강력함 (코드를 정적으로 분석, 사용하지 않는 코드 제거) | O (ES6및 CommonJS 모듈 모두 지원) | O (Rollup을 기반으로 함) |
Code splitting | O | O 최적화 | O (비동기적으로 로드됨) | O |
개발 시 변경 사항 즉시 확인 | O 안전하다 | O | O | O |
HMR(Hot Module Replacement) | O 안전하다 | O | O | O (ESM을 이용) |
Caching | 일부 캐싱 | 없음 (브라우저 캐싱 전략 사용) | 전체 캐싱 | 변경된 파일만 갱신 |
지원 라이브러리 | 다양한 라이브러리와 플러그인 지원 | 비교적 적음 | 최근 도입, 비교적 적음 | 비교적 많이 제공하지 않음 |
장점 | 플러그인, 로더 생태계 매우 풍부함 | 라이브러리, 프레임워크 개발에 적합, 강력한 tree-shaking 기능 | 설정 필요없음, 빠른 빌드 속도 제공 (초기 빌드, HMR에서 특히 빠름) | 매우 빠른 속도(개발 서버, 빌드 도구), 간단한 설정, 브라우저 직접 로드 |
단점 | 설정 복잡, 초기 빌드 속도 느림 | 파일 형식 호환성과 플러그인 생태계가 작음 | 복잡한 프로젝트에서는 설정하기 어려움 | 사용자 적음, 플러그인 생태계 없음,특수한 설정 어려움 |
Polyfill (MDN)
기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드(일반적으로 JavaScript)폴리필은 본직적으로 JavaScript 개발자에게 모든 브라우저에서 작동하는 단일 공통 API를 제공할 수 있도록 기본적으로 브라우저 별 해결방법을 모아둔 것이다.
Promise
나 Set
객체와 같은 최신 JavaScript 기능이 구형 브라우저에서 지원되지 않는 경우, polyfill을 사용하여 해당 기능을 구현할 수 있다.Javascript 이외의 파일을 처리하기 위해서는 Javascript 형식으로 파일을 변환한 후, Bundler로 전달을 해주어야 한다.
Tree-shaking (MDN)
사용되지 않는 코드를 제거하기 위해 JavaScript 컨텍스트에서 일반적으로 사용되는 용어이다.
JavaScript 파일 간에 사용하기 위해 코드 모듈을 내보내고 가져올지 여부를 감지하려면 import 및 export 문을 사용한다.
최신 JavaScript 애플리케이션에서 모듈 번들러를 사용하여 여러 JavaScript 단일 파일로 번들링할 때 자동으로 데드 코드를 제거한다. 이러한 과정을 Tree-shaking 이라고 한다.
개발 하는 동안 변경사항을 확인하기 위해 수동으로 새로 고치는 대신 작성한 새로운 코드로 앱을 업데이트 하는 것이 좋다.
wepback-dev-server
를 제공한다. 이는 live-reload를 지원한다.rollup-plugin-serve
를 제공한다.rollup-plugin-livereload
를 설치해야 한다.옛날에는 파일 하나가 수정되면 다시 번들링해서 사이트를 보여줬는데,
요새는 변경 사항만 수정해주는 기술을 이용해서 조금 더 빠르게 번들링해준다.
코드가 실행되는 동안 전체 리로드를 할 필요없이 모듈을 추가, 제거 할 수 있는 기능이다.
webpack-dev-server
를 통해 지원rollup-plugin-hotreload
를 통해 지원