Rollup 是一个 JavaScript 模块打包器。它的主要工作是将你编写的、分散的、多个小的 JavaScript 文件(或模块),按照它们的依赖关系,打包成一个或少数几个优化后的、可供浏览器高效执行的文件。

为什么需要打包?

要理解 Rollup,首先要明白为什么我们需要“打包”这个步骤。

  1. 模块化开发:现代前端项目非常复杂,我们不会把所有代码写在一个巨大的  main.js  文件里。而是采用 ES Module(import/export)等语法,将代码拆分成许多小的、功能独立的模块。这样便于代码的维护和复用。
  2. 浏览器瓶颈:然而,浏览器如果直接加载几百甚至上千个小文件,会产生大量的 HTTP 请求,严重拖慢页面加载速度。而且,并不是所有浏览器都原生支持 ES Module 语法。
  3. 代码优化:在开发中,我们可能会使用一些浏览器不支持的语法(如 TypeScript、JSX),或者使用一些未压缩的库。这些代码不能直接用于生产环境。

打包器就是来解决这些问题的。  它扮演着一个“构建流水线”的角色:

  • 依赖解析:从入口文件开始,分析所有  import  和  export,构建出一个完整的依赖关系图。
  • 代码转换:通过插件(如  @rollup/plugin-typescript),将 TypeScript、JSX、Sass 等非原生 JavaScript 代码转换成浏览器能识别的 JavaScript 和 CSS。
  • Tree-shaking:这是 Rollup 的王牌特性。它会静态分析你的代码,并“摇掉”那些你定义了但从未使用过的代码(dead code)。这能极大地减小最终打包文件的体积。
  • 代码合并与压缩:将成千上万的模块合并成少数几个文件(甚至一个文件),并进行压缩、混淆,以减少文件体积。

Rollup 的核心特点

与另一个著名打包器 Webpack 相比,Rollup 有其鲜明的特点:

  1. 基于 ES Module 标准设计:Rollup 从设计之初就专注于 ES Module,而不是 CommonJS。这使得它的 Tree-shaking 非常高效和准确。
  2. 输出结果更干净:Rollup 打包产生的代码非常“干净”,几乎没有模块包装器等冗余代码,更接近手写代码。这使得它特别适合打包库
  3. 配置更简洁:它的配置和概念通常比 Webpack 更简单直接。

适用场景:

  • 构建 JavaScript 库:如 React、Vue、Vuex 等众多知名库都使用 Rollup 进行打包,因为它能产生更小、更纯净的包。
  • 构建现代 Web 应用:尤其适合使用 Vite 的项目。

Vite 与 Rollup 的关系

Vite 会使用 Rollup 进行打包

Vite 在开发阶段和生产阶段采用了不同的策略:

  1. 开发阶段:Vite 使用  ES Module  的方式直接为浏览器提供源代码。它不使用 Rollup,而是启动一个开发服务器,当你请求一个模块时,它再按需进行编译和返回。这带来了极快的冷启动速度和热更新。
  2. 生产阶段:当运行  vite build  时,Vite 会调用  Rollup  来进行打包。
    • 为什么?  因为在生产环境中,使用未打包的、分散的 ES Module 仍然不是最佳实践(尽管现代浏览器支持)。大量的网络请求会影响性能。为了获得最佳的加载性能,我们仍然需要将代码打包、压缩和优化。
    • Vite 将你在  vite.config.js  中的配置,转化为 Rollup 能理解的选项,然后利用 Rollup 强大的打包能力和其丰富的插件生态系统(Vite 插件兼容 Rollup 插件接口)来构建最终的生产版本。

你可以把它们的合作关系理解为:

Vite = 极速的开发服务器 + 预配置好的 Rollup

Vite 吸收了 Rollup 在打包领域的稳定性和强大功能,同时在前端(开发阶段)做出了革命性的创新。

对比 Rspack 与 Rollup、Webpack

Rspack 的出现给前端构建工具领域带来了新的选择。

  • Webpack功能全面的老牌霸主。生态庞大,功能丰富,但配置复杂,性能在超大规模项目上可能成为瓶颈。
  • Rollup高效的库打包专家。设计简洁,Tree-shaking 出色,输出代码干净,尤其适合打包库。
  • Rspack基于 Rust 的快速继任者。旨在提供与 Webpack 相似的开发体验和生态兼容性,但通过 Rust 获得极致的构建性能。

详细对比表格

特性维度RspackWebpackRollup
核心技术Rust (高性能编译语言)JavaScript (Node.js)JavaScript (Node.js)
性能极快。编译速度、热更新速度远超 Webpack,接近 Vite。较慢。特别是大型项目,冷启动和热更新有感知延迟。中等。打包库时优化很好,但生态插件速度不一。
设计初衷应用打包。对标 Webpack,旨在提升构建速度。应用打包。大而全,解决前端工程化的所有问题。库打包。产出干净、优化的库代码。
配置与生态高度兼容 Webpack。配置、Loader、Plugin 设计与 Webpack 极其相似,迁移成本低。生态极其丰富。拥有最庞大的 Loader 和 Plugin 生态系统。生态专注。插件生态更专注于打包相关功能,不如 Webpack 庞大。
Tree-shaking很好。基于 Rust 的 SWC 编译器,静态分析能力强。很好。但实现相对复杂,在某些边缘情况下可能不如 Rollup。极好。是其核心优势,静态分析非常准确,死代码消除最彻底。
开发体验快。快速冷启动和热更新,体验接近现代工具如 Vite。慢。项目越大,启动和等待热更新的时间越长。需要配合其他工具(如  rollup-plugin-serve),原生不关注开发服务器。
输出质量很好。专注于应用,打包产物经过优化。很好。经过多年优化,产物质量很高,但可能会有一些运行时包装代码。极好。产物非常干净、紧凑,几乎没有冗余代码,非常适合库。
学习成本 (对 Webpack 用户)。几乎无需学习新概念。。配置复杂,概念众多(Loader, Plugin, Chunk, Bundle 等)。。概念比 Webpack 简单,但生态和高级用法仍需学习。
适用场景中大型 Web 应用。对构建性能有高要求,尤其是从 Webpack 迁移的项目。任何规模的 Web 应用。需要用到各种特殊生态插件的复杂项目。JavaScript 库和 SDK。如 React, Vue, Lodash-es 等。

Rspack:速度与兼容性的平衡者

Rspack 是由字节跳动开发的,它的核心理念是:“为什么不用一个更快的工具来实现 Webpack 的功能呢?”

  • 核心技术优势:使用 Rust 编写,在模块解析、代码转换、打包等 CPU 密集型任务上比 JavaScript 快一个数量级。
  • 生态兼容性:这是 Rspack 的杀手锏。它的大部分配置项与 Webpack 保持一致,并且可以直接使用大部分 Webpack 的 Loader 和 Plugin。这意味着一个现有的 Webpack 项目可以几乎零成本地迁移到 Rspack,并立即获得巨大的性能提升。
  • 内置功能强大:默认集成了 SWC(一个基于 Rust 的快速 Babel 替代品),用于 JavaScript 和 TypeScript 的转换,以及 PostCSS 用于 CSS 处理,无需额外配置。

简单来说,Rspack 可以看作是一个“用 Rust 重写的、性能大幅提升的、且兼容 Webpack 生态的”构建工具。

Webpack:生态与功能的集大成者

Webpack 是当前事实上的标准,它的优势在于其成熟度和生态系统

  • 无所不包的生态:任何你能想到的构建需求,几乎都能在 Webpack 的插件生态中找到解决方案(如 PWA、微前端、资源优化等)。
  • 代码分割:它的代码分割和懒加载功能非常成熟和强大,是大型应用的基石。
  • 痛点性能配置复杂度是其最大的痛点。随着项目规模增长,构建速度会显著下降,复杂的配置也被称为“Webpack 配置工程师”。

Rollup:简洁与高效的库打包专家

Rollup 的哲学是“做一件事并把它做好”。它专注于 ES Module 的打包。

  • Tree-shaking 的王者:由于其静态模块分析的方式,Rollup 消除无用代码的能力是最强的,这对于发布给他人使用的库来说至关重要,可以确保用户不会引入他们不需要的代码。
  • 干净的输出:打包后的代码几乎没有模块系统自身的运行时开销,可读性高,就像手写的一样。
  • 痛点:在开发大型应用时,其生态不如 Webpack 全面(例如,对动态导入、代码分割的热更新支持不如 Webpack 成熟),因此通常不作为大型应用的首选打包器。