一、资源打包概述

一句话说清楚:资源打包就是把一堆零散的 JS、CSS、图片、字体…… 揉成一个或几个能在浏览器里直接跑的文件。这个看似简单的过程,背后藏了十多年的工程化演进。

1.1 什么是资源打包

我们先抛开所有工具,想想看:一个现代前端项目里,你写了 100 个 ES Module 文件、引用了 20 个 npm 包、用了 TypeScript 和 SCSS,浏览器能直接跑吗?

不能。 浏览器不认识 import 语法,不知道 .ts 怎么解析,更别说处理 .scss 了。所以我们需要一个“中间人”——把源码转换成浏览器能理解的格式,这就是打包要做的事。

我个人习惯把打包理解成三条流水线:

  1. 依赖分析——从入口文件开始,顺着 import/require 把所有模块摸清楚,画出一张依赖图。
  2. 转换——用各种 loader 把 TS 转 JS、SCSS 转 CSS、ESNext 转 ES5…… 嗯,这里要注意 loader 的顺序,我在项目中踩过不止一次坑。
  3. 合并输出——把转换好的模块按某种格式(IIFE、CommonJS、ESM……)打包成一个或多个 bundle 文件。

你想想看,如果没有打包这一步,你得手动在 HTML 里写几十个 script 标签,还要保证顺序正确——那场景简直噩梦。我曾经在一个老项目中见过 300 多行脚本引用,后来用了 Webpack 才解放了双手。

1.2 前端打包的历史演变

打包不是一开始就有的。早期前端很简单,写几个 .js 文件,用全局变量通信就行。但项目大了以后,问题就来了:命名冲突、依赖顺序、模块复用…… 于是社区开始折腾。

我大致把它分成四个阶段:

阶段时间代表工具核心痛点
无打包时代~2010直接写 script全局污染,依赖混乱
任务流时代2010-2014Grunt、Gulp只是任务编排,不解决模块化
模块打包时代2015-2018Webpack、Rollup体积大、配置复杂
原生 ESM + 精简化时代2019-今Vite、Parcel 2 / Turbopack开发慢、打包重

记得在 2016 年我刚接触 Webpack 时,光配一个 css-loader 就折腾了一下午,当时还纳闷:为什么这么复杂?但现在回头看,正是 Webpack 让前端工程化真正落地了。

一个关键转折点:浏览器开始支持原生 ESM(<script type="module">)。这意味着开发阶段可以不用打包,直接请求模块文件——Vite 就是抓住这个契机,用 esbuild 做预构建,做到了秒启动开发服务器。

1.3 常见打包工具介绍

市面上打包工具不少,但真正主流的是这四个:Webpack、Rollup、Vite、Parcel。我简单说说他们的定位和适合场景。

Webpack —— 全能型选手

你想想看,一个工具能处理 JS、CSS、图片、字体,还能做代码分割、热更新、tree shaking … 它就是前端界的瑞士军刀。我的个人经验是:如果项目复杂、需要高度定制,Webpack 依然最稳。但代价就是配置多,有时一个插件版本冲突能查半天。我曾经在升级 Webpack 5 时,因为 loader 兼容性问题多花了三天调试。

Rollup —— 库打包首选

Rollup 的理念是“纯 ES Module 打包”,它生成的 bundle 非常干净,几乎没有冗余代码。我的建议:如果你想打包一个 npm 库或组件库,优先用 Rollup。它原生支持 tree shaking,而且输出格式(ESM、CJS、UMD)切换方便。但 Rollup 对代码分割、HMR 支持较弱,不适合大型应用。

Vite —— 开发体验最优

Vite 的最大亮点是“快”。它利用浏览器原生 ESM 在开发时不做打包,只做转换;生产环境才用 Rollup 做打包。我亲自试过,一个 Vue3 项目用 Vite 启动只需 0.5 秒,而用 Webpack 要 5-6 秒。从 2022 年开始,我个人所有新项目都改用 Vite 了,除非有历史包袱。但也有一点要注意:Vite 的插件生态不如 Webpack 丰富,一些超冷门的 loader 可能没现成的。

Parcel —— 零配置极简派

Parcel 号称“零配置开箱即用”,你只要把入口文件传给它,它自动识别 TypeScript、SCSS 等。我试过用它搭一个小型活动页,确实省心。但为什么我用得少?因为项目稍微复杂点(比如需要自定义 loader 或 plugin),Parcel 的定制能力就显弱了。它适合快速原型或小型项目。

一句话选型指南:
- 大型应用 → Webpack(或 Vite,如果你能接受生态差异)
- 库/组件库 → Rollup
- 新项目、快速开发 → Vite
- 零门槛演示 → Parcel

好了,我们理清了“打包是什么、怎么演变而来、现在有哪些工具”。其实不管工具怎么变,核心逻辑没变:把开发者友好的代码,变成浏览器友好的代码。下面这张图从整体上帮你梳理了本章的知识脉络——

资源打包概述 · 知识体系 核心概念 输入:JS / CSS / TS / 图片 / 字体 处理:依赖分析 / 转换 / 合并 输出:Bundle 文件(IIFE / ESM / CJS) 历史演变 无打包时代:直接 script 引用 任务流:Grunt / Gulp(只合并不转换) 模块打包:Webpack / Rollup(全流程) 原生 ESM + 精简化:Vite / Turbopack 主流工具 Webpack:全能 · 大型应用首选 Rollup:库 · 干净输出 Vite:开发极速 · 新项目首选 Parcel:零配置 · 快速原型 核心逻辑总结 输入(开发者友好) → 依赖分析 + 转换 + 合并 → 输出(浏览器友好) 历史趋势:从手动 → 任务流 → 全流程打包 → 原生 ESM 精简化
注意:虽然工具在变,但核心理论(模块依赖、作用域隔离、tree shaking)是通用的。不要只学怎么配某个工具,而要理解它背后的设计思想。否则换一个工具你又要从头学起。