Rollup
什么是 Rollup?
Rollup 是一个 JavaScript 模块打包器,它可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。与 Webpack 偏向于前端应用打包不同,Rollup 最初的设计目标和最擅长的领域是类库(Library)的打包。
Rollup 使用的是 ES6 版本 JavaScript 中的模块标准(ESM),而不是以前的特殊解决方案,如 CommonJS 和 AMD。
核心特性与优势
1. Tree-shaking 的先驱
Rollup 是最早提出并实现 Tree-shaking 概念的构建工具。
- 原理:基于 ES6 模块的静态特性(
import和export是在编译时确定的),Rollup 能够在打包阶段静态分析代码,找出哪些代码被导入了但没有被实际使用,然后在最终生成的 bundle 中将这些“死代码(Dead Code)”剔除掉。 - 相比于早期的 Webpack,Rollup 的 Tree-shaking 更加纯粹和高效,生成的代码体积通常更小。
2. 扁平化打包(Scope Hoisting)
在 Rollup 中,所有的模块都会被提升到一个单一的函数作用域中进行打包(即所谓的 Scope Hoisting,作用域提升)。
- 这避免了像早期 Webpack 那样为每一个模块生成一个闭包函数(IIFE)和模块加载器代码。
- 优点:大大减少了打包后的代码体积;减少了函数闭包导致的内存开销;代码的执行速度更快。
3. 多种输出格式支持
Rollup 非常适合打包类库,因为它原生支持将代码输出为多种格式,以适应不同的使用环境:
iife:自执行函数,适合通过<script>标签直接在浏览器中引入。cjs:CommonJS 规范,适合 Node.js 环境。umd:通用模块定义,兼容 IIFE、AMD、CJS,适合作为万能的库发布。es/esm:ES 模块规范,适合在现代浏览器环境或其他支持 ESM 的打包工具(如 Webpack、Vite)中使用。
面试高频对比:Rollup vs Webpack
| 特性 | Webpack | Rollup |
|---|---|---|
| 定位与侧重点 | 适合构建复杂的前端应用(Application) | 适合构建纯粹的 JavaScript 类库(Library) |
| 生态与功能 | 大而全,支持代码分割、HMR、各种静态资源(图片、CSS 等)处理 | 小而美,专注于 JS 模块打包,静态资源处理依赖插件且相对较弱 |
| 打包产物 | 会生成模块引导代码和闭包(即使有 Scope Hoisting),产物相对臃肿 | 扁平化打包,产物非常干净,几乎只有业务逻辑代码 |
| 模块热更新 (HMR) | 原生支持,生态完善 | 默认不支持,不适合作为复杂前端应用的开发服务器 |
| 依赖处理 | 原生支持 CommonJS 和 ESM | 默认只支持 ESM,处理 CommonJS 需要 @rollup/plugin-commonjs 插件 |
总结:
- 开发应用(App):使用 Webpack 或 Vite。因为应用通常需要处理各种静态资源、复杂的代码分割、热更新等,Webpack 的生态更完善。
- 开发类库(Library):使用 Rollup。因为类库通常只需要暴露几个 API,需要打包出的代码尽可能干净、体积小,且需要输出 ESM/CJS/UMD 等多种格式供不同环境使用。
注:Vite 的生产环境构建底层也是基于 Rollup 来实现的,充分利用了 Rollup 优秀的打包和 Tree-shaking 能力。