Rollup - A Solid JavaScript Bundler for Libraries

Updated Sep 10, 2021#javascript#libs

Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD.

Rollup was created to build flat distributables of JavaScript libraries as efficiently as possible, taking advantage of ES modules.

Getting Started

Rollup is an open-source project written in JavaScript, published as npm package. You can install and use it as both globally or locally CLI tool:

# as global command line tool
npm install --global rollup

# or as locally command line tool
npm install rollup --save-dev

Rollup can be used either through a command line interface with an optional configuration file:

# compile to a CommonJS module ('cjs')
rollup main.js --file bundle.js --format cjs
// rollup.config.js example
export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  }
}

Rollup provides a JavaScript API which is usable from Node.js. You will rarely need to use this, and should probably be using the command line API unless you are extending Rollup itself or using it for something esoteric, such as generating bundles programmatically.

// example using rollup JavaScript API
const rollup = require('rollup');

const inputOptions = {...};
const outputOptions = {...};

async function build() {
  // create a bundle
  const bundle = await rollup.rollup(inputOptions);

  console.log(bundle.watchFiles);
  const { output } = await bundle.generate(outputOptions);

  for (const chunkOrAsset of output) {
    if (chunkOrAsset.type === 'asset') {
      console.log('Asset', chunkOrAsset);
    } else {
      console.log('Chunk', chunkOrAsset.modules);
    }
  }

  await bundle.write(outputOptions);
  await bundle.close();
}

build();

Rollup returns Promises which are understood by Gulp so integration is relatively painless.

// example using rollup with gulp
const gulp = require('gulp')
const rollup = require('rollup')
const rollupTypescript = require('@rollup/plugin-typescript')

gulp.task('build', async function () {
  const bundle = await rollup.rollup({
    input: './src/main.ts',
    plugins: [rollupTypescript()]
  })

  await bundle.write({
    file: './dist/library.js',
    format: 'umd',
    name: 'library',
    sourcemap: true
  })
})

Under the Hood

Rollup allows you to write your code using the new ES module syntax, and will then compile it back down to existing supported formats such as CommonJS modules, AMD modules, and IIFE-style scripts.

ES modules allow static analysis that helps with optimizations like tree-shaking and scope-hoisting, and provide advanced features like circular references and live bindings.

Rollup was the first bundler to support tree-shaking in JavaScript. ES module syntax allows Rollup to statically analyze the code you are importing, and will exclude anything that isn’t actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project.

For code splitting, there are cases where Rollup splits code into chunks automatically, like dynamic loading or multiple entry points, and there is a way to explicitly tell Rollup which modules to split into separate chunks via the output.manualChunks option.

As you build more complex bundles, you’ll often need more flexibility – importing modules installed with NPM, compiling code with Babel, working with JSON files and so on. For that, Rollup uses plugins, which change its behaviour at key points in the bundling process.

// example using plugin in rollup.config.js
import json from '@rollup/plugin-json'

export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  },
  plugins: [json()]
}

To interact with the build process, your plugin object includes hooks. Hooks are functions which are called at various stages of the build. Hooks can affect how a build is run, provide information about a build, or modify a build once complete.

Rollup is already used by many major JavaScript libraries, and can also be used to build the vast majority of applications.