vite开发阶段不打包,依赖浏览器原生esm实现按需编译;webpack必须全量打包后启动。vite预构建第三方库、零编译启动src代码,hmr精准到单模块,其开发服务器是智能代理而非打包器。

核心就一点:Vite在开发阶段根本不打包,而Webpack必须先打包完才能启动——这不是优化,是范式切换。
浏览器原生ES模块(ESM)是底层支点
现代浏览器(Chrome 61+、Firefox 60+、Safari 11.1+)已原生支持 <script type="module"></script>。这意味着浏览器能直接解析 import 语句,按需发起 HTTP 请求获取单个模块文件,无需提前合并成 bundle。
- Vite 利用这点,把每个
.vue、.ts、.jsx文件都当作独立 ESM 模块暴露给浏览器 - 浏览器请求
/src/App.vue→ Vite 实时编译为 JS 模块并返回,全程无打包环节 - Webpack 却必须先扫描全部依赖、构建完整依赖图、生成 bundle 后才响应首个请求
预构建只处理第三方依赖,且用 esbuild 加速
第三方库(如 vue、lodash、axios)通常含大量内部文件和 CommonJS 导出,直接让浏览器一个个请求会引发海量 HTTP 请求,拖慢首屏。
- Vite 启动时仅对
node_modules中的依赖做一次预构建,用 Go 写的 esbuild(比 JS 工具快 10–100 倍)转成标准化 ESM 格式,缓存到node_modules/.vite/deps/ - 业务代码(
src/下)完全跳过预构建,真正“零编译启动” - Webpack 则需把所有源码 + 第三方库统一纳入依赖分析和打包流程,复杂度随项目规模指数增长
热更新(HMR)精准到模块粒度,无需重跑依赖链
改一个 Button.vue,Vite 只重新编译它自己,并通知浏览器替换该模块;Webpack 往往要重建受影响的 chunk 及其整个子图。
- Vite 的 HMR 基于 ESM 的静态 import 关系,能精确追踪谁引用了谁
- 浏览器收到更新通知后,直接 fetch 新的
/src/components/Button.vue模块,旧模块被卸载,新模块注入执行 - Webpack 的模块系统基于自定义 runtime,每次变更需重新计算 chunk 分割、重写模块 ID、注入 hot API,开销大得多
开发服务器本质是智能代理,不是打包器
Vite dev server 更像一个带编译能力的静态资源网关:接收请求 → 解析路径 → 按需转换(TS/JSX/Vue/Sass)→ 返回模块 → 缓存结果。
- 没有入口概念,没有 bundle 配置,没有 loader/plugin 链式调用
- 首次请求耗时 = 单文件编译时间(毫秒级),后续请求走内存缓存
- Webpack dev server 是打包器的延伸,启动即触发全量构建,哪怕你只改一行,也要等整个流程跑完











