Webpack에서 Rollup 전환기
앞서 Webpack에서 Tree Shaking
을 적용하면서 컴포넌트 용량을 줄이는데 큰 도움을 줬습니다.
Tree Shaking 이외 용량을 줄이는 방법이 또 있는지 조사를 하다가 Rollup
이라는 번들러를 찾았습니다.
Rollup도 Webpack과 마찬가지로 크고 복잡한 코드의 모듈(파일)들을 라이브러리나 어플리케이션으로 작게 만들어 주는 번들러입니다.
Webpack의 문제점이자 Rollup의 사용하게된 계기는 다음과 같습니다.
- Webpack은 ESM(ES Module)형태의 번들이 불가능합니다.
- Webpack에서 빌드할 시 중복 코드 제거가 되지 않습니다.
- Webpack에서 빌드할 시 기본 용량이 큽니다.
- Webpack3에서 Tree Shaking이 잘 이루어지지 않습니다.
Rollup을 사용하면 뭐가 좋을까?
1.ESM형태로 번들이 가능합니다.
Tree Shaking 조건은 코드가 ESM형태여야 하지만 Webpack은 ESM형태로 번들할 수 없기 때문에 각각의 파일로 변환해야 합니다.
Rollup 은 여러 모듈(파일)을 한 모듈로 합치면서 ESM 형태로 번들이 가능합니다.
이를 통해 개별 파일로 배포하는 것보다 파일 하나로 통합되기 때문에 관리 및 사용 편의성도 높아집니다.
2.모듈간의 import/export과정이 사라지기 때문에 중복되는 코드가 제거됩니다.
Webpack 에서는 import
는 __webpack_require__
로 바뀌고 export
는 exports 오브젝트
로 바뀌면서 코드가 증가합니다. 그래서 상수를 사용하면 상수 이름을 그대로 쓰고 uglify가 되지 않기 때문에 오히려 코드가 증가할 수 있습니다.
- 여러 모듈을 한 모듈로 합치게 된다면 용량을 많이 줄일 수 있습니다.
rollup 은 여러 개의 모듈을 하나의 scope 로 합쳐진 단일 모듈로 만듭니다. 그리고 상수 이름도 uglify가 되기 때문에 코드가 감소합니다.
Webpack에서도 ModuleConcatenationPlugin
이 있어 Rollup과 비슷한 효과를 볼 수 있습니다. 하지만 typescript, babel 플러그인을 통해 생긴 함수의 중복은 제거할 수 없습니다.
대표적인 예로 assign
, extends
등과 같이 ES6 이상의 문법을 ES5로 바꾸면서 생기는 polyfill이 있습니다. 이 함수는 파일(모듈)마다 존재하고 각자 다른 함수로 인식해 파일 개수만큼 늘어납니다.
위 코드는 Webpack으로 빌드할 시 똑같은 extends
함수가 세 개가 추가됩니다. 반면 Rollup 은 하나의 모듈로 합치고 동일한 polyfill 은 하나만 존재합니다.
3. 빌드하면서 생긴 코드가 Webpack보다 적습니다.
- Webpack으로 빌드할 시 생기는 기본 코드
- Rollup으로 빌드할 시 생기는 기본 코드
Webpack 과 Rollup 기본 코드 용량 차이는 1.2kb 정도 됩니다.
4. Webpack3에서도 Tree Shaking이 잘 됩니다.
Webpack3에서 Tree Shaking이 되지 않는 이유 중 하나는 import한 모듈을 사용한 함수를 사용하지 않는 경우
입니다.
b 함수에서 외부 a 함수를 사용했지만 실제로 b함수를 호출하지 않더라도 Webpack3 에서는 b 가 a 를 참조했다고 판단하기 때문에 Tree Shaking 이 이루어 지지 않습니다.
하지만 Rollup은 여러 모듈을 한 모듈로 합치기 때문에 이 경우를 해결할 수 있습니다.
Rollup 설정 예시
복잡한 Webpack 설정에 비해 Rollup 은 기본 설정이 매우 간단합니다.
다음 파일들은 egjs 에서 적용한 Rollup 설정 파일 예제입니다.
- https://github.com/naver/egjs-component/blob/master/rollup.config.js
- https://github.com/naver/hammer.js/blob/master/rollup.config.js
- https://github.com/naver/egjs-axes/blob/master/rollup.config.js
- https://github.com/naver/egjs-flicking/blob/master/rollup.config.js
단점
1.entry(input, output)가 많아질수록 복잡해질 수 있습니다.
예시 코드를 보면 entry이 적으면 config작성이 Webpack보다 쉬울 수 있습니다.
하지만 entry가 많아지면 옵션을 중복으로 써야 하므로 복잡해집니다.
component
, axes
, flicking
에서는 default config를 설정해서 복잡함을 줄였습니다.
2.plugin의 규칙을 정할 수 없습니다.
Webpack은 정규식이나 파일 이름의 패턴으로 plugin을 활성화 / 비활성화 할 수 있습니다. 하지만 Rollup은 규칙을 정할 수 없기 때문에 각각의 entry마다 plugin 목록을 지정해줘야 합니다.
Webpack 에서 Rollup 으로 전환한 결과
다음 3개의 프로젝트에서 Weback에서 Rollup으로 전환을 했습니다.
component
같은 경우 기본 코드가 줄어들었고 Axes
는 Hammer
의 일부분만 사용하고 Flicking
도 Axes
의 일부분만 사용하고 한 모듈로 합쳐지기 때문에 용량을 크게 줄일 수 있었습니다.
용량을 개선하는데 다양한 방법이 있고 그 중 하나인 Webpack에서 Rollup으로 번들러를 바꿨을 때 얻는 장점을 소개했습니다. 용량 절감으로 고민하시는 분들께 조금이라도 참고가 되셨으면 좋겠습니다.