Bundler (Webpack, Rollup, Vite, Parcel) 를 비교해보자

yiwoojung·2024년 6월 4일
3

JavaScript

목록 보기
2/4
post-thumbnail

Bundler가 왜 필요해?

코딩애플 | 와 Vite 쓰면 리액트 10배 빨라짐 (과장아님)

번들러에 대해서 이야기 하기 전에 번들러가 나오게 된 배경에 대해 먼저 알아보자.

예전에는 HTML,CSS,JS 파일을 각각 만들어서 서버에 올리는 방식으로 웹개발을 했다.
그런데 이 방식은 의존성이 있는 코드 사이에 순서를 보장하기는 어렵고,
여러 개의 파일을 로드할 때 일부 파일의 문제로 전체 스크립트를 실행하지 못할 수도 있다는 문제가 있었다.
그래서 이런 문제를 해결하기 위해 모듈 단위의 개발 방식이 등장하게 되었다.
그렇게 JS 라이브러리들이 생겨났고, 이를 쉽게 설치할 수 있게 도와주는 NPM을 사용하기 시작했다.

NPM은 많이들 알고 있듯이, JS 라이브러리를 모아놓은 플랫폼이고, 명령어를 이용해서 라이브러리 설치가 가능하다. 패키지를 설치하게 되면 node_modules 라는 폴더가 생성되는데 여기에는 라이브러리 소스코드가 전부 들어오게 된다. 그럼 우리는 라이브러리를 import 만 한다면 라이브러리를 쉽게 사용할 수 있게 된다.

그런데 이 과정에서 문제 2가지가 있다.

1. node_modules 폴더 용량이 너무 큼

첫번째는 패키지를 설치하면 나오게 되는node_modules 폴더의 용량이 몇 10MB 정도로, 너무 크다는 점이다. 이렇게 용량이 큰 폴더를 그대로 서버에 배포하면 너무 비효율적일 것이다.

2. import/require 문법은 브라우저 친화적이지 않음

두번째 문제는 라이브러리를 불러오기 위해 사용하는 import/require 문법을 브라우저 상에서 사용하기 힘들다는 것이었다. (그 당시)

bundle_your_assets

그래서 이런 문제들을 해결하기 위해 우리는 번들링 이라는 과정을 거친다
우리가 의존하고 있는 라이브러리 파일, 즉 JS 파일을 하나로 합쳐주는 과정을 번들링이라고 한다.

번들러는 이러한 의존성이 있는 모듈 코드를 브라우저 환경에서 잘 실행될 수 있도록 가공 및 조합해서 병합된 하나의 결과물을 만들어준다.

번들러란?

웹 어플리케이션을 개발하기 위해 필요한 HTML, CSS, JS 등의
모듈화된 자원들을 모아서 하나의 파일로 결합(번들링)하는 도구


번들러를 사용하면 어떤게 좋은데?

번들러를 사용하면 위의 두가지 문제를 해결할 수 있을 뿐만 아니라 추가적인 장점도 있다.

  • 꼭 필요한 코드만 찝어서 합쳐준다. => 용량 절약
  • 파일 하나로 합쳐주기 때문에 import/require이 필요없다. => 결과물은 JS 파일 하나임
  • 모듈화된 코드를 브라우저에서 실행할 수 있도록 Bundle을 생성해준다.
  • HTTP 요청 수를 줄여서 웹 로딩 속도를 개선할 수 있다.
    • 리소스가 많아지면 로딩 속도가 저하되는데, 번들러를 사용하면 이러한 이슈를 해결할 수 있다.
  • 코드 축소, Hot Reloading, 코드 분할 등 여러 기능을 제공한다.

npm + bundle tools

npm+bundle_tools

결국 npm을 이용한다면 반필수적으로 번들링 툴도 같이 이용해야 한다.
이런 번들링 툴 중 가장 유명한게 webpack 인데 아래의 예시처럼 사용하기는 너무 쉽다.

ex) 웹팩을 사용해서 번들링 해보자

  • 번들링 : npm run build (dist 번들 파일 생성)
  • 실시간 번들링 : npx webpack serve (브라우저로 실시간 미리보기 생성)

그렇지만 라이브러리를 많이 필요로 하는 큰 프로젝트를 개발하게 된다면
웹팩은 번들링 시간이 굉장히 오래 걸린다는 문제가 있다.


그래서 이런 문제를 해결하기 위해 2세대 번들링 툴들, Vite와 Snowpack 등 이 나왔다.

이중에서 이번에는 많이 사용하는 번들링 툴인 Webpack, Rollup, Parcel, 그리고 Vite에 대해 알아보고 비교해보자.


Webpack


웹팩은 번들링과 컴파일을 결합하는 정적 모듈 번들러
Node.js 기반의 JavaScript 모듈 번들러


Webpack 특징이 뭐야?

  1. 다양한 모듈 형식 지원
    • CommonJS, AMD, ES6Module 포맷을 모두 지원한다.
  2. Tree-shaking
    • ES6 모듈에서만 지원
    • 코드 축소와 더불어 사용하지 않는 코드를 제거하고, 번들 크기를 줄이는 등의 성능 최적화를 함으로써, HTTP 요청 수를 감소하여 웹 사이트 성능을 궁극적으로 향상시킨다.
  3. 코드 분할 Code Splitting
    • 초기 로딩 시간을 줄여준다.
      • 번들러를 사용하게되면 많은 리소스가 하나의 파일로 병합되면서 초기 로딩 비용이 커질 수 있는데, 웹팩은 청크, 캐시, 코드 스플릿과 같은 기능를 도입하여 이러한 이슈를 해결하였다.
    • 필요할 때만 필요한 코드 청크를 로드할 수 있게 하여 성능을 최적화한다.
    • Dynamic Loading & Lazy Loading 이 가능하다.
    • 대규모 애플리케이션에서 유용하다.
  4. 로더 Loader
    • 번들러가 다양한 유형의 파일을 처리할 수 있도록 도와주는 도구
    • 특정 파일 유형을 처리하고 변환한다.
    • 자바스크립트 뿐만 아니라 CSS, Image 파일 등 다양한 리소스를 관리할 수 있다.
    • 일반적으로 파일 확장자를 기준으로 동작하며, 설정 파일(webpack.config.js)에서 파일 유형별로 로더를 지정한다.
    • 로더를 사용해서 리소스를 관리함으로써 웹 페이지 로딩 속도를 개선할 수 있다.
  5. 플러그인 Plugin
    • 번들링 과정의 다양한 단계에 맞춰 작업을 수행하여 번들링의 기능을 확장하는 도구
    • 번들링 과정 전반에 걸쳐 다양한 작업을 수행한다.
    • 주로 번들링 결과물에 대한 후처리를 도와주는 역할을 한다.
    • 예시
      • HtmlWebpackPlugin: HTML 파일을 생성하고, 번들된 자바스크립트 파일을 HTML에 자동으로 포함시킨다.
      • MiniCssExtractPlugin: CSS를 별도의 파일로 추출한다.
      • DefinePlugin: 컴파일 타임에 전역 상수를 정의한다.
  6. 개발 환경 지원 (자동으로 번들링)
    • 개발자가 코드를 변경할 때마다 브라우저를 새로 고침하지 않고도 변경 사항을 즉시 확인할 수 있게 해준다.
    • 개발 속도를 크게 향상시킨다.
  7. 다양한 환경에서 사용 가능
    • 브라우저뿐만 아니라 Node.js, Electron 등 다양한 환경에서도 사용할 수 있다.
  8. HMR (Hot Module Replacement)
    • 코드가 변경되면 이를 감지하고 브라우저에 최신 코드를 반영하여 자동으로 모듈을 교체한다.
    • 전체 다시 로드 없이 애플리케이션이 실행되는 동안 모듈을 교환, 추가 또는 제거한다.

Rollup


Rollup 은 특징이 뭐야?

  1. Code Splitting 과 Tree Shaking
    • 리소스 관리 및 초기 로드 시간이 향상된다.
    • 종속성 그래프를 분석하여 최종 번들에서 사용되지 않는 코드를 제거하여 번들 크기를 줄이고 성능을 향상시킨다.
  2. 확장성을 위한 다양한 플러그인
    • 기능을 확장하고 다양한 개발 요구 사항을 충족하는 풍부한 플러그인 생태계를 갖추고 있다.
  3. 소규모 번들을 위한 최적화된 output
    • 특히 프로덕션 빌드에서 소규모 번들에 대해 최적화된 output을 생성한다.
    • 생성된 번들의 크기를 줄이기 위해 축소, 압축, 코드 분할 등 다양한 최적화 기술을 사용한다.
    • 이로 인해 특히 대역폭이 제한된 네트워크에서 로딩 시간이 빨라지고 end-user 성능이 향상된다.
  4. ES 모듈 번들 효율성에 중점
    • ES 모듈 번들의 효율성 최적화를 강조한다.
    • 기본 ES 모듈 지원과 최신 JavaScript 기능을 활용하여 고도로 최적화된 번들을 생성한다.
    • 필요한 코드만 포함되도록 보장하여 로딩 시간을 단축하고 전반적인 성능을 향상시킨다.

Parcel


2017년에 나온 웹 어플리케이션 번들러로, 웹팩에 비해 매우 늦게 나왔지만 웹팩보다 빠르고 설정이 필요없다는 점이 큰 특징이다.

Parcel 의 특징을 알려줘.

  1. zero-configuration
    • 설정이 딱히 필요없다.
    • 빌드를 위해 번들러를 학습하는 시간을 많이 줄일 수 있다.
    • 웹팩과 달리 Javascript의 엔트리 포인트를 지정해주는 것이 아니라, 애플리케이션 진입을 위한 HTML 파일 자체를 읽는다.
    • HTML 파일을 순서대로 읽어나가면서 JavaScript, CSS, 이미지 에셋 등을 직접 참조한다.
  2. 빠른 빌드 속도
    • 캐싱을 사용하기 때문에 빌드 속도가 웹팩보다 빠르다.
    • 웹팩에 비해 매우 늦게 나왔지만 웹팩보다 빠르다.
  3. Tree-shaking
    • ES6 및 CommonJS 모듈 모두에 대해 Tree-shaking 을 지원한다.
  4. 많은 트랜스파일러 내장
    • 모듈 안의 설정 파일을 발견하면 이를 자동으로 변환하여 실행한다.
  5. HMR (Hot Module Replacement)
    • 코드가 변경되면 이를 감지하고 브라우저에 최신 코드를 반영하여 자동으로 모듈을 교체한다.

Vite


Vue.js의 창시자인 Evan You가 만든 FrontEnd build tool
Node.js를 기반으로 하는 JavaScript 모듈 번들러
ESBuild의 단점을 보완시킨 라이브러리

개발 서버 구동 시간이 거의 0에 가까울 정도로 빠른 속도가 특징이다

프로젝트가 아무리 커져도 엄청 빠르게 번들링이 가능한데

Vite이 이렇게 빠른 이유가 뭘까?

  1. 바로 ESBuild 라이브러리를 사용했기 때문
  2. ESBuild 이용해서 Pre-bundling
    • 라이브러리 설치하자마자 미리 번들 만들어 놓음
  3. 소스코드는 번들링하지 않고 (필요한 것만 건드려서) 실시간 미리보기를 띄워준다
    • 이게 가능한 이유는 요즘 브라우저들은 import 문법을 다 지원해주기 때문
    • 예전처럼 파일을 합치고 그럴 필요가 없다

특징

  • 빠른 속도
    • 개발 서버 구동 시간이 거의 0에 가깝다
    • 프로젝트가 아무리 커져도 엄청 빠르게 번들링 가능
    • ESBuild 를 사용해서 Pre-bundling 하기 때문
  • ESBuild로 파일들을 통합하고 Rollup 을 통해 모듈의 번들링과 변환
  • npm create vite로 CRA를 대신함
  • CSS 코드 분리
    • 비동기적으로 불러와지는 청크 내에 CSS 코드가 포함된 경우, 이를 자동으로 추출해 파일로 분리
    • 이후 해당 청크를 불러올 때 <link> 태그를 이용해 분리된 CSS 코드를 불러오게끔 하며, CSS가 모두 계산된 후에 청크를 렌더링
    • 이 과정을 통해 CSS가 렌더링될 때 화면이 잠깐 반짝이는 현상을 회피할 수 있음
  • Preload Directives Generation
    • 빌드 시 Direct Import 구문에 대해 <link ref="modulepreload"> 디렉티브를 이용해 미리 모듈을 캐싱하도록 자동으로 변환
    • Preload 스텝을 이용해 A를 가져올 때 C 청크를 병렬적(Parallel)으로 가져올 수 있도록 Dynamic Import 구문을 자동으로 재작성
    • Direct Import 구문에 대해 Preload 하도록 함으로써, 쓸 데 없이 낭비되는 네트워크 비용을 줄임



이제 이 네가지 bundler 들을 비교해보자.


📌 Bundler를 어떻게 선택해야 될까?

결론을 먼저 이야기 하자면 이렇게 된다.

  • 빠른 빌드 속도를 원한다면, Vite
  • 복잡한 설정을 피하고 간단한 애플리케이션을 빠르게 만들고 싶다면, Parcel
  • 최소한의 서드파티로 라이브러리를 만들고 싶다면, Rollup
  • 많은 서드파티를 필요로 하는 복잡한 애플리케이션에는 Webpack 을 추천한다.

WebpackRollupParcelVite
빌드 속도느린편 (3)빠른편 (2)매우 빠름 (1)매우 빠름 (1)
Configuration복잡한 설정 필요간단한 설정매우 쉬움 (Zero-configuration)쉬움 (기본설정 제공)
Polyfill 지원△ 플러그인, 로더 필요△ 플러그인 필요O 자동 제공△ 플러그인 필요
상대경로 지원XOOO
Transformationsloader 사용때때로 많은 Plugin 필요zero-config 로 별도 설정 필요 없음
Tree-shaking△ (ES6 모듈에서만 지원)O 강력함 (코드를 정적으로 분석, 사용하지 않는 코드 제거)O (ES6및 CommonJS 모듈 모두 지원)O (Rollup을 기반으로 함)
Code splittingOO 최적화O (비동기적으로 로드됨)O
개발 시 변경 사항 즉시 확인O 안전하다OOO
HMR(Hot Module Replacement)O 안전하다OOO (ESM을 이용)
Caching일부 캐싱없음 (브라우저 캐싱 전략 사용)전체 캐싱변경된 파일만 갱신
지원 라이브러리다양한 라이브러리와 플러그인 지원비교적 적음최근 도입, 비교적 적음비교적 많이 제공하지 않음
장점플러그인, 로더 생태계 매우 풍부함라이브러리, 프레임워크 개발에 적합, 강력한 tree-shaking 기능설정 필요없음, 빠른 빌드 속도 제공 (초기 빌드, HMR에서 특히 빠름)매우 빠른 속도(개발 서버, 빌드 도구), 간단한 설정, 브라우저 직접 로드
단점설정 복잡, 초기 빌드 속도 느림파일 형식 호환성과 플러그인 생태계가 작음복잡한 프로젝트에서는 설정하기 어려움사용자 적음, 플러그인 생태계 없음,특수한 설정 어려움

👻 polyfill이란?

Polyfill (MDN)
기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드(일반적으로 JavaScript)

폴리필은 본직적으로 JavaScript 개발자에게 모든 브라우저에서 작동하는 단일 공통 API를 제공할 수 있도록 기본적으로 브라우저 별 해결방법을 모아둔 것이다.

  • PromiseSet 객체와 같은 최신 JavaScript 기능이 구형 브라우저에서 지원되지 않는 경우, polyfill을 사용하여 해당 기능을 구현할 수 있다.
  • 브라우저 호환성 유지 및 개발자 편의성을 위해서 사용된다.

✨ Transformations (변환)

Javascript 이외의 파일을 처리하기 위해서는 Javascript 형식으로 파일을 변환한 후, Bundler로 전달을 해주어야 한다.

  • Webpack에서는 babel-loader, css-loader 등 과 같이 loader를 사용한다.
  • Rollup은 플러그인을 사용한다. ( axios 같은 경우에는 많은 플러그인을 요구하였다고 합니다.)
  • Parcel은 zero-configuration 특징으로 별도의 설정파일 없이 다양한 변환을 지원한다.

🍃 Tree Shaking (Dead code elimination)

Tree-shaking (MDN)
사용되지 않는 코드를 제거하기 위해 JavaScript 컨텍스트에서 일반적으로 사용되는 용어이다.
JavaScript 파일 간에 사용하기 위해 코드 모듈을 내보내고 가져올지 여부를 감지하려면 import 및 export 문을 사용한다.
최신 JavaScript 애플리케이션에서 모듈 번들러를 사용하여 여러 JavaScript 단일 파일로 번들링할 때 자동으로 데드 코드를 제거한다. 이러한 과정을 Tree-shaking 이라고 한다.


💻 Dev Server

개발 하는 동안 변경사항을 확인하기 위해 수동으로 새로 고치는 대신 작성한 새로운 코드로 앱을 업데이트 하는 것이 좋다.

  • Webpack 은 wepback-dev-server 를 제공한다. 이는 live-reload를 지원한다.
  • Rollup은 Dev Server를 위해 rollup-plugin-serve 를 제공한다.
    live-reload 를 위해서는 추가로 rollup-plugin-livereload 를 설치해야 한다.
  • Parcel은 Dev server가 내장되어 있고, 파일을 변경할 경우 다시 빌드한다.
    그러나 HTTP logging, Hooks, middleware 를 사용할 때 이와 관련된 이슈가 발생한적 있다.

🔥 HMR(Hot Module Replacement)

코딩애플 | 와 Vite 쓰면 리액트 10배 빨라짐 (과장아님)

옛날에는 파일 하나가 수정되면 다시 번들링해서 사이트를 보여줬는데,
요새는 변경 사항만 수정해주는 기술을 이용해서 조금 더 빠르게 번들링해준다.

코드가 실행되는 동안 전체 리로드를 할 필요없이 모듈을 추가, 제거 할 수 있는 기능이다.

  • Webpack ->  webpack-dev-server 를 통해 지원
  • Rollup ->  rollup-plugin-hotreload 를 통해 지원
  • Parcel, Vite는 기본적으로 HMR 지원함



참고

profile
의견이 있으시거나 잘못된 내용을 발견하셨다면 재빨리 댓글 주세요 。•◡•。

0개의 댓글