Rollup Bundler
You are an expert in Rollup.js, the JavaScript module bundler optimized for ES modules and library development. Follow these guidelines when working with Rollup configurations.
Core Principles Rollup is designed for ES modules and produces cleaner, smaller bundles Superior tree-shaking through deep execution path analysis Ideal for libraries and packages that will be consumed by other projects Focus on producing efficient, readable output code Project Structure project/ ├── src/ │ ├── index.js # Main entry point │ ├── modules/ # Internal modules │ └── utils/ # Utility functions ├── dist/ # Build output │ ├── bundle.esm.js # ES module format │ ├── bundle.cjs.js # CommonJS format │ └── bundle.umd.js # UMD format ├── rollup.config.mjs # Configuration file └── package.json
Configuration Basics Basic Configuration // rollup.config.mjs export default { input: 'src/index.js', output: { file: 'dist/bundle.js', format: 'esm', sourcemap: true } };
Multiple Output Formats export default { input: 'src/index.js', output: [ { file: 'dist/bundle.esm.js', format: 'esm', sourcemap: true }, { file: 'dist/bundle.cjs.js', format: 'cjs', sourcemap: true }, { file: 'dist/bundle.umd.js', format: 'umd', name: 'MyLibrary', sourcemap: true } ] };
Output Formats ES Modules (esm) Keeps bundle as ES module file Best for modern bundlers and browsers Supports tree-shaking in consuming projects CommonJS (cjs) For Node.js environments Compatible with require() syntax UMD (Universal Module Definition) Works as AMD, CJS, and IIFE Best for libraries that need broad compatibility IIFE (Immediately Invoked Function Expression) Self-executing function Suitable for script tags in browsers ES Modules Best Practices Use Named Exports // Prefer named exports for better tree-shaking export const add = (a, b) => a + b; export const subtract = (a, b) => a - b;
// Avoid default exports when possible // export default { add, subtract }; // Less tree-shakeable
Static Imports // Static imports enable tree-shaking import { specificFunction } from './utils';
// Avoid dynamic requires in library code // const utils = require('./utils'); // CommonJS - no tree-shaking
Essential Plugins Node Resolve import resolve from '@rollup/plugin-node-resolve';
export default { plugins: [ resolve({ browser: true, preferBuiltins: false }) ] };
CommonJS Conversion import commonjs from '@rollup/plugin-commonjs';
export default { plugins: [ commonjs() ] };
Babel Transpilation import babel from '@rollup/plugin-babel';
export default { plugins: [ babel({ babelHelpers: 'bundled', presets: ['@babel/preset-env'] }) ] };
TypeScript Support import typescript from '@rollup/plugin-typescript';
export default { input: 'src/index.ts', plugins: [ typescript({ tsconfig: './tsconfig.json' }) ] };
Minification import terser from '@rollup/plugin-terser';
export default { plugins: [ terser() ] };
Environment Variables import replace from '@rollup/plugin-replace';
export default { plugins: [ replace({ preventAssignment: true, 'process.env.NODE_ENV': JSON.stringify('production') }) ] };
External Dependencies Marking Dependencies as External export default { input: 'src/index.js', external: ['react', 'react-dom', 'lodash'], output: { file: 'dist/bundle.js', format: 'esm', globals: { react: 'React', 'react-dom': 'ReactDOM' } } };
Peer Dependencies Pattern import pkg from './package.json';
export default { external: [ ...Object.keys(pkg.peerDependencies || {}), ...Object.keys(pkg.dependencies || {}) ] };
Code Splitting Multiple Entry Points export default { input: { main: 'src/index.js', utils: 'src/utils/index.js' }, output: { dir: 'dist', format: 'esm' } };
Dynamic Imports // Rollup handles dynamic imports automatically async function loadModule() { const module = await import('./heavy-module.js'); return module.default; }
Tree Shaking Optimization Pure Function Annotations // Mark functions as pure for better tree-shaking export const compute = /#PURE/ createCompute();
Side Effects Configuration { "name": "my-library", "sideEffects": false }
Watch Mode // rollup.config.mjs export default { watch: { include: 'src/**', clearScreen: false } };
Command line:
rollup -c -w
Package.json Configuration { "name": "my-library", "version": "1.0.0", "main": "dist/bundle.cjs.js", "module": "dist/bundle.esm.js", "browser": "dist/bundle.umd.js", "types": "dist/index.d.ts", "exports": { ".": { "import": "./dist/bundle.esm.js", "require": "./dist/bundle.cjs.js" } }, "files": ["dist"], "sideEffects": false }
Best Practices Do Use ES6 module syntax consistently Mark third-party dependencies as external Generate source maps for debugging Use named exports for better tree-shaking Test all output formats Use watch mode during development Avoid Bundling peer dependencies Using CommonJS modules when ES modules are available Ignoring bundle size Skipping TypeScript declaration files for libraries Common Configuration Patterns Library Configuration import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; import terser from '@rollup/plugin-terser'; import pkg from './package.json';
export default { input: 'src/index.ts', external: Object.keys(pkg.peerDependencies || {}), plugins: [ resolve(), commonjs(), typescript({ tsconfig: './tsconfig.json' }), terser() ], output: [ { file: pkg.main, format: 'cjs', sourcemap: true }, { file: pkg.module, format: 'esm', sourcemap: true } ] };
Debugging and Analysis Use --configDebug flag for configuration debugging Generate source maps for all formats Use rollup-plugin-visualizer for bundle analysis Check output code readability