Rollup logo

Rollup

JavaScript 模块打包器——将小块代码编译为更大、更复杂的库或应用,是 Tree Shaking 概念的开创者和 ES Module 打包领域的工业标准。

精选工具BundlerES ModuleTree Shaking库打包标准

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/
  • GitHubhttps://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 的插件系统基于一系列生命周期钩子,分为三个阶段:

  • 构建阶段钩子buildStartresolveIdloadtransformbuildEnd):在模块解析和加载过程中调用
  • 输出生成钩子renderStartrenderChunkgenerateBundle):在代码生成过程中调用
  • 输出生成后钩子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)。

工作原理

  1. 入口解析:从配置的 input 入口文件开始
  2. 依赖图构建:递归分析所有 import 语句,构建完整的模块依赖图
  3. 插件转换:在模块加载过程中,通过插件进行 TypeScript 编译、CSS 处理等转换
  4. Tree Shaking:静态分析所有模块的导出,标记未被引用的代码并移除
  5. 副作用分析:根据 sideEffects 标注判断模块是否有副作用,决定是否可以安全移除
  6. 作用域提升(Scope Hoisting):将多个模块合并到同一作用域中,减少函数包装开销
  7. 代码生成:根据 format 配置输出对应格式的 bundle
  8. 代码拆分(Code Splitting):支持 manualChunkspreserveModules 将代码分割为多个 chunk

核心特性

  • 🌳 卓越的 Tree Shaking:基于静态分析和执行路径追踪的死代码消除,是 Rollup 最核心的竞争力。产出的包体积通常比 Webpack/esbuild 方案更小
  • 📦 多格式输出:一次构建同时输出 ES Module、CommonJS、UMD、AMD、SystemJS、IIFE 等多种格式,覆盖所有使用场景
  • 🔌 强大的插件系统:提供易学且强大的插件 API,拥有丰富的官方和社区插件生态(200+ 插件)
  • 📊 代码拆分:支持 manualChunkspreserveModules 等策略进行细粒度代码拆分
  • 🏷️ 多入口支持:支持多个入口文件同时打包,自动生成共享 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 生态中也能广泛复用。

关键依赖

依赖作用
acornJavaScript 解析器,将源码转换为 AST
magic-string字符串操作库,用于高效的源码变换和 Source Map 生成
fseventsmacOS 文件监听(可选依赖)
平台原生绑定(@rollup/rollup-*各平台原生代码加速(可选依赖)

官方核心插件(@rollup/plugin-*

插件用途说明
@rollup/plugin-node-resolveNode.js 模块解析实现 Node.js 的模块解析算法,支持 node_modules
@rollup/plugin-commonjsCommonJS 转换将 CommonJS 模块转换为 ES Module,使 npm 包可被打包
@rollup/plugin-typescriptTypeScript 支持集成 TypeScript 编译器
@rollup/plugin-babelBabel 转译集成 Babel 进行代码转换
@rollup/plugin-terser代码压缩使用 Terser 压缩输出代码
@rollup/plugin-replace字符串替换替换代码中的指定字符串(如环境变量)
@rollup/plugin-jsonJSON 导入允许直接 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-postcssPostCSS 集成,处理 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-scssSass/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 }}

工程化最佳实践

  1. 使用 publint 验证发布配置:在 CI 中集成 publint 检查 exports 字段和类型路径是否正确
  2. 使用 are-the-types-wrong:验证发布的类型声明能被各种消费端正确解析
  3. peerDependencies 标记为 external:确保 React、Vue 等框架依赖不被打包进库中
  4. 正确配置 sideEffects:在 package.json 中声明 "sideEffects": false(或列出有副作用的文件),帮助下游工具做 Tree Shaking
  5. 分离类型检查与打包:Rollup 不做类型检查,类型检查用 tsc --noEmit
  6. 使用 rollup-plugin-dts 合并类型声明:避免类型声明文件碎片化
  7. 添加 /* @__PURE__ */ 注释:标记无副作用的函数调用,帮助 Tree Shaking 更精确

性能与安全

性能特点

指标表现
打包速度中等(JavaScript 引擎,比 esbuild/Rolldown 慢,但比 Webpack 快)
Tree Shaking 质量⭐⭐⭐⭐⭐ 业界最优——基于完整执行路径分析
输出体积⭐⭐⭐⭐⭐ 通常最小——精确移除所有死代码
增量构建✅ Watch 模式支持增量重新构建
大型项目(10000+ 模块)可能需要 30-60 秒(相比 esbuild 的 1-3 秒)
原生加速Rollup 4 引入平台特定 native bindings,提升约 20-40%

性能优化建议

  1. 善用 external:将不需要打包的依赖标记为外部依赖,减少打包范围
  2. 使用 @rollup/plugin-terser:生产环境开启代码压缩
  3. 配置 manualChunks:合理拆分 chunk,避免单个 bundle 过大
  4. 开发时使用 Watch 模式rollup -c -w 避免冷启动开销
  5. 关闭不必要的 Source Map:生产环境如不需要可关闭以加速
  6. 使用 treeshake.moduleSideEffects:精确配置副作用判断策略
  7. 考虑使用 Rolldown 替代:对于需要极致构建速度的场景,Rolldown(Rust 实现)可提速 5-10 倍

安全注意事项

  • 依赖链安全:Rollup 及其插件生态中存在间接依赖风险,建议定期运行 npm auditpnpm audit
  • 配置文件执行rollup.config.mjs 作为 ES Module 被执行,可访问 Node.js API,需注意代码安全
  • 插件信任:社区插件可能存在安全风险,优先使用 @rollup/plugin-* 官方插件和高星插件
  • Snyk 安全报告:Rollup 核心包近期无高危漏洞,但个别历史版本曾报告过中等风险问题
  • @rollup/rollup-* 原生绑定:Rollup 4 的原生绑定包来自官方仓库,安全性可控

已知性能瓶颈

  1. JavaScript 引擎限制:核心解析和打包逻辑使用 JavaScript,速度无法与 Go(esbuild)或 Rust(Rolldown)的原生实现相比
  2. 大型项目扩展性:模块数量超过 10000 时性能下降明显,增量编译优化有限
  3. TypeScript 编译:使用 @rollup/plugin-typescript 时,TypeScript 编译是整体流程中的主要瓶颈
  4. 首次构建较慢:冷启动需要完整解析所有模块,Watch 模式下的增量构建有明显改善
  5. 插件链开销:大量插件的 resolve/load/transform 钩子串行执行,增加整体构建时间

技术对比

同类工具对比

特性RollupesbuildViteWebpackRolldowntsupunbuild
定位库打包标准通用极速打包前端开发工具应用打包标准下一代打包器零配置库打包UnJS 库打包
实现语言JavaScriptGoJS + esbuild/RollupJavaScriptRustJS + esbuildJS + 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()],
  },
]

常见陷阱

  1. 忘记标记 external:peerDependencies 和 dependencies 必须标记为外部依赖,否则会被打包进 bundle,导致体积膨胀和运行时错误
  2. CJS 模块无法被 Tree Shake:CommonJS 模块的导入需要 @rollup/plugin-commonjs 转换,但转换后的代码通常无法进行 Tree Shaking
  3. TypeScript 的 isolatedModules 问题:Rollup 的 @rollup/plugin-typescript 可能需要特殊的 tsconfig 配置
  4. 插件顺序很重要resolve() 应在 commonjs() 之前;typescript() 应在 commonjs() 之前
  5. 配置文件扩展名:Rollup 4 中 ES Module 配置文件必须使用 .mjs 扩展名,否则可能被当作 CJS 解析
  6. 动态导入的处理:Rollup 默认保留 import() 为外部引用,如需打包动态导入的模块需额外配置
  7. 循环依赖警告:循环依赖可能导致输出顺序问题,需通过 onLogtreeshake 配置处理
  8. 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

技术局限与边界

已知限制

  1. 打包速度:JavaScript 实现的速度上限,在大型项目(10000+ 模块)中明显慢于 esbuild(Go)和 Rolldown(Rust)
  2. 不做类型检查:Rollup 只做代码打包,类型检查需要额外工具(tsc --noEmit
  3. 不内建开发服务器:Rollup 本身不提供 HTTP 服务器和 HMR,需要搭配 rollup-plugin-serve + rollup-plugin-livereload 或使用 Vite
  4. 不处理非 JS 资源:图片、字体、CSS 等非 JavaScript 资源需要额外插件处理
  5. CJS 模块的 Tree Shaking 限制:CommonJS 模块的静态分析不如 ESM 精确,可能导致死代码残留
  6. 配置复杂度:对于多格式输出、样式处理、类型声明生成等完整需求,配置较为复杂
  7. 不支持 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 效果通常更好,包体积更小

学习资源

官方资源

教程与指南

社区资源

视频资源

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 生态的关键趋势:

  1. Rolldown 崛起:Vite 团队用 Rust 开发的 Rolldown 1.0 于 2026 年 5 月正式发布,兼容 Rollup 插件 API,构建速度提升 5-10 倍。Vite 8 已切换底层引擎为 Rolldown
  2. Rust 化加速:整个构建工具生态加速向 Rust 迁移(Rolldown、Oxc、SWC),Rollup 通过原生绑定(native bindings)应对
  3. 库打包标准地位稳固:尽管新工具涌现,Rollup 作为"库打包标准工具"的地位短期内难以被完全替代
  4. 插件生态持续繁荣:官方插件仓库保持活跃更新,社区插件数量持续增长
  5. 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