An Introduction to the Rollup.js JavaScript Bundler

Here’s a great article from SitePoint

Rollup.js is a next-generation JavaScript module bundler from Rich Harris, the author of Svelte. It compiles multiple source files into a single bundle.

The benefits include:

  • development is easier to manage when using smaller, self-contained source files
  • the source can be linted, prettified, and syntax-checked during bundling
  • tree-shaking removes unused functions
  • transpiling to ES5 for backward compatibility is possible
  • multiple output files can be generated — for example, your library could be provided in ES5, ES6 modules, and Node.js-compatible CommonJS
  • production bundles can be minified and have logging removed

Other bundler options, such as webpack, Snowpack, and Parcel, attempt to magically handle everything: HTML templating, image optimization, CSS processing, JavaScript bundling, and more. This works well when you’re happy with the default settings, but custom configurations can be difficult and processing is slower.

Rollup.js primarily concentrates on JavaScript (although there are plugins for HTML templates and CSS). It has a daunting number of options, but it’s easy to get started and bundling is fast. This tutorial explains how to use typical configurations within your own projects.

Install Rollup.js

Rollup.js requires Node.js v8.0.0 or above and can be installed globally with:

npm install rollup --global

This permits the rollup command to be run in any project directory containing JavaScript files — such as a PHP, WordPress, Python, Ruby or other project.

However, if you’re on a larger team creating a Node.js project, it can be preferable to install Rollup.js locally to ensure all developers are using the same version. Presuming you have an existing Node.js package.json file within a project folder, run:

npm install rollup --save-dev

You won’t be able to run the rollup command directly, but npx rollup can be used. Alternatively, rollup commands can be added to the package.json "scripts" section. For example:

"scripts": {
  "watch": "rollup ./src/main.js --file ./build/bundle.js --format es --watch",
  "build": "rollup ./src/main.js --file ./build/bundle.js --format es",
  "help": "rollup --help"
},

These scripts can be executed with npm run <scriptname> — for example, npm run watch.

The examples below specifically use npx rollup, since it will work regardless of whether rollup is installed locally or globally.

Example Files

Example files and Rollup.js configurations can be downloaded from GitHub. It’s a Node.js project, so run npm install after cloning and examine the README.md file for instructions. Note that Rollup.js and all plugins are installed locally.

Alternatively, you can create the source files manually after initializing a new Node.js project with npm init. The following ES6 modules create a real-time digital clock used to demonstrate Rollup.js processing.

src/main.js is the main entry point script. It locates a DOM element and runs a function every second, which sets its content to the current time:

import * as dom from './lib/dom.js';
import { formatHMS } from './lib/time.js';

// get clock element
const clock = dom.get('.clock');

if (clock) {

  console.log('initializing clock');

  // update clock every second
  setInterval(() => {

    clock.textContent = formatHMS();

  }, 1000);

}

src/lib/dom.js is a small DOM utility library:

// DOM libary

// fetch first node from selector
export function get(selector, doc = document) {
  return doc.querySelector(selector);
}

// fetch all nodes from selector
export function getAll(selector, doc = document) {
  return doc.querySelectorAll(selector);
}

and src/lib/time.js provides time formatting functions:

// time formatting

// return 2-digit value
function timePad(n) {
  return String(n).padStart(2, '0');
}

// return time in HH:MM format
export function formatHM(d = new Date()) {
  return timePad(d.getHours()) + ':' + timePad(d.getMinutes());
}

// return time in HH:MM:SS format
export function formatHMS(d = new Date()) {
  return formatHM(d) + ':' + timePad(d.getSeconds());
}

The clock code can be added to a web page by creating an HTML element with a clock class and loading the script as an ES6 module:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rollup.js testing</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<script type="module" src="http://www.sitepoint.com/./src/main.js"></script>
</head>
<body>

  <h1>Clock</h1>

  <time class="clock"></time>

</body>
</html>

Rollup.js provides options for optimizing the JavaScript source files.

Rollup.js Quick Start

The following command can be run from the root of the project folder to process src/main.js and its dependencies:

npx rollup ./src/main.js --file ./build/bundle.js --format iife

A single script at build/bundle.js is output. It contains all code, but notice that unused dependencies such as the getAll() function in src/lib/dom.js have been removed:

(function () {
  'use strict';

  // DOM libary

  // fetch first node from selector
  function get(selector, doc = document) {
    return doc.querySelector(selector);
  }

  // time library

  // return 2-digit value
  function timePad(n) {
    return String(n).padStart(2, '0');
  }

  // return time in HH:MM format
  function formatHM(d = new Date()) {
    return timePad(d.getHours()) + ':' + timePad(d.getMinutes());
  }

  // return time in HH:MM:SS format
  function formatHMS(d = new Date()) {
    return formatHM(d) + ':' + timePad(d.getSeconds());
  }

  // get clock element
  const clock = get('.clock');

  if (clock) {

    console.log('initializing clock');

    setInterval(() => {

      clock.textContent = formatHMS();

    }, 1000);

  }

}());

The HTML <script> can now be changed to reference the bundled file:

<script type="module" src="http://www.sitepoint.com/./build/bundle.js"></script>

Note: type="module" is no longer necessary, so the script should work in older browsers which support early ES6 implementations. You should also add a defer attribute to ensure the script runs after the DOM is ready (this occurs by default in ES6 modules).

Rollup.js offers numerous command-line flags. The following sections describe the most useful options.

Rollup.js Help

Rollup’s command-line options can be viewed with the --help or -h flag:

npx rollup --help

The Rollup.js version can be output with --version or -v:

npx rollup --version

Output File

The --file (or -o) flag defines the output bundle file, which is set to ./build/bundle.js above. If no file is specified, the resulting bundle is sent to stdout.

JavaScript Formatting

Rollup.js provides several --format (or -f) options to configure the resulting bundle:

option description
iife wrap code in an Immediately Invoked Function Expression (function () { ... }()); block so it cannot conflict with other libraries
es6 standard ES6
cjs CommonJS for Node.js
umd Universal Module Definition for use on both the client and server
amd Asynchronous Module Definition
system SystemJS modules

Unless you’re using a specific module system, iife will be the best option for client-side JavaScript. es6 will produce a slightly smaller bundle, but be wary of global variables and functions which could conflict with other libraries.

Output a Source Map

A source map provides a reference back to the source files so they can be examined in browser developer tools. This makes it easier to set breakpoints or locate problems when errors occur.

An external source map can be created by adding a --sourcemap flag to the rollup command:

npx rollup ./src/main.js --file ./build/bundle.js --format iife --sourcemap

This creates an additional ./build/bundle.js.map file. You can view it, although it’s mostly gibberish and not intended for human consumption! The map is referenced as a comment at the end of ./build/bundle.js:

//# sourceMappingURL=bundle.js.map

Alternatively, you can create an inline source map with --sourcemap inline. Rather than producing an additional file, a base64-encoded version of the source map is appended to ./build/bundle.js:

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY...etc...

After generating the source map, you can load an example page which references the script. Open your developer tools and navigate to the Sources tab in Chrome-based browsers or the Debugger tab in Firefox. You’ll see the original src code and line numbers.

Watch Files and Automatically Bundle

The --watch (or -w) flag monitors your source files for changes and automatically builds the bundle. The terminal screen is cleared on every run, but you can disable this with --no-watch.clearScreen:

npx rollup ./src/main.js --file ./build/bundle.js --format iife --watch --no-watch.clearScreen

Create a Configuration File

Command-line flags can quickly become unwieldy. The examples above are already long and you’ve not begun to add plugins!

Rollup.js can use a JavaScript configuration file to define bundling options. The default name is rollup.config.js and it should be placed in the root of your project (typically, the directory where you run rollup from).

The file is an ES module which exports a default object that sets Rollup.js options. The following code replicates the commands used above:

// rollup.config.js

export default {

  input: "http://www.sitepoint.com/./src/main.js",

  output: {
    file: "http://www.sitepoint.com/./build/bundle.js",
    format: 'iife',
    sourcemap: true
  }

}

Note: sourcemap: true defines an external sourcemap. Use sourcemap: 'inline' for an inline sourcemap.

You can use this configuration file when running rollup by setting the --config (or -c) flag:

npx rollup --config

A file name can be passed if you named the configuration something other than than rollup.config.js. This can be practical when you have multiple configurations perhaps located in a config directory. For example:

npx rollup --config ./config/rollup.simple.js

Continue reading
An Introduction to the Rollup.js JavaScript Bundler
on SitePoint.

Source link