How to Package Component Libraries with Rollup Instead of Webpack
When developing component libraries, choosing the right bundler is critical for delivering optimized and compatible packages. While Webpack is a versatile tool for web application bundling, Rollup is often preferred for packaging libraries due to its cleaner outputs, efficient tree-shaking, and robust plugin system. This article dives into the reasons why Rollup is a superior choice for component library packaging, along with practical examples comparing it to Webpack.
Why Rollup for Component Libraries?
Rollup is purpose-built for bundling JavaScript libraries. Unlike Webpack, which is designed for web applications and includes runtime management, Rollup focuses on generating minimal, dependency-free bundles. This makes it ideal for libraries that need to be lightweight and compatible with multiple environments.
- Clean Output: Rollup avoids including runtime code, producing lean bundles.
- Multiple Module Formats: Rollup natively supports ESM, CommonJS, and UMD, crucial for distributing libraries.
- Tree-Shaking: Rollup’s default tree-shaking eliminates unused code, reducing bundle size.
- Extensibility: The plugin system simplifies customization and modularity.
- Integration with Modern Tools: Tools like Vite use Rollup for production builds.
Comparison: Rollup vs. Webpack
1. Packaging Example
To illustrate the differences, let’s package a simple project using both Rollup and Webpack.
Project Structure
We’ll use two basic modules:
src/index.js:
1 import { add } from './utils';23 function main() {4 console.log(add(1, 2));5 }67 export default main;
src/utils.js
:
1 function add(a, b) {2 return a + b;3 }45 export { add };
Using Rollup
1. Install Rollup:
2. Create Configuration:
rollup.config.js:
1 /** @type {import('rollup').RollupOptions} */2 export default {3 input: 'src/index.js',4 output: [5 { file: 'dist/esm.js', format: 'esm' },6 { file: 'dist/cjs.js', format: 'cjs' },7 { file: 'dist/umd.js', name: 'LibraryName', format: 'umd' },8 ],9 };
3. Build:
Output:
- Clean bundles for ESM, CommonJS, and UMD, free of runtime code.
Using Webpack
1. Install Webpack:
2. Create Configuration:
webpack.config.mjs
:
1 import path from 'path';23 /** @type {import('webpack').Configuration} */4 export default {5 entry: './src/index.js',6 mode: 'development',7 devtool: false,8 output: {9 path: path.resolve(process.cwd(), 'dist'),10 filename: 'bundle.js',11 libraryTarget: 'commonjs2',12 },13 };
3. Build:
Output:
- The bundle includes over 100 lines of runtime code, even in simple scenarios.
CSS Handling: Rollup vs. Webpack
Component libraries often require separate CSS files. Let’s see how both bundlers handle this.
Packaging CSS with Rollup
1. Install PostCSS Plugin:
2. Configure Rollup for CSS Extraction:
rollup.config.js
:
1 import postcss from 'rollup-plugin-postcss';23 /** @type {import('rollup').RollupOptions} */4 export default {5 input: 'src/index.js',6 output: [7 { file: 'dist/esm.js', format: 'esm' },8 { file: 'dist/cjs.js', format: 'cjs' },9 { file: 'dist/umd.js', name: 'LibraryName', format: 'umd' },10 ],11 plugins: [12 postcss({13 extract: 'styles.css', // Extracts CSS to a separate file14 }),15 ],16 };
3. Build:
Result:
- The CSS is extracted into
styles.css
, while the JS remains clean.
Packaging CSS with Webpack
1. Install CSS Loaders:
2. Configure Webpack for CSS:
webpack.config.mjs
:
1 import path from 'path';2 import MiniCssExtractPlugin from 'mini-css-extract-plugin';34 /** @type {import('webpack').Configuration} */5 export default {6 entry: './src/index.js',7 mode: 'development',8 devtool: false,9 output: {10 path: path.resolve(process.cwd(), 'dist'),11 filename: 'bundle.js',12 },13 module: {14 rules: [15 {16 test: /\.css$/i,17 use: [MiniCssExtractPlugin.loader, 'css-loader'],18 },19 ],20 },21 plugins: [22 new MiniCssExtractPlugin({ filename: 'styles.css' }),23 ],24 };
3. Build:
Result:
- CSS is extracted into
styles.css
, but the JS bundle still contains references to runtime helpers.
When to Use Rollup vs. Webpack
Use Rollup for:
- Packaging libraries (e.g., JavaScript utilities, React/Vue component libraries).
- Scenarios requiring clean, runtime-free bundles.
- Projects targeting multiple module formats.
Use Webpack for:
- Bundling web applications.
- Handling complex assets like images, fonts, and dynamic imports.
- Scenarios requiring advanced development server features.
Rollup in Modern Toolchains
Tools like Vite and SvelteKit use Rollup under the hood for production builds. While Vite employs esbuild for development due to its speed, Rollup’s plugin system powers production packaging. This hybrid approach combines speed and flexibility.
Conclusion
Rollup is a focused, efficient tool for library packaging, offering clean outputs and multiple format support. While Webpack dominates application bundling, Rollup excels in scenarios where simplicity, tree-shaking, and modularity are paramount. By understanding their strengths, developers can choose the right tool for their projects.
Whether you're building a JavaScript library, a UI component library, or exploring tools like Vite, Rollup is an indispensable part of modern bundling workflows.