본문 바로가기
javascript

롤업과 웹팩의 차이점 (rollup vs webpack)

by 윤-찬미 2021. 4. 22.

🤩 ui 라이브러리를 만들어 보자~

최근 하고 있는 사이드 프로젝트에들어가는 ui-components 를 라이브러리화 시켜 npm 에 올려 두고 쓰려고
elpo-ui 라는 이름으로 개발을 준비 중입니다.
기존에 프로젝트들에는 늘 웹팩을 사용하여 번들링을 진행했는데, '앱은 웹팩으로 라이브러리는 롤업으로!' 라는 말이 생각나 그 이유가 무엇이며 둘의 차이점을 알아보고자 합니다.
롤업을 도입하기 전에 왜 롤업을 도입하려 하는지 도입 후 얻는 이점이 어떤 것들이 있는지,
그리고 그들의 특성을 이해하고 언제 롤업을, 언제 웹팩을 써야할지 구분하고자 이 글을 작성합니다.

🤩 웹팩과 롤업의 차이점을 알아보자!

Webpack✨은 2012년도에 탄생한 짱짱 번들링도구 입니다.
특히나 spa개발에 있어 webpack은 이제 뗄래야 뗄 수 없는 사이가 되었죠.
서브파티 라이브러리 관리나 css전처리 이미지 에셋관리 등에 있어서 더욱 짱짱(?) 이며 생태계가 가장 풍부하고(다른 번들러들보다 ex) Rollup, Parce..)) 안정적입니다.

webpack이 작동하는 방식은 각 모듈을 함수로 감싸고 로더와 모듈 캐시를 구현하는 번들을 생성합니다.
→ 런타임시에 이제 이러한 각 모듈 함수들이 평가되어 모듈 캐시를 채웁니다.
on-demand loading 이 필요한 경우에는 좋지만, 그렇지 않으면 낭비 이며, 모듈이 많아질 수록 좋은 방법은 아니라 할 수 있습니다. 하지만 각 모듈을함수로 감싸는 방식은 안정적입니다. 이유를 아래에서 설명하겠습니다.

각 모듈을 함수로 감싼다,안정적이다. 이게다 뭔소리야! 하며 어려워 하실 수 있을 것 같습니다. 조금 풀어서 설명하명 '스코프' 와 관련이 있습니다.
전역스코프에 있던 변수를들 지역으로 변경해 줌에 따라 충돌없이 모듈화를 시킬 수 있습니다.
아래 두개의 코드가 있고, 이를 웹팩을 통해 번들링해보겠습니다.
some-file.js

export default 10;


index.js

import multiplier from './some-file.js'; export function someMaths() { console.log(multiplier); console.log(5 * multiplier); console.log(10 * multiplier); }

bundle.webpack.js
위에서 설명한 것 처럼 각 모듈들이 모듈 캐시를 채웁니다.
그리고 (1) 부분처럼 각 모듈이 함수로 랩핑되어 지역변수로 만들어 줍니다.

module.exports = /******/ (function(modules) {
// webpackBootstrap /******/ // 여기는 모듈 캐시!/******/
var installedModules = {}; /******/ /******/
// The require function /******/
function __webpack_require__(moduleId) {
/******/ /******/ // Check if module is in cache /******/
if(installedModules[moduleId]) {
	/******/ return installedModules[moduleId].exports; /******/ } 
    /******/ // Create a new module (and put it into the cache)
    /******/ var module = installedModules[moduleId] = { 
    /******/ i: moduleId, /******/ l: false, /******/ exports: {} ......... // (1) (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.someMaths = someMaths; var _someFile = __webpack_require__(1); var _someFile2 = _interopRequireDefault(_someFile); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj}; } function someMaths() { console.log(_someFile2.default); console.log(5 * _someFile2.default); console.log(10 * _someFile2.default); } }), (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = 10; }) )


Rollup✨ 도 알아보겠습니다.
롤업의 작동 방식은 웹팩이랑 차이를 보입니다. 각 모듈들을 함수로 감싸 평가하는 웹팩과 달리 롤업은 코드들을 동일한 수준으로 올립니다. (호이스팅) 그 후 한번에 번들링을 진행하는데 "한번에" 하기 때문에 속도는 웹팩보다 빠르며, 번들링된 결과물도 훨씬 가볍습니다. 또한 가장 큰 특징 중 하나는 ES6모듈 형태로 빌드 결과물을 출력할 수 있으므로 라이브러리나 패키지에 활용 할 수 있다는 것 입니다.
여러분이 많이들 알고 계신 많은 라이브러리들은 롤업을 이용해 번들링을 진행하고 있습니다.(ex) Vue)
아래는 위코드를 롤업으로 번들링한 결과 입니다.
bundle.rollup.js

'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var multiplier = 10; function someMaths() { console.log(multiplier); console.log(5 * multiplier); console.log(10 * multiplier); } exports.someMaths = someMaths;

한눈에 봐도 결과물이 매우 가볍다는게 느껴지지 않나요?

그렇다면 변수충돌에 대한 문제는 롤업에서 어떻게 다루고 있을까요?
💡 바로 상황에 따라 식별자를 변경해 충돌을 방지하고 있습니다.
어? 그러면 롤업이 훨씬 가볍고 빠른데, 그럼 웹팩 필요없는거 아니야? 하실 수도 있겠습니다만,
절대 아닙니다. 웹팩에서 제공해주는 개발서버 가 다른 번들러에 비해 뛰어날 뿐만 아니라, 성능면에서 롤업이 더 빠를 순 있지만 웹팩이 훨씬 안정적입니다.

 

🤗 앱에는 웹팩 사용, 라이브러리에는 롤업 사용

코드 스플릿팅이 필요하거나 static assets 이 많은경우, 안정성이 추구된다던지, CommonJS 종속성이 많은 무언가를 번들링 하려고 할땐 웹팩이 더 나은 선택이라 할 수 있구,
ES6모듈이고 다른 사람들이 사용하는 무언가(라이브러리) 를 만들고 있다면 Rollup이 더욱 잘 맞는다고 말할 수 있을 것 같습니다.