From our initial introduction, I hope the idea of using Rollup in your next project has gained some interest. It’s a great tool, while not so popular, that does a great job of providing a variety of solutions. This variety allows for a multitude of options when scaling out your repositories or creating intricate modules that live/import into the greater application codebase. So that begins the question, how do you configure it? Let’s get into it!

Key Options

Input

This is a very familiar configuration option. For any bundler or compiler, you have to direct it somewhere to look, and that is what the input is. This is where rollup would look to begin walking through imports into said main input to find everything that needs to be a part of the output.

External

This is where things get fun with Rollup. To make illustrating this configuration option a bit easier, let’s look at the submodule architecture for applications. Obviously in applications following this pattern, there will be module overlap. Say they all rely on momentjs. Would it make sense to include that same package in every submodule, and possibly risk mismatches? No!

External allows you to specify that a module is external, and there is no need to expect to include it into the end result bundle.

Plugins

This is where things get interesting. Plugins in Rollup give us the opportunity to handle aspects of our module that require more instruction to process our final output. Let’s look at how Rollup handles node modules. Natively, this bundler doesn’t have the ability to easily look up a module from your node modules directory. So to solve this, there is a plugin called @rollup/plugin-node-resolve. This plugin allows Rollup to find third-party modules that are imported somewhere in your application tree.

Specifiying Output

This is the moment of fluidity. Rollup provides a very simple output format that is suitable for most. While at the same time, with more advanced engineers and complex architectures, they leave open the ability to extend quite beyond that as well. For now, we’ll stick with the basics.

File

This is how you specify the final file output destination. So think of it like this, if you wanted your bundled output to be placed at dist/output.js. This is where you would specify that.

Dir

This is where things begin to lean more toward our bigger and complex projects. Specifying this is required when your output requires the creation of chunks. In instances where you have more than one file, and your importing modules, methods, and/or constants, those would be compiled into chunks that will be referenced into your main file.

Format

This is where you specify what type of JS module you want. For now, we’ll focus on the ones you’re most likely to use:

  • umd: Browser friendly with the right configuration; works as an amd, common JS, and iife modules all in one.
  • iife: Stands for immediately-invoked function expression. Suitable for script tags, and adds your code to the global scope
  • cjs: Stands for CommonJS. More so used in NodeJS, where the require statement is used to import modules
  • es: ES modules are great when you want an output suitable to be used with other bundlers, or creating a submodule pattern for larger applications

Name

This is a property that directly relates to iife and umd formatted outputs only. It gives your outputed module a variable name in the global scope to access by.

Globals

To be used for specifying what external imports reference in your code. Let’s take a look at this snippet from the Rollup official documentation.

// rollup.config.js
export default {
  ...,
  external: ['jquery'],
  output: {
    format: 'iife',
    name: 'MyBundle',
    globals: {
      jquery: '$'
    }
  }
};

/*
var MyBundle = (function ($) {
  // code goes here
}($));
*/

jQuery is being identified as an external global module, and the $ is being designated as its alias in the code. The MyBundle part commented out is what the output would look like.

Plugins

Similar to what we mentioned earlier in the top-level scope of the config. At the output level, specifying plugins here indicates that you only want to use them for this specific output. All other configurations present will not incorporate it.

Simple Example

This example I’m about to share with you was taken from the rollup lib starter repo. It’s a pretty good starting point to begin your Rollup journey and see how things work in real-time.

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import pkg from './package.json';

export default [
	// browser-friendly UMD build
	{
		input: 'src/main.js',
		output: {
			name: 'howLongUntilLunch',
			file: pkg.browser,
			format: 'umd'
		},
		plugins: [
			resolve(), // so Rollup can find `ms`
			commonjs() // so Rollup can convert `ms` to an ES module
		]
	},

	// CommonJS (for Node) and ES module (for bundlers) build.
	// (We could have three entries in the configuration array
	// instead of two, but it's quicker to generate multiple
	// builds from a single configuration where possible, using
	// an array for the `output` option, where we can specify
	// `file` and `format` for each target)
	{
		input: 'src/main.js',
		external: ['ms'],
		output: [
			{ file: pkg.main, format: 'cjs' },
			{ file: pkg.module, format: 'es' }
		]
	}
];

In Closing

As you can see, Rollup has a plethora of options and possibilities for supercharging your project architecture. Taking the time to learn and understand it can be quite beneficial for positioning your team for the most productivity. The best thing about all of this is that we’ve only covered the basics so far. There is a whole other arena of advanced configurations we’ll be going over in the future!