← 返回 构建与部署图解 目录

📦 前端打包全链路

Webpack 和 Vite 到底在干嘛?为什么 Vite 快?一页看懂

① 先搞懂:打包到底是干嘛的?

你写的代码浏览器看不懂,打包工具帮你翻译+整理成浏览器能直接用的文件。
.vue / .jsx / .scss / TypeScript → 翻译成 → .js / .css / .png(浏览器认的格式)
你写了一堆 .vue.scss.ts 文件,还用了 import 互相引用。但浏览器只认 HTML/CSS/JS 三件套,不认识 .vue 是啥。

打包工具就是翻译官+搬运工:把你写的各种格式的源码,翻译成浏览器能直接跑的 JS/CSS/图片,还要把零散的文件合并、压缩、优化,最后放到 dist/ 目录里,就能部署上线了。

目前主流打包工具有两个:

📦
Webpack
老牌选手(2012年),生态最成熟。先把所有文件打包成一个 bundle,再启动。
特点:稳,但启动慢
Vite
新秀(2020年),Vue 作者出品。不打包,浏览器要什么才编译什么。
特点:快,秒级启动

② Webpack 怎么打包的?

Webpack = 工厂流水线:开门营业前,要把所有菜提前做好摆好。
从入口文件开始,顺着 import 一路找下去,把所有用到的文件都找出来 → 用 loader 翻译 → 用 plugin 加工 → 最后打包成一个 bundle.js。

问题:项目越大,要找的文件越多,启动越慢(几十秒到几分钟)。
① Entry 入口文件 ② 依赖收集 顺着import找 ③ Loader 翻译文件 ④ Plugin 额外加工 ⑤ Output 输出dist/ 从入口开始 → 递归找所有依赖 → loader翻译非JS文件 → plugin做额外处理 → 输出到dist ⚠️ 必须把所有文件都找完打包完,才能启动 → 项目越大越慢
Webpack 打包 5 步:入口 → 依赖收集 → Loader 翻译 → Plugin 加工 → 输出

Loader 和 Plugin 有啥区别?

Loader(加载器)Plugin(插件)
干嘛的翻译文件内容在整个过程中做额外的事
举例vue-loader 把 .vue 变成 JS
babel-loader 把 ES6 变成 ES5
sass-loader 把 .scss 变成 CSS
HtmlWebpackPlugin 生成 HTML
MiniCssExtractPlugin 抽取 CSS
CompressionWebpackPlugin 压缩
一句话"怎么翻译文件""还能干什么别的事"
面试常问"loader 和 plugin 区别"——记住一句话:loader 管翻译文件,plugin 管扩展功能

③ Vite 怎么工作的?

Vite = 快闪店 / 回转寿司:开门就营业,客人点什么现做什么。
不提前打包!浏览器请求哪个文件,Vite 就现场编译哪个文件返回。

结果:启动只要不到 1 秒,不管项目多大都这么快。
① esbuild 预构建 把 node_modules 里的库 用 Go 编译,极快 ② 启动 dev server 就这一步,启动完成! ⚡ < 1 秒 ③ 按需编译 浏览器请求哪个文件 才编译哪个,不打包 Webpack:全部打包完 → 启动(等很久)    Vite:直接启动 → 用到才编译(秒开) ✅ Vite 启动时间和项目大小无关,永远是毫秒级 ❌ Webpack 启动时间和项目大小成正比,项目越大越慢
Vite 工作流程:预构建依赖 → 秒级启动 → 按需编译(不打包)

④ 为什么 Vite 这么快?(面试必问)

三个原因(面试标准答案):
🚀
① esbuild 预构建
Go 语言写的 esbuild 编译第三方库,比 babel(JS写的)快 10~100倍。Go 是编译型语言,天生比 JS 快,还用多核并行。
🌐
② Native ESM
开发时不打包!利用浏览器原生的 ES Modules 能力,浏览器请求哪个文件就编译哪个,直接返回 ESM 格式的 JS。
🎯
③ 按需编译
只编译当前页面用到的文件。500 页面的后台系统,打开登录页只编译登录页那 10 个文件,剩下 490 个不碰。
注意区分:Vite 开发时不打包(用 esbuild + 浏览器 ESM),但生产构建时还是要打包的!生产用 Rollup 打包(Tree Shaking 更彻底、产物更小)。
开发追求快 → esbuild;生产追求优 → Rollup。两个工具各司其职。

⑤ 几个常见概念(一句话搞懂)

🌳
Tree Shaking(摇树)
打包时自动删掉没被用到的代码。你 import 了 lodash 但只用了 debounce,其他函数不会打包进去。
前提:必须用 ES Module(import/export),CommonJS(require)不行。
✂️
Code Splitting(代码分割)
把一个大 bundle 拆成多个小 chunk,按需加载。首屏只加载首页代码,其他页面用到才加载。常见方式:动态 import()
🔥
HMR(热更新)
改了代码不刷新整个页面,只替换改的那个模块,保留页面状态(表单输入、滚动位置)。
Webpack 要重新编译模块链(慢);Vite 只编译那一个文件(快,恒定 50ms)。
📦
Chunk(代码块)
多个模块打包在一起就是一个 chunk。比如 vendor.js(第三方库)+ main.js(你的代码)+ home.js(首页懒加载)。

HMR 热更新原理(简单版)

传统刷新(F5)= 脱光重穿:全身衣服都脱了再穿,身上带的东西(页面状态)全丢了。
HMR = 只换一件:坐着不动,只换那一件要换的衬衫,其他不碰,状态全保留。

流程:文件改动 → 服务器检测到 → 通过 WebSocket 通知浏览器 → 浏览器拉取新代码 → 替换旧模块(不刷新页面)。

Vite HMR 为什么更快:Webpack 要重新编译受影响的模块链(改一个文件,它依赖的模块也要重新打包);Vite 只编译改的那一个文件,不管项目多大,永远 50ms 以内。

⑥ 面试速答(背这些就够)

Vite 为什么比 Webpack 快?(最高频)
三个原因
1. esbuild 预构建:用 Go 写的 esbuild 编译依赖,比 babel 快 10~100 倍
2. Native ESM:开发时不打包,利用浏览器原生 ESM,请求哪个文件才编译哪个
3. 按需编译:只编译当前页面用到的模块,不编译没访问的页面

结果:冷启动 <1s(和项目大小无关),HMR <50ms(恒定)
Webpack 打包流程是什么?
5 步:① 从 entry 入口开始 → ② 顺着 import 递归找所有依赖 → ③ 用 loader 翻译非 JS 文件 → ④ 用 plugin 做额外处理 → ⑤ 输出到 dist 目录。

本质就是"从入口出发,递归收集依赖,用 loader 转换,用 plugin 扩展,最后打包输出"。
loader 和 plugin 的区别?
loader 是"翻译器":处理文件内容,把非 JS 文件(.vue/.scss/.ts)转成 JS。比如 babel-loader 把 ES6 转 ES5。
plugin 是"扩展器":介入整个构建过程,做 loader 做不了的事。比如生成 HTML、压缩代码、抽取 CSS。

一句话:loader 管"怎么翻译文件",plugin 管"还能干什么别的事"。
HMR 热更新原理?Vite 和 Webpack 的 HMR 区别?
HMR 原理:文件改动 → 服务器重新编译 → WebSocket 通知浏览器 → 浏览器拉取新代码 → 替换旧模块(不刷新页面,保留状态)。

区别:Webpack HMR 要重新编译受影响的模块链(慢,随项目增长);Vite HMR 只编译改的那一个文件(快,恒定 50ms)。
Vite 生产构建为什么用 Rollup 不用 esbuild?
esbuild 快但代码分割和 CSS 处理不成熟;Rollup 慢一点但Tree Shaking 更彻底、产物体积更小
开发追求快 → esbuild;生产追求优 → Rollup。各司其职。
什么是 Tree Shaking?
摇树优化:打包时自动删掉没被用到的代码。你 import 了一个库的 4 个函数但只用了 2 个,另外 2 个不会出现在最终产物里。
前提:必须用 ES Module(import/export 是静态的,编译时能确定)。CommonJS(require)是动态的,不能 Tree Shaking。
什么是 Code Splitting?
代码分割:把一个大 bundle 拆成多个小 chunk,按需加载,减小首屏体积。

最常见方式:const Foo = () => import('./Foo.vue'),用到才加载(懒加载路由就是这个原理)。

好处:首屏只加载当前页面代码,其他页面用到才加载,首屏更快。
新项目选 Vite 还是 Webpack?
新项目无脑选 Vite。Vue 3 / React 18 官方脚手架都默认 Vite,开发体验碾压,生态已经够用。

Webpack 仍不可替代的场景:Module Federation(微前端模块联邦)、重度依赖 Webpack 专属插件的老项目。
速记口诀
• Vite 快三宝:esbuild + Native ESM + 按需编译
• Webpack 五步:入口 → 依赖收集 → loader 翻译 → plugin 加工 → 输出
• loader 翻译文件,plugin 扩展功能
• HMR:Webpack 编译模块链(慢),Vite 只编译一个文件(快)
• 开发用 esbuild(快),生产用 Rollup(优)