Webpack에서 Rollup 전환기

앞서 Webpack에서 Tree Shaking을 적용하면서 컴포넌트 용량을 줄이는데 큰 도움을 줬습니다.

Tree Shaking 이외 용량을 줄이는 방법이 또 있는지 조사를 하다가 Rollup이라는 번들러를 찾았습니다.

https://rollupjs.org/guide/en

Rollup도 Webpack과 마찬가지로 크고 복잡한 코드의 모듈(파일)들을 라이브러리나 어플리케이션으로 작게 만들어 주는 번들러입니다.

Webpack의 문제점이자 Rollup의 사용하게된 계기는 다음과 같습니다.

  1. Webpack은 ESM(ES Module)형태의 번들이 불가능합니다.
  2. Webpack에서 빌드할 시 중복 코드 제거가 되지 않습니다.
  3. Webpack에서 빌드할 시 기본 용량이 큽니다.
  4. Webpack3에서 Tree Shaking이 잘 이루어지지 않습니다.

Rollup을 사용하면 뭐가 좋을까?

1.ESM형태로 번들이 가능합니다.

Tree Shaking 조건은 코드가 ESM형태여야 하지만 Webpack은 ESM형태로 번들할 수 없기 때문에 각각의 파일로 변환해야 합니다.

각각의 ts 파일마다 es 모듈 형태로만 변환 가능

Rollup 은 여러 모듈(파일)을 한 모듈로 합치면서 ESM 형태로 번들이 가능합니다.

Rollup 에서는 하나의 es 모듈로도 변환 가능

이를 통해 개별 파일로 배포하는 것보다 파일 하나로 통합되기 때문에 관리 및 사용 편의성도 높아집니다.

2.모듈간의 import/export과정이 사라지기 때문에 중복되는 코드가 제거됩니다.

Webpack 에서는 import__webpack_require__로 바뀌고 exportexports 오브젝트로 바뀌면서 코드가 증가합니다. 그래서 상수를 사용하면 상수 이름을 그대로 쓰고 uglify가 되지 않기 때문에 오히려 코드가 증가할 수 있습니다.

  • 여러 모듈을 한 모듈로 합치게 된다면 용량을 많이 줄일 수 있습니다.

rollup 은 여러 개의 모듈을 하나의 scope 로 합쳐진 단일 모듈로 만듭니다. 그리고 상수 이름도 uglify가 되기 때문에 코드가 감소합니다.

Webpack에서도 ModuleConcatenationPlugin이 있어 Rollup과 비슷한 효과를 볼 수 있습니다. 하지만 typescript, babel 플러그인을 통해 생긴 함수의 중복은 제거할 수 없습니다.

대표적인 예로 assign, extends 등과 같이 ES6 이상의 문법을 ES5로 바꾸면서 생기는 polyfill이 있습니다. 이 함수는 파일(모듈)마다 존재하고 각자 다른 함수로 인식해 파일 개수만큼 늘어납니다.

Webpack 에서는 각 세 개의 모듈에 대해서 각각 polyfill 이 생성

위 코드는 Webpack으로 빌드할 시 똑같은 extends함수가 세 개가 추가됩니다. 반면 Rollup 은 하나의 모듈로 합치고 동일한 polyfill 은 하나만 존재합니다.

3. 빌드하면서 생긴 코드가 Webpack보다 적습니다.

  • Webpack으로 빌드할 시 생기는 기본 코드
Webpack Default Code
  • Rollup으로 빌드할 시 생기는 기본 코드
Rollup Default Code

Webpack 과 Rollup 기본 코드 용량 차이는 1.2kb 정도 됩니다.

4. Webpack3에서도 Tree Shaking이 잘 됩니다.

Webpack3에서 Tree Shaking이 되지 않는 이유 중 하나는 import한 모듈을 사용한 함수를 사용하지 않는 경우입니다.

b 함수에서 a 함수를 사용했지만 실제로 b 함수를 사용하지 않는 경우

b 함수에서 외부 a 함수를 사용했지만 실제로 b함수를 호출하지 않더라도 Webpack3 에서는 b 가 a 를 참조했다고 판단하기 때문에 Tree Shaking 이 이루어 지지 않습니다.

b함수는 a 함수를 사용했지만 외부가 아닌 내부 모듈이 된 경우

하지만 Rollup은 여러 모듈을 한 모듈로 합치기 때문에 이 경우를 해결할 수 있습니다.

Rollup 설정 예시

복잡한 Webpack 설정에 비해 Rollup 은 기본 설정이 매우 간단합니다.

다음 파일들은 egjs 에서 적용한 Rollup 설정 파일 예제입니다.

단점

1.entry(input, output)가 많아질수록 복잡해질 수 있습니다.

예시 코드를 보면 entry이 적으면 config작성이 Webpack보다 쉬울 수 있습니다.

multi entries

하지만 entry가 많아지면 옵션을 중복으로 써야 하므로 복잡해집니다.

component, axes, flicking에서는 default config를 설정해서 복잡함을 줄였습니다.

2.plugin의 규칙을 정할 수 없습니다.

Webpack은 정규식이나 파일 이름의 패턴으로 plugin을 활성화 / 비활성화 할 수 있습니다. 하지만 Rollup은 규칙을 정할 수 없기 때문에 각각의 entry마다 plugin 목록을 지정해줘야 합니다.

Webpack 에서 Rollup 으로 전환한 결과

다음 3개의 프로젝트에서 Weback에서 Rollup으로 전환을 했습니다.

from Webpack to Rollup

component같은 경우 기본 코드가 줄어들었고 AxesHammer의 일부분만 사용하고 FlickingAxes의 일부분만 사용하고 한 모듈로 합쳐지기 때문에 용량을 크게 줄일 수 있었습니다.

용량을 개선하는데 다양한 방법이 있고 그 중 하나인 Webpack에서 Rollup으로 번들러를 바꿨을 때 얻는 장점을 소개했습니다. 용량 절감으로 고민하시는 분들께 조금이라도 참고가 되셨으면 좋겠습니다.

NAVER FE Platform

NAVER Front End Story

NAVER FE Platform

NAVER Front End Story

Daybrush (Younkue Choi)

Written by

A Front-end Engineer at NAVER / Daybrush https://daybrush.com

NAVER FE Platform

NAVER Front End Story