Rollup is a great bundling tool but is it the one you should use?

Frontend development has its own quirks and that should be considered thoughtfully when choosing your toolset

Paolo Marchezzolo
THRON tech blog
5 min readDec 4, 2018

--

At THRON, we are transitioning from a monolithic architecture to a modular one for our front-end SPA application. The change was triggered by both business goals (making parts of “the monolith” available to our development partners) and internal ones (simplify codebase, improve maintainability and improve automated testing).

In this context, tooling needs to change to accommodate the new structure. Our build/bundle process (i.e. the steps that transform raw code/assets into a package that a web browser can understand and execute) was relatively simple and did not do much besides concatenating Javascript files, minificating, and automating some tasks like sprites generation. It now needs to take modularity into account, which demands a more complex approach with different requirements. We needed to create a new bundling workflow that…

  • allows us to focus on small, reusable libraries that can be used on their own or composed into more complex applications;
  • keeps the compiled size as small as possible, avoiding duplication between complex dependency hierarchies and using modern techniques like tree shaking (which is basically a fancy definition for dead code elimination);
  • works well with latest ES6+ technologies and features, and painlessly integrates with our framework of choice (Vue.js).

Considering alternatives

We excluded using a task-runner based approach before even starting to evaluate alternatives. Using gulp/grunt and assembling a build pipeline ourselves would allow us to reuse some of our team’s expertise; however, it is more complex to maintain, less supported by the Vue community, and you end up re-implementing or hacking together features that other tools already provide out-of-the-box. We then looked into the more modern approach of module bundlers, that already implement many of the required features and are more actively developed and used by the Vue community. We considered the following alternatives:

  • Webpack: widely adopted and much more consolidated, it lacks however one key feature: exporting in ES2015 module format, which enables tree shaking for the end-user;
  • Rollup: much newer alternative, adoption and community are smaller although improving rapidly; however, the full support for the ES2015 module format makes it the best candidate for our needs.

As Rich Harris, the creator of Rollup says, “Use webpack for apps, and Rollup for libraries”, and since we need to produce module libraries, Rollup it is!

Rollup is great…

We are happy with the results we obtained. Rollup handled quite well our new, fairly complex build phase (which involves type-checking with flow.js, eslint check/autofix, SASS compilation, Vue single-file components handling, icon-font generation, sprite generation, babel transpiling and export into multiple output formats).

Our bundling pipeline

Tree shaking has proven itself priceless for our current architecture: it is quite common to use just parts of a module in another module, and tree shaking allows us to not worry about dead code inclusion or to be forced to fragment our codebase too much. Furthermore, libraries like Lodash or Date-fns can be “trimmed down” to just what we need without any developer intervention. While we cannot compare the final bundle size between before and after the refactor yet, we expect a considerable improvement in both size and load/execute time. We were also impressed by the pace at which the community responded to some of our concerns; within days, issues were at least validated (or discarded), and either addressed, or planned shortly.

…but at what cost

While the end result of using rollup was great, we encountered lots of issues we did not anticipate or fully understand when analyzing the transition.

  • Modularity is a cost: this is not strictly related to Rollup, but maintaining a set of small libraries tends to be a complex task itself; while coding is easier, dependency management, coordination and deployment is harder and requires carefulness (e.g. not bumping a library version for all dependencies may cause unexpected growth in output file size, because Rollup needs to include multiple versions of the same library and thus cannot de-duplicate the dependency anymore).
  • Tree shaking: understanding the technicalities of tree shaking may be hard, and relatively innocuous code may cause the inclusion of large amounts of unused code without developers realizing it.
Suppose you will only use “button” component. Treeshaking applied to code on the left side will remove the table function but would preserve tableCss and injectCss lines. Code on the right side is functionally equivalent but will fully leverage tree shaking optimisation. You might need to change your code style to leverage Rollup features.
  • Rollup maturity and ecosystem: we encountered many issues when trying to accomplish relatively simple tasks with Rollup. We had issues with the built-in watch/serve functionalities, with several plugins (especially when trying to co-ordinate flow, Vue and eslint), with import resolutions, and with many other minor aspects that ended up slowing down development to an halt. Also, frequent releases forced us to continually review our build process for correctness and for possible improvements, which is a plus, but is also expensive and caused unwanted changes and/or broken builds.

While we did expect to encounter some of those issues, we underestimated the slow-down and the increased complexity that were created when dealing with such issues. As an example of this, we realised the built-in Rollup watcher for SASS files was not working properly and won’t recompile our code when such files changed. We had to use an alternative file watcher to re-trigger the whole build process manually, investing a couple days and ending up with more moving parts and thus a less maintainable build process. We will also need to revert our approach (and trash the code) as soon as the fix will be released by Rollup community.

So…is it worth it?

Rollup is a great tool, and it perfectly aided us in our quest for modularity. However we realized that using our shiny new toolchain had many “hidden” costs. Modularity is not free, and the tools/processes it requires may be complex and expensive. Also, Rollup is still not fully stable and mature yet, and that may cause additional slow-down, especially for complex projects.

We think Rollup is not for everyone: being younger and less stable than other bundling tools you need to be absolutely sure about why you want to use it. Rollup benefits are evident but the risks and the costs might not be as clear.
We are willing to take this “risk” and invest in Rollup since we need to expose modular libraries (either internally or externally) and Rollup helps us avoid code duplication and optimise compiled size. If your needs are solved by Webpack it might be easier and cheaper to just use it instead of Rollup.

We will keep you posted about our findings but in the meantime feel free to share your experience and thoughts.

--

--