# Rollup 概述

# 文档

Rollup 英文文档 (opens new window)

Rollup 中文文档 (opens new window)

# 什么是Rollup

Rollup 是一个 JavaScript 模块打包工具,它可以将多个 JavaScript 文件(模块)打包成一个文件,使得应用程序的加载速度更快、体积更小。其主要目标是生成轻量、快速且高效的代码包,特别适用于库和框架的打包发布。

Rollup 使用 JavaScriptES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJSAMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。

# Rollup 有哪些特点

  • 模块化支持:

    Rollup 专注于原生 ES 模块(ESM)的打包。ES 模块允许开发者将代码拆分成多个独立的模块,这有助于提高代码的可维护性和可重用性。Rollup 可以将这些模块打包成单个文件,便于在浏览器或其他环境中运行。

  • 摇树优化(Tree-shaking):

    Rollup 的一个核心特性是摇树优化,它可以自动移除代码中未使用的部分(“死代码”),从而减少最终打包文件的体积。这在优化打包库或框架时尤为重要,特别是当库中包含大量功能但只使用其中一部分时。

  • 轻量打包:

    Rollup 输出的代码文件非常轻量且易于理解,它生成的包往往比其他工具(如 Webpack)打包的文件更小。因为 Rollup 聚焦于移除冗余代码并保留必要的部分,以减少不必要的性能开销。

  • 可配置性和灵活性:

    Rollup 提供了高度可配置的插件系统,使开发者能够根据项目的需求自定义打包流程。无论是处理 CSS、TypeScript,还是其他资源类型,Rollup 都可以通过插件扩展其功能。

# Rollup 有哪些缺点

  • 缺少复杂应用的功能支持

Rollup 主要是为打包库和框架设计的,虽然它可以打包应用程序,但与 Webpack 相比,Rollup 在打包复杂的前端应用程序时缺少一些重要功能,例如动态导入、开发服务器和热模块替换(HMR)等功能。这使得它在开发大型前端应用程序时可能不如 Webpack 等工具灵活。

  • 生态系统不如 Webpack 丰富

虽然 Rollup 也有插件系统,但相比 WebpackRollup 的插件生态相对较小。某些特定功能(如 CSS 模块化处理、复杂的资源加载等)可能需要额外的配置或开发自定义插件。

  • 对非 ES 模块 支持有限

Rollup 更倾向于 ES 模块的打包,而对 CommonJS(CJS)的支持相对较弱。虽然可以通过插件(如 @rollup/plugin-commonjs)来处理 CommonJS 模块,但与 Webpack 的模块处理相比,这通常需要更多配置,且在某些场景下可能无法完美兼容。

  • 代码拆分功能有限

虽然 Rollup 支持代码拆分(Code Splitting),但在处理复杂的动态依赖图时,它的能力不如 Webpack。Webpack 在处理异步模块加载、动态导入和按需加载方面更具优势。

  • 配置较为复杂

尽管 Rollup 的配置比 Webpack 更简单直观,但对于某些特定场景,比如需要整合多种工具(如 BabelTypeScriptCSS 预处理等)时,Rollup 的配置可能变得复杂,尤其是当使用多个插件时,如何让它们协同工作可能不直观。

  • 开发体验较弱

与 Webpack 等工具不同,Rollup 不自带开发服务器,因此需要额外配置诸如 rollup-plugin-serverollup-plugin-livereload 等插件来实现开发服务器和热更新功能,这使得开发体验不如 Webpack 方便。

# 为什么要学习 Rollup

Rollup 特别适合构建轻量的库和工具,它生成的代码更加简洁,且可以根据项目需要生成不同格式的模块,适用于浏览器、Node.js 或其他运行环境。

许多著名的前端库(如 Vue.jsReactSvelte)都采用 Rollup 作为打包工具。学习 Rollup 可以让你更好地理解这些库的构建过程,并掌握相应的开发技巧。

Rollupesbuild 是组成 Vite 的两架马车。下面是 vite 的架构图

vite架构图

# 摇树优化(tree shaking)

除了可以使用 ES 模块之外,Rollup 还可以静态分析你导入的代码,并将排除任何实际上没有使用的内容,从上面的引入和最后的打包结果就可以看到,没有使用到的内容直接被删除了。

注意,摇树优化的核心思想是在编译阶段通过静态分析确定代码的使用情况,而不是在运行时

所以摇树优化一般是建立在ES6 模块化语法基础之上的,ESM的导入导出是静态的。

CommonJS 模块的导入和导出是动态的,无法在编译阶段静态确定代码的使用情况。一般情况下,摇树优化工具无法在 CommonJS 模块中进行精确的摇树,因为无法静态分析模块间的导入和导出关系。

然而,一些构建工具(如 Webpack)会尝试通过静态分析和启发式方法对 CommonJS 模块进行近似的摇树优化。它们会尽可能地识别出那些可以在编译阶段确定未被使用的代码,并进行剔除。但这种处理方式可能不如对 ES6 模块的优化效果好,且有一定的限制。

摇树优化的原理:

  1. 静态分析:对 JavaScript 代码进行静态分析,识别出模块的导入和导出关系。
  2. 标记未使用代码:标记出在导入和导出关系上没有被使用的代码。这些代码可能是模块的导出函数、变量、类等。
  3. 剔除未使用代码:根据标记结果,构建工具会将未被使用的代码从最终的打包结果中剔除,只保留被使用的部分。