Quick differences to note:
Rollup has node polyfills for import/export, whereas webpack doesn’t
Rollup has support for relative paths, whereas webpack does not, so we either use path.resolve or path.join
Rollup requires you have modules set to false on es2015 presets, because it will process modules as ES2015 if it can and do scope hoisting magic before transpiling the module.
Let’s take a very simple example:
What would you expect the output of this be?
This is arguably where Rollup shines. For simpler modules, it returns a very efficiently transformed, minimal bundle, whereas Webpack has a lot of magic™ included in the bundle.
bundle.rollup.js — ~245 bytes
bundle.webpack.js — ~4108 bytes
In the Webpack bundle, the actual imports occur on around line ~100. If you navigate to this point, you will see that the actual module code is mostly the same (below), with the biggest difference being that in the Webpack bundle, each module is wrapped in a function which can be internally invoked. This is why Webpack bundles are considered to be ‘safer’ for larger/more complex applications.
A lot of the mess is removed in production mode builds and the bundle size.
So, how do you tell which one is right for you? In recent history, the conventional wisdom has been:
“Use webpack for apps, and Rollup for libraries”
However, it’s becoming more difficult to justify this as a rule. Webpack enhancements have really levelled the playing field in terms of general bundling efficiency, and Rollup recently added code splitting (the major lacking features between the two).
To make a real life parallel, I’d compare this bundler battle to the product design theory called the “Kano model”. The Kano model essentially states that “over time, delightful innovation becomes another basic need”.
Take for example the arrow on the fuel gauge of a car to indicate which side to face the fuel pump (figure 1). When the idea was conceived, it was considered to be a great innovation, however, now it is simply an expectation amongst users.
To see the real differentiating features, we have to go back to the wild west of 2016.
Rollup (circa 2016)
- Tree shaking (live code inclusion / dead code elimination)
- esnext:main entry in package.json to import es2015+ (renamed to ‘module’)
- Scope hoisting
- Simple API
- Limited support for alternative file type loading (css, images etc)
- No code splitting
Webpack (circa 2016)
- Advanced support for CSS/HTML/image loading
- Code splitting
- Hot module replacement for super fast dev builds
- No tree shaking
- No Scope hoisting
- No native support for ES2015+ modules
- Complicated API
A lot has changed since then (the above is not an exhaustive list, and both of the libraries have additional pros and cons I couldn’t possibly list), and both libraries have taken cues from one another. The community surrounding both libraries has also grown which has helped accelerate the implementation of novel features.
Rollup (now) — What’s changed?
- Rich ecosystem of plugins for file loading/dev servers
- Code splitting (Added 8th of Feb 2018 after a 2 year wait! 🎉🎉)
Webpack (now) — What’s changed?
- Tree shaking & ES2015+ module support (Added in Webpack 2)
- Scope hoisting (Added in Webpack 3)
- Support for esnext:main / module
In my opinion, you should still probably prefer Rollup for libraries, but the option of using Rollup for large apps is much more realistic now. One thing’s for sure, both Webpack and Rollup are here to stay. I’d say the main reason for the staying power of these two libraries is the amazing internal teams and the unending effort they put into maintaining them and answering issues and StackOverflow questions.
For a more detailed comparison of the internals of the two libraries, Rich Harris (creator of Rollup) has a great writeup here.
BONUS: A challenger approaches
parcel index.html and have a fancy dev server running in moments. It also brags that it has blistering fast bundle speeds (though their comparison table omits a Rollup comparison, so I can only assume they are similar).
If Parcel proves to have the staying power as Webpack/Rollup, I’m sure we’ll see many of the zero configuration features bubble to the surface in those libraries.