Introduction to Rollup: What It Is and Why It Matters
Rollup is a module bundler for JavaScript that takes your small pieces of code and compiles them into a larger, more complex application. While other bundlers like Webpack were primarily designed to handle application-level bundling (including assets like CSS and images), Rollup was born with a specific focus on JavaScript modules and creating efficient, production-ready libraries.
Why does Rollup matter? The core advantage of Rollup lies in its strict adherence to ES module standards and its powerful tree-shaking algorithm. Tree-shaking is a process of dead-code elimination, where Rollup analyzes your code, identifies which modules are imported but not actually used, and strips them out of the final bundle. This results in significantly smaller, faster, and cleaner builds, making Rollup the go-to choice for modern JavaScript library development.
Beginner Level: Setting Up Your First Rollup Project
To begin your journey with Rollup, you first need to initialize a project and install Rollup as a development dependency. Rollup relies on a configuration file to understand how to bundle your code.
First, initialize your project and install Rollup:
npm init -y
npm install --save-dev rollup
Next, create a configuration file named rollup.config.js in the root of your project. This is where you define your entry point and output settings.
// rollup.config.js
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es', // ES module format
}
};
Create a simple src/main.js file to test the setup:
// src/main.js
const greet = (name) => `Hello, ${name}!`;
console.log(greet('Rollup'));
To run the bundler, add a script to your package.json:
"scripts": {
"build": "rollup -c"
}
Running npm run build will read the configuration file (-c) and output your bundled file into the dist directory.
Intermediate Level: Plugins and Customization
Out of the box, Rollup only understands ES module syntax. If you want to use CommonJS modules (like many older npm packages) or compile modern JavaScript (like JSX or TypeScript) down to older syntax, you need to use plugins.
Plugins are functions that modify Rollup's behavior at different stages of the build process. The most common plugins you will use are @rollup/plugin-node-resolve (to bundle dependencies from node_modules) and @rollup/plugin-babel or @rollup/plugin-typescript (for transpilation).
Install the necessary plugins:
npm install --save-dev @rollup/plugin-node-resolve @rollup/plugin-commonjs
Update your rollup.config.js to include these plugins:
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es',
},
plugins: [
nodeResolve(), // teaches Rollup how to find modules in node_modules
commonjs(), // converts CommonJS modules to ES modules
]
};
With this configuration, you can now import npm packages directly into your source code, and Rollup will seamlessly include them in your final bundle.
Expert Level: Code Splitting, Tree Shaking, and Library Mode
At the expert level, you leverage Rollup's advanced features to create highly optimized libraries. One of the most powerful features is code splitting. By defining multiple entry points, Rollup can automatically split shared code into separate chunks, reducing duplication.
// rollup.config.js
export default {
input: ['src/main.js', 'src/secondary.js'],
output: {
dir: 'dist',
format: 'es',
}
};
When building a library, you typically want to output multiple formats (ESM for modern bundlers, UMD for browsers, and CJS for Node.js) while keeping your dependencies external (so they are not bundled into your code, but expected to be provided by the consumer).
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.js',
output: [
{
file: 'dist/my-lib.es.js',
format: 'es',
},
{
file: 'dist/my-lib.umd.js',
format: 'umd',
name: 'MyLib', // Required for UMD format
},
{
file: 'dist/my-lib.cjs.js',
format: 'cjs',
}
],
plugins: [nodeResolve(), commonjs()],
external: ['lodash'], // Do not bundle lodash; expect it to be installed by the user
};
Best Practices for Rollup
- Use ES Module Syntax: Always write your source code using
importandexportstatements. This allows Rollup to perform static analysis and effectively tree-shake unused code. - Keep Dependencies External for Libraries: If you are building a library, do not bundle your dependencies (like React, Lodash, etc.). Use the
externalarray in your config to prevent bloating your library with code the consumer already has. - Use
output.dirfor Multiple Inputs: When using code splitting or multiple entry points, always useoutput.dirinstead ofoutput.fileso Rollup can generate multiple chunks correctly. - Minify for Production: Use the
@rollup/plugin-terserplugin to minify your output bundles, ensuring the smallest possible footprint for production environments. - Leverage Watch Mode: During development, use
rollup -c -wto watch your files and recompile automatically on changes, significantly speeding up your workflow.
Conclusion
Mastering Rollup takes you from simply writing JavaScript to architecting highly optimized, distributable code. By starting with the basics of configuration, moving into the power of plugins, and finally mastering code splitting and library modes, you gain complete control over how your JavaScript is delivered to the world. By adhering to ES module standards and following best practices like keeping dependencies external and utilizing tree-shaking, you ensure your applications and libraries remain lean, efficient, and easily maintainable in the modern JavaScript ecosystem.