Rollup
JavaScript 模块打包器——将小块代码编译为更大、更复杂的库或应用,是 Tree Shaking 概念的开创者和 ES Module 打包领域的工业标准。
Rollup 是 ES Module 打包器的工业标准,开创了 Tree Shaking 概念,以卓越的死代码消除能力和多格式输出成为 npm 库和前端框架打包的首选工具,Vite 底层生产构建引擎。
Rollup
JavaScript 模块打包器——将小块代码编译为更大、更复杂的库或应用,是 Tree Shaking 概念的开创者和 ES Module 打包领域的工业标准。
技术简介说明
Rollup 是一个用于 JavaScript 的 ES Module 打包器(bundler),由 Rich Harris 于 2015 年创建,2017 年起由 Lukas Taegert-Atkinson 担任核心维护者。它的核心使命是:将分散的小模块按照 ES 模块标准(ESM)静态分析、解析依赖、深度优化,最终编译为可直接运行的更大代码包。Rollup 是将 Tree Shaking(死代码消除)概念带入 JavaScript 世界的先驱工具——这一特性如今已成为所有现代打包工具的标配。
与其他打包工具(如 Webpack)不同,Rollup 专注于"库(Library)打包"这一核心场景。它利用 ES Module 的静态导入/导出特性,在编译阶段就能精确判断哪些代码是真正被使用的,从而将未引用的代码完全剔除。这种基于静态分析的优化策略使得 Rollup 产出的包体积通常比同类工具更小,因此成为 npm 库作者和开源框架开发者的首选打包工具。React、Vue、D3、Three.js、Chart.js、date-fns 等大量知名库都使用 Rollup 构建。
Rollup 的插件系统和配置灵活性同样出众——支持 ES Modules、CommonJS、UMD、AMD、SystemJS、IIFE 等多种输出格式,可打包为浏览器、Node.js、Electron 等多平台使用。同时,Vite(目前最流行的前端开发工具链)底层正是采用 Rollup 作为其生产构建引擎。可以说,Rollup 在整个 JavaScript 生态中扮演着"基础设施"的角色。
基本信息
- 官网:https://rollupjs.org/
- 中文官网:https://cn.rollupjs.org/
- GitHub:https://github.com/rollup/rollup
- License:MIT
- 最新版本:v4.62.2(2026 年 6 月 19 日发布)
- 主要维护者/公司:Lukas Taegert-Atkinson(核心维护者,自 2017 年起);原始作者 Rich Harris(Svelte 框架作者)
- npm 周下载量:约 1.1 亿次(截至 2026 年中)
- GitHub Stars:约 26,300+
- GitHub Forks:约 1,800+
- Node.js 要求:>= 18.0.0
- 语言构成:JavaScript(核心)+ TypeScript(类型定义)
快速上手
安装
推荐使用本地安装方式(作为开发依赖):
# npm
npm install rollup --save-dev
# yarn
yarn add rollup --dev
# pnpm(推荐)
pnpm add rollup -D同时安装常用的官方插件:
# 安装最常用的插件组合
pnpm add -D @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript可选:全局安装 CLI(不推荐用于项目构建):
npm install rollup --global基础配置
在项目根目录创建 rollup.config.mjs(Rollup 4 中 ES Module 配置文件必须使用 .mjs 扩展名):
// rollup.config.mjs
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'
export default {
// 入口文件
input: 'src/index.ts',
// 输出配置
output: [
// ESM 格式输出
{
file: 'dist/index.esm.js',
format: 'es',
sourcemap: true,
},
// CommonJS 格式输出
{
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true,
},
// UMD 格式输出(浏览器直接使用)
{
file: 'dist/index.umd.js',
format: 'umd',
name: 'MyLibrary', // UMD 模块的全局变量名
globals: {
// 外部依赖的全局变量映射
react: 'React',
},
sourcemap: true,
},
],
// 外部依赖(不打包进 bundle)
external: ['react', 'react-dom'],
// 插件列表(顺序很重要)
plugins: [
resolve(), // 解析 node_modules 中的模块
commonjs(), // 将 CommonJS 模块转换为 ESM
typescript(), // TypeScript 编译
terser(), // 代码压缩(生产环境)
],
}最小示例
以下是一个最简单的完整示例——将一个 TypeScript 工具库打包为多格式输出:
src/index.ts:
export function greet(name: string): string {
return `Hello, ${name}!`
}
export function add(a: number, b: number): number {
return a + b
}
export const VERSION = '1.0.0'rollup.config.mjs:
import typescript from '@rollup/plugin-typescript'
export default {
input: 'src/index.ts',
output: [
{ file: 'dist/index.esm.js', format: 'es' },
{ file: 'dist/index.cjs.js', format: 'cjs' },
],
plugins: [typescript()],
}package.json:
{
"name": "my-library",
"version": "1.0.0",
"main": "./dist/index.cjs.js",
"module": "./dist/index.esm.js",
"exports": {
".": {
"import": "./dist/index.esm.js",
"require": "./dist/index.cjs.js"
}
},
"type": "module",
"files": ["dist"],
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w"
}
}执行构建:
# 生产构建
npx rollup -c
# 开发模式(监听文件变化)
npx rollup -c -w输出结构:
dist/
├── index.esm.js # ES Module 格式(供 import 使用)
├── index.esm.js.map
├── index.cjs.js # CommonJS 格式(供 require 使用)
└── index.cjs.js.map
核心概念与架构
核心概念
1. ES Module 优先
Rollup 的核心设计理念是围绕 ES Module(ESM)标准构建的。它利用 import / export 语法的静态特性——在编译阶段就能确定模块间的依赖关系和导出内容,无需运行代码。这使得 Rollup 能精确地进行 Tree Shaking,只保留被实际使用的代码。
2. Tree Shaking(死代码消除)
Rollup 是 Tree Shaking 概念的开创者。它通过分析模块间的导入导出关系,自动识别并移除未被使用的导出(dead code)。与其他工具不同,Rollup 的 Tree Shaking 基于完整的执行路径分析(execution path analysis),能处理复杂的间接引用、副作用标注(sideEffects)和条件导出。
3. 输入-输出管道(Pipeline)
源代码 → [解析] → [模块解析] → [加载] → [转换] → [Tree Shake] → [代码生成] → 输出
↓ ↓ ↓ ↓ ↓ ↓
acorn plugins plugins plugins 核心优化 格式转换
- 解析阶段:使用 acorn 解析器将源代码转为 AST
- 模块解析:通过插件(如
@rollup/plugin-node-resolve)确定导入路径 - 加载阶段:读取模块内容
- 转换阶段:通过插件(如
@rollup/plugin-typescript)转换代码 - 优化阶段:Tree Shaking、副作用分析、作用域提升
- 生成阶段:根据输出格式(ESM/CJS/UMD 等)生成最终代码
4. 插件钩子(Plugin Hooks)
Rollup 的插件系统基于一系列生命周期钩子,分为三个阶段:
- 构建阶段钩子(
buildStart→resolveId→load→transform→buildEnd):在模块解析和加载过程中调用 - 输出生成钩子(
renderStart→renderChunk→generateBundle):在代码生成过程中调用 - 输出生成后钩子(
writeBundle):在文件写入磁盘后调用
架构设计
┌─────────────────────────────────────────────┐
│ Rollup CLI / JS API │ ← 用户接口层
├─────────────────────────────────────────────┤
│ Rollup 核心引擎 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ AST 解析 │ │ 模块图构建│ │ Tree Shake│ │
│ │ (acorn) │ │ │ │ 优化引擎 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────┤
│ 插件系统(Plugin API) │ ← 扩展能力层
├─────────────────────────────────────────────┤
│ 原生代码层(可选) │ ← 性能加速层
│ (平台特定的 native binding) │
└─────────────────────────────────────────────┘
Rollup 4 的一个重要架构变化是引入了原生代码绑定(native bindings)。通过可选的 npm 依赖,Rollup 会根据操作系统和 CPU 架构自动安装对应的原生模块(如 @rollup/rollup-linux-x64-gnu),显著提升解析和打包性能。对于不支持原生绑定的平台,Rollup 提供 WASM 回退方案(@rollup/wasm-node)。
工作原理
- 入口解析:从配置的
input入口文件开始 - 依赖图构建:递归分析所有
import语句,构建完整的模块依赖图 - 插件转换:在模块加载过程中,通过插件进行 TypeScript 编译、CSS 处理等转换
- Tree Shaking:静态分析所有模块的导出,标记未被引用的代码并移除
- 副作用分析:根据
sideEffects标注判断模块是否有副作用,决定是否可以安全移除 - 作用域提升(Scope Hoisting):将多个模块合并到同一作用域中,减少函数包装开销
- 代码生成:根据
format配置输出对应格式的 bundle - 代码拆分(Code Splitting):支持
manualChunks和preserveModules将代码分割为多个 chunk
核心特性
- 🌳 卓越的 Tree Shaking:基于静态分析和执行路径追踪的死代码消除,是 Rollup 最核心的竞争力。产出的包体积通常比 Webpack/esbuild 方案更小
- 📦 多格式输出:一次构建同时输出 ES Module、CommonJS、UMD、AMD、SystemJS、IIFE 等多种格式,覆盖所有使用场景
- 🔌 强大的插件系统:提供易学且强大的插件 API,拥有丰富的官方和社区插件生态(200+ 插件)
- 📊 代码拆分:支持
manualChunks、preserveModules等策略进行细粒度代码拆分 - 🏷️ 多入口支持:支持多个入口文件同时打包,自动生成共享 chunk
- ⚡ 原生性能加速:Rollup 4 引入平台特定的原生绑定,大幅提升解析和打包速度
- 🌍 跨平台支持:支持 Web、Node.js、Electron 等多平台构建,提供 WASM 回退方案
- 🎯 精准的外部依赖控制:
external配置支持字符串、数组、函数,可精确控制哪些依赖不被打包 - 📝 Source Map 支持:完整支持 Source Map 生成和链式映射
- 🔍 副作用标注支持:识别
package.json中的sideEffects字段和代码中的/* @__PURE__ */注释 - 👁️ Watch 模式:内建文件监听,修改源码后自动重新构建
- 🔧 灵活的配置系统:支持函数式配置、多配置输出、环境变量注入等高级能力
生态图
生态系统概览
Rollup 拥有 JavaScript 生态中最成熟的库打包插件体系。其插件仓库 rollup/plugins 维护了 30+ 个官方插件,社区贡献的插件覆盖几乎所有常见的打包需求。此外,Vite(全球使用最广泛的前端开发工具)底层采用 Rollup 作为生产构建引擎,使得 Rollup 的插件在 Vite 生态中也能广泛复用。
关键依赖
| 依赖 | 作用 |
|---|---|
| acorn | JavaScript 解析器,将源码转换为 AST |
| magic-string | 字符串操作库,用于高效的源码变换和 Source Map 生成 |
| fsevents | macOS 文件监听(可选依赖) |
平台原生绑定(@rollup/rollup-*) | 各平台原生代码加速(可选依赖) |
官方核心插件(@rollup/plugin-*)
| 插件 | 用途 | 说明 |
|---|---|---|
@rollup/plugin-node-resolve | Node.js 模块解析 | 实现 Node.js 的模块解析算法,支持 node_modules |
@rollup/plugin-commonjs | CommonJS 转换 | 将 CommonJS 模块转换为 ES Module,使 npm 包可被打包 |
@rollup/plugin-typescript | TypeScript 支持 | 集成 TypeScript 编译器 |
@rollup/plugin-babel | Babel 转译 | 集成 Babel 进行代码转换 |
@rollup/plugin-terser | 代码压缩 | 使用 Terser 压缩输出代码 |
@rollup/plugin-replace | 字符串替换 | 替换代码中的指定字符串(如环境变量) |
@rollup/plugin-json | JSON 导入 | 允许直接 import JSON 文件 |
@rollup/plugin-alias | 路径别名 | 配置模块路径别名(类似 webpack 的 alias) |
@rollup/plugin-image | 图片导入 | 导入 JPG/PNG/GIF/SVG 图片 |
@rollup/plugin-virtual | 虚拟模块 | 从内存中加载模块 |
@rollup/plugin-dynamic-import-vars | 动态导入 | 支持动态 import() 中的变量 |
@rollup/plugin-eslint | 代码检查 | 在打包过程中运行 ESLint |
@rollup/plugin-inject | 全局注入 | 自动为全局变量添加 import 语句 |
@rollup/plugin-multi-entry | 多入口 | 支持多个入口点 |
社区热门插件
| 插件 | 用途 |
|---|---|
rollup-plugin-typescript2 | 更强大的 TypeScript 支持(常被优先于官方插件使用) |
rollup-plugin-postcss | PostCSS 集成,处理 CSS 预处理器和 CSS Modules |
rollup-plugin-peer-deps-external | 自动将 peerDependencies 标记为外部依赖 |
rollup-plugin-peer-deps-external | 自动排除 peerDependencies |
rollup-plugin-livereload | 开发时热重载 |
rollup-plugin-serve | 简易开发服务器 |
rollup-plugin-copy | 构建时复制文件 |
rollup-plugin-delete | 构建前清理输出目录 |
rollup-plugin-dts | 合并 .d.ts 类型声明文件 |
rollup-plugin-scss | Sass/SCSS 编译支持 |
rollup-plugin-visualizer | 可视化 bundle 内容和分析包体积 |
rollup-plugin-filesize | 显示 bundle 文件大小 |
rollup-plugin-license | 在 bundle 头部添加许可协议声明 |
rollup-plugin-string | 将文本文件作为字符串导入 |
与 Rollup 相关的上游工具
- Vite:底层使用 Rollup 进行生产构建,是 Rollup 最知名的"消费者"
- unbuild:UnJS 生态的库打包工具,基于 Rollup 构建
- tsup:基于 esbuild 的库打包工具(已停止维护),可视为 Rollup 的高层替代方案
- tsdown:tsup 的继任者,基于 Rolldown(Rust 实现的 Rollup 兼容打包器)
- Rolldown:Vite 团队用 Rust 开发的新一代打包器,兼容 Rollup 插件 API,目标替代 Rollup + esbuild
适用场景
- npm 库/开源包开发与发布:Rollup 最核心的使用场景。它的 Tree Shaking 能力确保发布的包体积最小,支持同时输出 ESM + CJS + UMD 多格式。React、Vue、Three.js 等顶级开源库均采用 Rollup 构建
- 前端框架核心打包:框架自身(如 Svelte、Vue 的部分模块)需要极致的包体积优化,Rollup 的静态分析能力无可替代
- Monorepo 子包构建:在 pnpm workspace / Turborepo 等 monorepo 结构中,每个子包使用 Rollup 独立构建,配合
--watch实现增量开发 - UI 组件库打包:需要同时输出 JS + CSS + 类型声明的 UI 组件库,Rollup 搭配 PostCSS 插件可完成完整的样式管线
- CLI 工具打包:配合 shebang 保留、external 配置、target 环境指定,适合打包 Node.js CLI 工具
- SDK / Widget 嵌入式脚本:UMD 或 IIFE 格式输出适合嵌入式脚本场景,如第三方 SDK、浏览器 Widget、分析追踪脚本等
- 微前端/模块联邦中的共享库:SystemJS 格式输出天然适配微前端架构中的共享依赖
开发与工程化
开发流程
# 开发模式(监听文件变化,自动重新构建)
pnpm dev # rollup -c -w
# 生产构建
pnpm build # rollup -c
# 类型检查(Rollup 不做类型检查,需单独运行)
pnpm typecheck # tsc --noEmit
# 测试
pnpm test重要:Rollup 只做代码打包和转换,不做类型检查。TypeScript 项目需要单独运行
tsc --noEmit进行类型检查。
package.json 完整配置参考
{
"name": "@scope/my-library",
"version": "1.0.0",
"type": "module",
"main": "./dist/index.cjs.js",
"module": "./dist/index.esm.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.esm.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs.js"
}
},
"./package.json": "./package.json"
},
"files": ["dist"],
"sideEffects": false,
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"typecheck": "tsc --noEmit",
"lint": "eslint src/",
"test": "vitest run",
"prepublishOnly": "pnpm typecheck && pnpm build"
},
"peerDependencies": {
"react": ">=18.0.0"
},
"devDependencies": {
"rollup": "^4.62.0",
"@rollup/plugin-typescript": "^12.0.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-terser": "^0.4.0",
"rollup-plugin-dts": "^6.0.0",
"typescript": "^5.5.0"
}
}多配置输出(UMD + ESM + CJS + 类型声明)
// rollup.config.mjs
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 dts from 'rollup-plugin-dts'
const external = ['react', 'react-dom']
const basePlugins = [
resolve(),
commonjs(),
typescript({ tsconfig: './tsconfig.json' }),
]
export default [
// 配置 1:ESM + UMD 构建
{
input: 'src/index.ts',
external,
output: [
{
file: 'dist/index.esm.js',
format: 'es',
sourcemap: true,
},
{
file: 'dist/index.umd.js',
format: 'umd',
name: 'MyLibrary',
globals: { react: 'React', 'react-dom': 'ReactDOM' },
sourcemap: true,
plugins: [terser()],
},
],
plugins: basePlugins,
},
// 配置 2:CJS 构建
{
input: 'src/index.ts',
external,
output: {
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true,
},
plugins: basePlugins,
},
// 配置 3:类型声明合并
{
input: 'src/index.ts',
external,
output: {
file: 'dist/index.d.ts',
format: 'es',
},
plugins: [dts()],
},
]CI/CD 集成(GitHub Actions 示例)
name: Build & Publish
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck
- run: pnpm lint
- run: pnpm test
- run: pnpm build
# 验证包发布配置
- run: npx publint
- run: npx are-the-types-wrong dist/
- run: pnpm publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}工程化最佳实践
- 使用
publint验证发布配置:在 CI 中集成 publint 检查exports字段和类型路径是否正确 - 使用
are-the-types-wrong:验证发布的类型声明能被各种消费端正确解析 peerDependencies标记为external:确保 React、Vue 等框架依赖不被打包进库中- 正确配置
sideEffects:在package.json中声明"sideEffects": false(或列出有副作用的文件),帮助下游工具做 Tree Shaking - 分离类型检查与打包:Rollup 不做类型检查,类型检查用
tsc --noEmit - 使用
rollup-plugin-dts合并类型声明:避免类型声明文件碎片化 - 添加
/* @__PURE__ */注释:标记无副作用的函数调用,帮助 Tree Shaking 更精确
性能与安全
性能特点
| 指标 | 表现 |
|---|---|
| 打包速度 | 中等(JavaScript 引擎,比 esbuild/Rolldown 慢,但比 Webpack 快) |
| Tree Shaking 质量 | ⭐⭐⭐⭐⭐ 业界最优——基于完整执行路径分析 |
| 输出体积 | ⭐⭐⭐⭐⭐ 通常最小——精确移除所有死代码 |
| 增量构建 | ✅ Watch 模式支持增量重新构建 |
| 大型项目(10000+ 模块) | 可能需要 30-60 秒(相比 esbuild 的 1-3 秒) |
| 原生加速 | Rollup 4 引入平台特定 native bindings,提升约 20-40% |
性能优化建议
- 善用
external:将不需要打包的依赖标记为外部依赖,减少打包范围 - 使用
@rollup/plugin-terser:生产环境开启代码压缩 - 配置
manualChunks:合理拆分 chunk,避免单个 bundle 过大 - 开发时使用 Watch 模式:
rollup -c -w避免冷启动开销 - 关闭不必要的 Source Map:生产环境如不需要可关闭以加速
- 使用
treeshake.moduleSideEffects:精确配置副作用判断策略 - 考虑使用 Rolldown 替代:对于需要极致构建速度的场景,Rolldown(Rust 实现)可提速 5-10 倍
安全注意事项
- 依赖链安全:Rollup 及其插件生态中存在间接依赖风险,建议定期运行
npm audit或pnpm audit - 配置文件执行:
rollup.config.mjs作为 ES Module 被执行,可访问 Node.js API,需注意代码安全 - 插件信任:社区插件可能存在安全风险,优先使用
@rollup/plugin-*官方插件和高星插件 - Snyk 安全报告:Rollup 核心包近期无高危漏洞,但个别历史版本曾报告过中等风险问题
@rollup/rollup-*原生绑定:Rollup 4 的原生绑定包来自官方仓库,安全性可控
已知性能瓶颈
- JavaScript 引擎限制:核心解析和打包逻辑使用 JavaScript,速度无法与 Go(esbuild)或 Rust(Rolldown)的原生实现相比
- 大型项目扩展性:模块数量超过 10000 时性能下降明显,增量编译优化有限
- TypeScript 编译:使用
@rollup/plugin-typescript时,TypeScript 编译是整体流程中的主要瓶颈 - 首次构建较慢:冷启动需要完整解析所有模块,Watch 模式下的增量构建有明显改善
- 插件链开销:大量插件的 resolve/load/transform 钩子串行执行,增加整体构建时间
技术对比
同类工具对比
| 特性 | Rollup | esbuild | Vite | Webpack | Rolldown | tsup | unbuild |
|---|---|---|---|---|---|---|---|
| 定位 | 库打包标准 | 通用极速打包 | 前端开发工具 | 应用打包标准 | 下一代打包器 | 零配置库打包 | UnJS 库打包 |
| 实现语言 | JavaScript | Go | JS + esbuild/Rollup | JavaScript | Rust | JS + esbuild | JS + Rollup |
| 打包速度 | 🟡 中等 | 🟢 极快 | 🟢 极快(dev) | 🔴 较慢 | 🟢 极快 | 🟢 快 | 🟡 中等 |
| Tree Shaking | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 输出体积 | 最小 | 较小 | 小 | 较大 | 最小 | 较小 | 最小 |
| 插件生态 | ⭐⭐⭐⭐⭐ 丰富 | ⭐⭐⭐ 一般 | ⭐⭐⭐⭐⭐ 丰富 | ⭐⭐⭐⭐⭐ 最丰富 | ⭐⭐⭐ 成长中 | ⭐⭐⭐ 一般 | ⭐⭐⭐⭐ 好 |
| 多格式输出 | ✅ 全部 | ✅ 部分 | ⚠️ 库模式 | ✅ 全部 | ✅ 全部 | ✅ ESM/CJS/IIFE | ✅ 全部 |
| 类型声明 | ❌ 需插件 | ❌ 需工具 | ❌ 需插件 | ❌ 需插件 | ❌ 需插件 | ✅ 内建 | ✅ 内建 |
| 零配置 | ❌ | ❌ | ✅ | ❌ | ⚠️ | ✅ | ⚠️ |
| 适用场景 | 库打包 | 通用打包 | 前端开发 | 应用打包 | 库+应用 | 库打包 | 库打包(UnJS) |
关键差异分析
Rollup vs esbuild:
- esbuild 速度快 10-100 倍(Go vs JS),但 Tree Shaking 不如 Rollup 精确
- Rollup 插件生态远比 esbuild 丰富,支持更多高级打包策略
- esbuild 不支持 UMD/SystemJS 等格式,Rollup 全格式支持
- 很多工具(如 Vite)采用组合策略:esbuild 负责开发(速度),Rollup 负责生产(质量)
Rollup vs Webpack:
- Webpack 是应用打包的事实标准,Rollup 是库打包的事实标准
- Webpack 功能更全面(HMR、代码分割、资源处理),但更重更慢
- Rollup 产出的包体积通常更小,配置更简洁
- Webpack 的生态和社区更大,但 Rollup 在库打包场景更专业
Rollup vs Vite:
- Vite 是上层开发工具,Rollup 是底层打包引擎
- Vite 的生产构建直接使用 Rollup,开发服务器使用 esbuild
- 两者不是竞争关系,而是上下游关系
Rollup vs Rolldown:
- Rolldown 是 Rust 实现的 Rollup 兼容替代,速度提升 5-10 倍
- Rolldown 兼容大部分 Rollup 插件 API,迁移成本低
- Rolldown 是 Vite 8 的底层引擎(替代 Rollup + esbuild)
- Rollup 目前仍是成熟稳定的选择,Rolldown 代表未来方向
最佳实践
生产环境配置推荐
// rollup.config.mjs - 生产环境完整配置
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 replace from '@rollup/plugin-replace'
import dts from 'rollup-plugin-dts'
const pkg = require('./package.json')
const external = [
...Object.keys(pkg.peerDependencies || {}),
...Object.keys(pkg.dependencies || {}),
]
export default [
{
input: 'src/index.ts',
external,
output: [
{
file: pkg.module,
format: 'es',
sourcemap: true,
},
{
file: pkg.main,
format: 'cjs',
sourcemap: true,
exports: 'named',
},
],
plugins: [
resolve({ extensions: ['.ts', '.tsx', '.js', '.jsx'] }),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
declaration: true,
declarationDir: './dist/types',
}),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify('production'),
}),
terser({
format: { comments: false },
compress: { drop_console: true },
}),
],
// Tree Shaking 精细控制
treeshake: {
moduleSideEffects: false, // 假设所有模块无副作用
annotations: true, // 识别 @__PURE__ 注释
},
},
// 合并类型声明
{
input: 'src/index.ts',
external,
output: { file: pkg.types, format: 'es' },
plugins: [dts()],
},
]常见陷阱
- 忘记标记
external:peerDependencies 和 dependencies 必须标记为外部依赖,否则会被打包进 bundle,导致体积膨胀和运行时错误 - CJS 模块无法被 Tree Shake:CommonJS 模块的导入需要
@rollup/plugin-commonjs转换,但转换后的代码通常无法进行 Tree Shaking - TypeScript 的
isolatedModules问题:Rollup 的@rollup/plugin-typescript可能需要特殊的 tsconfig 配置 - 插件顺序很重要:
resolve()应在commonjs()之前;typescript()应在commonjs()之前 - 配置文件扩展名:Rollup 4 中 ES Module 配置文件必须使用
.mjs扩展名,否则可能被当作 CJS 解析 - 动态导入的处理:Rollup 默认保留
import()为外部引用,如需打包动态导入的模块需额外配置 - 循环依赖警告:循环依赖可能导致输出顺序问题,需通过
onLog或treeshake配置处理 sideEffects: false的副作用:如果库中有全局副作用代码(如 polyfill),sideEffects: false会导致它们被意外移除
推荐模式
- 小型工具库:单入口 + ESM/CJS 双格式 + Tree Shaking + 类型声明合并
- UI 组件库:多入口 + code splitting + external 框架 + PostCSS 样式管线 + dts 合并
- CLI 工具:单入口 + CJS/ESM + shebang 保留 + external 所有 Node.js 内建模块
- 嵌入式 SDK:UMD/IIFE 格式 + terser 压缩 + globals 映射 + Source Map
- Monorepo 子包:每个子包独立 Rollup 配置 + watch 模式 + pnpm workspace
技术局限与边界
已知限制
- 打包速度:JavaScript 实现的速度上限,在大型项目(10000+ 模块)中明显慢于 esbuild(Go)和 Rolldown(Rust)
- 不做类型检查:Rollup 只做代码打包,类型检查需要额外工具(
tsc --noEmit) - 不内建开发服务器:Rollup 本身不提供 HTTP 服务器和 HMR,需要搭配
rollup-plugin-serve+rollup-plugin-livereload或使用 Vite - 不处理非 JS 资源:图片、字体、CSS 等非 JavaScript 资源需要额外插件处理
- CJS 模块的 Tree Shaking 限制:CommonJS 模块的静态分析不如 ESM 精确,可能导致死代码残留
- 配置复杂度:对于多格式输出、样式处理、类型声明生成等完整需求,配置较为复杂
- 不支持 HMR:没有内建的模块热更新能力
不适用场景
- 大型 Web 应用打包:Vite(开发) + Webpack(生产)更适合大型应用,支持 HMR、资源处理、代码分割等完整能力
- 需要 HMR 的开发环境:使用 Vite 或 Webpack Dev Server 获得更好的开发体验
- 需要极致构建速度的 CI/CD:esbuild 或 Rolldown 在速度上有数量级优势
- 纯 CSS/资源打包:Rollup 是 JS bundler,CSS 打包需要大量插件辅助
- 需要开箱即用的体验:tsup 或 Vite 提供更零配置的体验
迁移注意事项
从 Rollup 迁移到 Rolldown:
Rolldown 是当前最推荐的 Rollup 升级路径:
- Rolldown 1.0 已于 2026 年 5 月发布,兼容大部分 Rollup 插件 API
- Vite 8 已切换到 Rolldown,社区生态逐步迁移
- 迁移工具和方法正在完善中
- 建议新项目考虑直接使用 Rolldown,现有项目关注 Rolldown 兼容性进展
从 Webpack 迁移到 Rollup:
- 迁移适合场景:库打包(不是应用打包)
- 需要重写 Webpack 特有功能(如
require.context、内建 loader) - 配置模型完全不同(Webpack 面向应用,Rollup 面向库)
- Tree Shaking 效果通常更好,包体积更小
学习资源
官方资源
- 官方文档:https://rollupjs.org/
- 中文文档:https://cn.rollupjs.org/
- 配置选项:https://rollupjs.org/configuration-options/
- 插件开发指南:https://rollupjs.org/plugin-development/
- Rollup 4 迁移指南:https://rollupjs.org/migration/
- 在线 REPL:https://rollupjs.org/repl/(实时实验 Rollup 配置效果)
- 官方插件仓库:https://github.com/rollup/plugins
- 社区插件精选:https://github.com/rollup/awesome
教程与指南
- Complete Guide to Setting Up React with TypeScript and Rollup (2025):React + TypeScript + Rollup 完整搭建指南
- Rollup Plugins for Absolute Beginners:插件系统入门教程
- The 2025 Guide to JS Build Tools:构建工具全景指南
- Best Webpack Alternatives: Modern JS Bundlers 2025:现代打包器对比分析
- 常用插件指南 - 知乎专栏:中文插件配置指南
- 常用插件 - 汪图南博客:中文常用插件文档
- Rollup 打包原理与实战:深入原理分析
社区资源
- GitHub Issues:https://github.com/rollup/rollup/issues
- Stack Overflow(rollupjs 标签):https://stackoverflow.com/questions/tagged/rollupjs
- Reddit 讨论:r/javascript 和 r/node 社区中有多篇深度讨论
- The Story of Rollup(视频):https://www.youtube.com/watch?v=azk-GuGiy3E — Rich Harris 讲述 Rollup 的诞生故事
- State of JavaScript 2025 - Build Tools:https://2025.stateofjs.com/en-US/libraries/build-tools/:年度构建工具使用调查
视频资源
- Webpack 5 vs Parcel vs Vite vs ESBuild, and Rollup:五大打包器深度对比
- Rollup JS setup and build the component library:组件库打包实战
2026 年现状
最新版本
- 当前版本:v4.62.2(2026 年 6 月 19 日发布)
- 发布频率:持续活跃,2026 年已发布 10+ 个版本
- 最近重要更新:
- v4.62.0(2026.06.13):确保 manual chunks 和 entry points 之间的共享依赖获得独立 chunk
- v4.61.0(2026.05.14):提升 chunk hash 稳定性
- v4.60.x(2026.04-05):多项 bug 修复和性能优化
维护状态
✅ 项目持续活跃维护。 Rollup 核心团队(以 Lukas Taegert-Atkinson 为首)保持着稳定的发布节奏。每周下载量超过 1.1 亿次,是 npm 上使用最广泛的包之一。
发展趋势
2025-2026 年 Rollup 生态的关键趋势:
- Rolldown 崛起:Vite 团队用 Rust 开发的 Rolldown 1.0 于 2026 年 5 月正式发布,兼容 Rollup 插件 API,构建速度提升 5-10 倍。Vite 8 已切换底层引擎为 Rolldown
- Rust 化加速:整个构建工具生态加速向 Rust 迁移(Rolldown、Oxc、SWC),Rollup 通过原生绑定(native bindings)应对
- 库打包标准地位稳固:尽管新工具涌现,Rollup 作为"库打包标准工具"的地位短期内难以被完全替代
- 插件生态持续繁荣:官方插件仓库保持活跃更新,社区插件数量持续增长
- ESM-only 趋势:随着 Node.js 和浏览器对 ESM 的完整支持,UMD/CJS 输出的重要性逐步下降
社区活跃度
| 指标 | 数值 |
|---|---|
| GitHub Stars | ~26,300+ |
| npm 周下载量 | ~1.1 亿 |
| GitHub Forks | ~1,800+ |
| 官方插件数 | 30+(@rollup/plugin-*) |
| 社区插件数 | 200+ |
| 累计 Issue 数 | 6,400+ |
| Open GitHub Issues | 活跃维护中 |
未来路线图
- 短期(2026):继续维护 Rollup 4.x,修复 bug,优化原生绑定性能;关注 Rolldown 的兼容性和采用率
- 中期(2026-2027):Rolldown 逐步替代 Vite 中的 Rollup,Rollup 可能进入维护模式(类似 tsup 之于 tsdown)
- 长期:Rollup 的核心价值(Tree Shaking 算法、插件设计理念)将被 Rolldown 等 Rust 实现继承和发扬。Rollup 本身作为"标准制定者"的历史地位已不可动摇
选型建议(2026 年)
| 情况 | 建议 |
|---|---|
| 库打包,追求最小体积 | 继续使用 Rollup |
| 新项目,追求极致构建速度 | 考虑 Rolldown |
| 前端应用开发 | 使用 Vite(底层已切换到 Rolldown) |
| 需要零配置体验 | 使用 tsup / tsdown |
| 在 UnJS/Nuxt 生态中 | 使用 unbuild |
| 现有 Rollup 项目,运行正常 | 继续使用 Rollup,关注 Rolldown 进展 |
| 需要 HMR 开发环境 | 使用 Vite |