Rollup Complete Guide | ES Module Bundler
이 글의 핵심
Rollup is a module bundler for JavaScript that compiles ES modules into optimized bundles. It's the bundler of choice for libraries and powers Vite's production builds.
Introduction
Rollup is a module bundler for JavaScript that treats ES modules as first-class citizens. It’s designed for building libraries and produces highly optimized output.
Why Rollup?
Traditional bundlers include lots of runtime code:
// Webpack output (simplified)
(function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
// ... runtime code
}
return __webpack_require__(0);
})([/* modules */]);
Rollup output is clean and minimal:
// Just your code, optimized
function add(a, b) {
return a + b;
}
export { add };
1. Installation
npm install --save-dev rollup
Basic config:
// rollup.config.js
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
}
};
rollup -c
2. Output Formats
Rollup supports multiple module formats:
export default {
input: 'src/index.js',
output: [
// ES Module (modern)
{
file: 'dist/bundle.esm.js',
format: 'es'
},
// CommonJS (Node.js)
{
file: 'dist/bundle.cjs.js',
format: 'cjs'
},
// UMD (browser)
{
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
},
// IIFE (browser script tag)
{
file: 'dist/bundle.iife.js',
format: 'iife',
name: 'MyLibrary'
}
]
};
3. Tree Shaking
Rollup pioneered tree shaking - removing unused code:
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export function multiply(a, b) {
return a * b;
}
// main.js
import { add } from './math.js';
console.log(add(1, 2));
Output (only used code):
function add(a, b) {
return a + b;
}
console.log(add(1, 2));
// subtract and multiply are removed!
4. Essential Plugins
@rollup/plugin-node-resolve
Resolves npm packages:
npm install --save-dev @rollup/plugin-node-resolve
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [resolve()]
};
@rollup/plugin-commonjs
Converts CommonJS to ES modules:
npm install --save-dev @rollup/plugin-commonjs
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
export default {
plugins: [
resolve(),
commonjs() // After resolve
]
};
@rollup/plugin-babel
Transpiles modern JavaScript:
npm install --save-dev @rollup/plugin-babel @babel/core @babel/preset-env
import babel from '@rollup/plugin-babel';
export default {
plugins: [
babel({
babelHelpers: 'bundled',
presets: ['@babel/preset-env']
})
]
};
@rollup/plugin-terser
Minifies output:
npm install --save-dev @rollup/plugin-terser
import terser from '@rollup/plugin-terser';
export default {
plugins: [
terser()
]
};
5. Building a Library
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
export default {
input: 'src/index.js',
output: [
{
file: 'dist/my-library.esm.js',
format: 'es',
sourcemap: true
},
{
file: 'dist/my-library.cjs.js',
format: 'cjs',
sourcemap: true
},
{
file: 'dist/my-library.min.js',
format: 'umd',
name: 'MyLibrary',
sourcemap: true,
plugins: [terser()]
}
],
plugins: [
resolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**'
})
],
external: ['react', 'react-dom'] // Don't bundle React
};
package.json:
{
"name": "my-library",
"main": "dist/my-library.cjs.js",
"module": "dist/my-library.esm.js",
"browser": "dist/my-library.min.js",
"files": ["dist"],
"scripts": {
"build": "rollup -c"
}
}
6. Code Splitting
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js'
},
output: {
dir: 'dist',
format: 'es'
}
};
Dynamic imports:
// main.js
async function loadModule() {
const module = await import('./heavy-module.js');
module.init();
}
7. TypeScript Support
npm install --save-dev @rollup/plugin-typescript typescript
import typescript from '@rollup/plugin-typescript';
export default {
input: 'src/index.ts',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
typescript()
]
};
8. React Library
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
export default {
input: 'src/index.jsx',
output: [
{
file: 'dist/index.js',
format: 'cjs',
sourcemap: true
},
{
file: 'dist/index.esm.js',
format: 'es',
sourcemap: true
}
],
plugins: [
peerDepsExternal(), // Externalize peer dependencies
resolve(),
babel({
babelHelpers: 'bundled',
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }]
],
exclude: 'node_modules/**'
}),
commonjs()
],
external: ['react', 'react-dom']
};
9. CSS and Assets
PostCSS
npm install --save-dev rollup-plugin-postcss
import postcss from 'rollup-plugin-postcss';
export default {
plugins: [
postcss({
extract: true,
minimize: true
})
]
};
Images
npm install --save-dev @rollup/plugin-image
import image from '@rollup/plugin-image';
export default {
plugins: [
image()
]
};
10. Development Workflow
npm install --save-dev rollup-plugin-serve rollup-plugin-livereload
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
const dev = process.env.NODE_ENV !== 'production';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: dev
},
plugins: [
// ... other plugins
dev && serve({
open: true,
contentBase: ['dist', 'public'],
port: 3000
}),
dev && livereload('dist')
].filter(Boolean)
};
{
"scripts": {
"dev": "rollup -c -w",
"build": "NODE_ENV=production rollup -c"
}
}
11. Advanced Configuration
Multiple Configs
// rollup.config.js
import dev from './rollup.config.dev.js';
import prod from './rollup.config.prod.js';
export default process.env.NODE_ENV === 'production' ? prod : dev;
Conditional Plugins
const production = !process.env.ROLLUP_WATCH;
export default {
plugins: [
resolve(),
commonjs(),
production && terser()
].filter(Boolean)
};
12. Optimizations
External Dependencies
export default {
external: [
'react',
'react-dom',
/^lodash/ // All lodash packages
]
};
Mangled Props (Advanced)
import terser from '@rollup/plugin-terser';
export default {
plugins: [
terser({
mangle: {
properties: {
regex: /^_/ // Mangle properties starting with _
}
}
})
]
};
13. Watch Mode
rollup -c -w
// rollup.config.js
export default {
watch: {
include: 'src/**',
exclude: 'node_modules/**',
clearScreen: false
}
};
14. Real-World Example
Complete library build:
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 peerDepsExternal from 'rollup-plugin-peer-deps-external';
import postcss from 'rollup-plugin-postcss';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/index.ts',
output: [
{
file: 'dist/index.js',
format: 'cjs',
sourcemap: true,
exports: 'named'
},
{
file: 'dist/index.esm.js',
format: 'es',
sourcemap: true,
exports: 'named'
},
{
file: 'dist/index.umd.js',
format: 'umd',
name: 'MyLib',
sourcemap: true,
exports: 'named',
globals: {
react: 'React',
'react-dom': 'ReactDOM'
}
}
],
plugins: [
peerDepsExternal(),
resolve({
extensions: ['.js', '.jsx', '.ts', '.tsx']
}),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
declaration: true,
declarationDir: 'dist'
}),
postcss({
extract: 'styles.css',
minimize: production
}),
production && terser()
].filter(Boolean),
external: ['react', 'react-dom']
};
15. Performance Tips
1. Use Cache
Rollup caches by default in watch mode.
2. Parallelize Builds
npm install --save-dev npm-run-all
{
"scripts": {
"build:esm": "rollup -c rollup.config.esm.js",
"build:cjs": "rollup -c rollup.config.cjs.js",
"build": "npm-run-all --parallel build:*"
}
}
3. Minimize Plugin Work
plugins: [
resolve({
mainFields: ['module', 'main'],
extensions: ['.js'] // Only what you need
})
]
Summary
Rollup excels at building optimized libraries:
- Tree shaking pioneer
- Clean output with minimal runtime
- ES module first design
- Plugin ecosystem for everything
- Powers Vite production builds
Key Takeaways:
- Best for library builds
- Excellent tree shaking
- Multiple output formats
- Clean, readable output
- Plugin-based architecture
Next Steps:
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete Rollup guide for JavaScript bundling. Learn tree-shaking, code splitting, plugins, and building optimized libra…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- CMake find_package for C++ | Boost· OpenSSL
- JavaScript Modules | ES Modules and CommonJS Explained
- esbuild Complete Guide | Fastest JavaScript Bundler
Keywords Covered in This Article (Related Search Terms)
This article covers Rollup, Build Tools, Bundler, JavaScript, ES Modules, Tree Shaking.