在Webpack几乎统治前端应用构建的这几年,很多团队其实忽略了一个事实:Rollup这种同样优秀的打包器,始终在库与组件构建领域活得很好。我最早接触Rollup是因为维护公司内部组件库,明明源码没多少,用Webpack打出来却总是拖着一堆运行时垫片和奇怪的兼容代码,最后切成Rollup之后,产物直接砍掉40%的体积,tree shaking也真正生效了。当时我就在想,大部分前端工程化文章都在讲Webpack怎么调,却很少有人把Rollup和Webpack放在一起,讲清楚它们的边界、各自的优势段位,以及如何在同一套前端工程中配合使用。
这篇文章就是围绕“模块打包优化与性能提升”这个主题,把我在实际项目中同时使用Webpack和Rollup的完整经验写出来。你会看到这两种工具分别适合解决什么问题、为什么库构建推荐用Rollup而应用打包继续用Webpack、如何在不推翻现有工程的前提下引入Rollup做局部优化,以及那些文档里不会写但实际一定会踩的坑。无论你是被Webpack构建速度折磨的应用开发人员,还是要为团队搭建组件库、工具库的工程负责同学,这篇内容应该都能提供一套可落地的操作路径。
1. 先弄清定位:Rollup和Webpack到底谁该出现在你的工程里
很多人一听说Rollup就把Webpack喷得一文不值,这属于典型的工具偏见。在我自己的实践观感里,Rollup和Webpack从来不是谁替代谁的关系,而是分工不同。你必须先想清楚自己要交付什么,再决定用谁。
1.1 两者的核心差异:产物代码与运行时机制
从设计哲学上看,Webpack是一个应用打包器,它考虑的是复杂依赖图、各种静态资源、代码分割、热更新、以及浏览器环境的兼容兜底。它的产物会内置一套模块运行时(runtime),用来在浏览器里动态加载chunk、处理模块之间的引用关系。这套运行时本身是有体积成本的,通常几KB到十几KB不等,尽管在大型应用里这点开销可以忽略,但在一个要发布给很多业务方使用的npm包里,它就是纯粹的负担。
Rollup则完全不同。它出生在ES Modules普及之后,核心思想是“把源码当成一组ES模块,通过静态分析直接合并成一份干净的产物”。Rollup不使用运行时,它把你写的模块代码按依赖关系直接拍平到一个文件里,引用顺序完全可预测。你写什么结构,产物大体还是什么结构,只是去掉了模块包装壳。这种特性让Rollup极其适合生成库文件、组件文件,因为它产出的代码干净、紧凑、没有黑魔法。
一个很直白的对比是:同一个工具函数库,用Webpack打包出来的dist文件里能看到__webpack_require__这种东西,用Rollup打包则完全看不到任何框架痕迹。对使用者来说,后者显然更友好。
1.2 选型逻辑:什么项目用Rollup,什么项目继续用Webpack
在我负责过的前端工程里,我基本按下面几条原则来做选择,大家可以参考。
Webpack的舒适区是业务应用。只要项目需要路由懒加载、按需引入图片字体、开发环境热更新、处理各种loader链,那Webpack或者是它生态下的Vite就是最合适的。你不太会想用Rollup去搭一个需要按页面拆包的中后台应用,虽然它技术上也能做到,但对开发体验的维护成本远超收益。
Rollup的舒适区是发布到npm的库文件。比如组件库、工具函数库、插件的打包产物、甚至被多个应用复用的业务模块。这类产物追求的是体积小、结构清晰、副作用可控、让使用方自己的打包工具能二次tree shaking。我自己维护过一个内部UI组件库,用Rollup同时输出ESM和CJS两种格式,总产物体积比之前用Webpack直接打包时减少了接近一半。
除此之外还有一种情况也很适合Rollup:现有Webpack应用里的大型内部模块如果单独提取出来用Rollup预构建,可以绕开Webpack对这部分代码的重复解析时间,让增量构建明显变快。这个操作我在第五节会详细讲。
1.3 为什么实际工程里会出现“Rollup方案 + Webpack工程”的混合形态
不少团队听到Rollup第一反应是“要不要把Webpack换掉”,其实这是误解。我在真实项目里更常用的是混合构建:整个应用仍然用Webpack搭建,但应用里那些需要被多个入口或外部项目复用的核心模块,会单独拉出来用Rollup打包成ESM格式,然后让Webpack通过alias或者依赖直接引用这份产物。
这么做有三个直接收益。第一,核心模块的构建时间被从Webpack全量构建里剥离,Webpack的依赖解析范围更小,构建速度显著提升。第二,核心模块的产物是ESM,Webpack在打包引用它的时候能够继续做tree shaking,应用体积不会因为预构建反而膨胀。第三,这套核心模块将来如果要从应用里拆成独立npm包,构建链路已经提前验证过,只需要调一下发布脚本。
当然这种混合模式不是没有代价,它要求团队必须维护两套构建配置。我在第二节和第三节会分别讲清楚Webpack侧的优化怎么做、Rollup侧的构建怎么配,以及在联调过程中最容易出的问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Webpack侧的打包优化:先把存量工程的性能榨干
如果你暂时不打算引入Rollup,只是想优化现有Webpack项目,那这一部分同样适用。我见过很多项目一谈优化就想到换构建工具,但往往连基础的持久化缓存都没开。把Webpack自身的潜力榨干之后,再决定要不要引入额外复杂度,这才是工程化的正确顺序。
2.1 分清问题类型:构建速度慢还是产物体积大
做Webpack优化之前先问自己:要解决的是开发时构建慢,还是线上产物体积大?这两个问题的解法和优化方向几乎不重叠,不先分类很容易把配置改得面目全非。
如果是开发时构建慢,通常是模块解析范围太大、loader执行时间过长、缓存失效频繁。这种情况我推荐优先做四件事:
- 把
cache设置为filesystem,让Webpack在磁盘上持久化中间结果。Webpack 5默认就是filesystem缓存,但很多从Webpack 4升上来的项目还在用cache: false或者内存缓存。 - 用`m
