Skip to content

Webpack 工作流与 Vite 对比:开发期打包哲学的分裂 ​

回到总览:构建与发布工程相关模块:iOS 构建与依赖 · CI/CD 流水线

一句话定义 ​

Webpack 以「依赖图 + loader/plugin」在开发期就全量打包;Vite 在开发期直接走浏览器原生 ESM 免打包(仅用 esbuild 预构建依赖),生产期再用 Rollup 打包。两者核心差异在开发服务器冷启动与 HMR 的实现路径。

代码索引 ​

对应 Lab:当前仓库尚未补齐 webpack-vite-compare 实验;本页保留构建链对照与命令说明,待后续在 Node host 中补可运行样板。

为什么需要 ​

  • Webpack 和 Vite 的核心差异是什么?
    • 一句话答:开发期打包方式不同——Webpack 启动即全量打包依赖图,Vite 改走原生 ESM 按需编译,这决定冷启动与 HMR 速度(详见 §底层机制.1/.2)。
  • 为什么 Vite 生产期又用 Rollup 而不是 esbuild?
    • 一句话答:Rollup 的 tree-shaking 与产物优化更成熟、产物质量优先;esbuild 快但产物优化弱,故生产期不用它打包应用。
  • 为什么 Webpack 配置越来越复杂?
    • 一句话答:「一切皆 loader/plugin」,灵活但样板多;Vite 把常用预设(TS、CSS、HMR)内置,开箱即可用。

底层机制 ​

1. Webpack:依赖图 + loader + plugin ​

  • 概念:从 entry 出发递归解析 import 构建依赖图;loader 负责单文件转译,plugin 在生命周期钩子上做优化(如 SplitChunksPlugin)。

2. Vite:开发期原生 ESM + 依赖预构建 ​

  • 概念:开发期 Vite 不做打包,浏览器直接请求源码模块,Vite 实时转译返回;对 node_modules 用 esbuild 预构建成 ESM 以解决 CommonJS/海量小文件问题。HMR 基于原生 ESM + WebSocket 精准替换模块。

3. 启动与构建命令对照 ​

bash
# Webpack:开发服务器(先全量打包再服务)
npx webpack serve --mode development

# Vite:开发服务器(免打包,按需编译)
npx vite

# 两者生产构建(Vite 走 Rollup)
npx vite build
npx webpack --mode production
  • 可能输出(Vite 启动)
    VITE v5.x  ready in 312 ms
    ➜  Local:   http://localhost:5173/
  • 可能输出(Webpack 启动)
    asset main.js 1.2 MiB [emitted]
    webpack 5.x compiled successfully in 4200 ms
  • 预期现象:Vite 启动时几乎只做依赖预构建,毫秒级就绪;Webpack 需先构建完整依赖图才服务,项目越大冷启动越慢。
  • 观察重点:大型项目里 Vite 的冷启动优势明显;但首屏「按需编译」会在浏览器首次请求时产生少量延迟,可用依赖预构建缓解。

Android / Flutter / Web / Backend 对照 ​

维度Web (Webpack)Web (Vite/Rollup)Android (R8/AGP)Flutter (AOT)
产物优化Terser 压缩Rollup tree-shakingR8 缩减/混淆树摇 + 混淆
开发体验全量打包后 HMR原生 ESM HMR热重载热重载(JIT)
增量单位module/chunkmoduletask文件
类比类似提前全量编译类似按需 JIT类似 AOTAOT

常见场景 ​

  • SPA / MPA:Webpack 的 html-webpack-plugin 与 Vite 的 index.html 入口都能驱动多页。
  • 微前端:Webpack Module Federation 原生支持运行时共享模块;Vite 需插件补足。
  • 库打包:Rollup(Vite 同内核)是库打包首选,tree-shaking 干净。

常见误配、事故后果与排障 ​

1. 误配:Webpack 循环依赖导致 chunk 拆分异常 ​

  • 后果:打包体积失控或运行时初始化顺序错乱。
  • 排障与修法:用 webpack-bundle-analyzer 看依赖图,打破循环、显式 SplitChunks。

2. 事故:Vite 依赖预构建失效,浏览器请求裸模块 404 ​

  • 误配原因:新增依赖后 optimizeDeps 缓存未刷新,或依赖含非 ESM 格式。
  • 后果:开发服务器报 Failed to resolve import。
  • 排障与修法:删 .vite 缓存重启;在 optimizeDeps.include 显式声明;对 CJS 依赖确认 esbuild 可转。

3. 误配:路径别名 @ 在 Webpack/Vite 配置不一致 ​

  • 后果:本地能跑、构建或他人环境报模块找不到。
  • 排障与修法:alias 配置统一,并在 tsconfig paths 同步。

相近概念对比 ​

  • Webpack vs Rollup:Webpack 主打应用打包、HMR、代码分割;Rollup 主打库打包、tree-shaking 干净。Vite 生产期借 Rollup 之长。
  • esbuild vs Rollup:esbuild 极快但优化弱;Rollup 慢些但产物优。Vite 开发用 esbuild、生产用 Rollup,各取所长。
  • HMR vs 热重载:HMR 替换单个模块保留状态;热重载整体刷新(Flutter 热重载更接近前者)。
  • bundle vs chunk:bundle 是最终文件,chunk 是拆分出的中间块。

对应实验 ​

实验说明关键源码
暂无独立 Lab当前仓库尚未补齐 webpack-vite-compare;本页先保留命令级对照与产物判断(与文首说明一致)文档内联命令

复习检查题 ​

  1. 为什么 Vite 开发期快,但生产期仍用 Rollup 而不是 esbuild 打包应用? 答:开发期快靠的是免打包(原生 ESM + 依赖预构建),不是 esbuild 打包应用;生产期要的是产物质量(tree-shaking、拆包优化),Rollup 比 esbuild 更成熟,所以 Vite 生产构建交给 Rollup。

  2. Webpack 与 Vite 的 HMR 实现路径有何本质不同? 答:Webpack HMR 建立在对依赖图全量打包后的模块运行时热替换系统;Vite 基于浏览器原生 ESM,配合 WebSocket 精准替换被编辑的单个模块,无需整体打包。

  3. 什么场景 Webpack 仍优于 Vite? 答:需要 Module Federation 微前端、复杂自定义 loader/plugin 链、或老项目生态绑死 Webpack 时,Webpack 更稳妥。

速记 ​

  • 哲学差:Webpack 开发即打包;Vite 开发即 ESM 免打包。
  • 三层工具:esbuild(快·开发预构建)/ Rollup(优·生产)/ Webpack(全·应用)。
  • 看体积:webpack-bundle-analyzer;看依赖:打破循环依赖。
  • 别名统一:Webpack/Vite/tsconfig 三处 alias 必须一致。

站点构建时间:2026/8/24 23:43:17