Vite 相比 Webpack 快在哪里,又有哪些迁移坑?
Vite 是一个面向现代前端项目的构建工具,开发期基于浏览器原生 ESM 提供按需转换,生产期默认用 Rollup 输出优化后的静态资源。它相比 Webpack 最明显的优势是启动快、HMR 快、默认配置更贴近现代框架。但如果把 Vite 理解成“Webpack 的全面替代品”,迁移时很容易踩坑,因为两者的开发模型、插件生态和打包边界并不完全一样。
Vite 快在哪里
Webpack 开发服务器启动时,通常要从入口开始构建完整依赖图。项目越大,首次启动越慢。Vite 则把源码模块交给浏览器按需请求,开发服务器只在请求到某个文件时转换它。依赖部分由 esbuild 预构建,速度很快,也能把 CommonJS 依赖整理成浏览器更容易消费的 ESM。
HMR 也是同样思路。Webpack 的热更新仍然围绕打包图生成补丁;Vite 只需要定位变化模块,通过 WebSocket 通知浏览器重新 import 对应模块。对于组件很多的大型后台项目,这个差异会非常明显,尤其是只改一个页面组件时。
Vite 不只是快
Vite 的另一个价值是默认配置少。TypeScript、CSS Modules、PostCSS、静态资源导入、环境变量、框架插件等能力开箱就能用。新项目不需要先写一大段 loader 和 plugin 配置,团队成员更容易统一开发方式。
bashnpm create vite@latest my-app -- --template react-ts cd my-app npm install npm run dev
生产构建上,Vite 使用 Rollup,因此 tree-shaking、代码分割、动态导入和库模式都有成熟支持。对常规 SPA、组件库、文档站、管理后台来说,Vite 的默认体验已经够稳。
Webpack 仍然有优势的地方
Webpack 的优势是可塑性和历史生态。大量老项目依赖自定义 loader、复杂 alias、Module Federation、非标准资源处理和企业内部插件,这些不是换个命令就能迁到 Vite。Webpack 对各种“历史包袱”的兼容经验更多,遇到特殊构建链时反而更省心。
所以选择不是简单的“Vite 新,Webpack 旧”。如果是新项目、现代浏览器、React/Vue/Svelte 等主流框架,Vite 通常更合适。如果是多年老项目、强依赖 Webpack 插件、微前端运行时共享复杂,迁移前要先做依赖盘点。
ts// vite.config.ts import { defineConfig } from 'vite' import path from 'node:path' export default defineConfig({ resolve: { alias: { '@': path.resolve(__dirname, 'src') } }, define: { __APP_VERSION__: JSON.stringify(process.env.npm_package_version) } })
迁移时常见坑是把 Webpack 的 process.env.X 直接搬过来。Vite 客户端环境变量默认需要 VITE_ 前缀,通过 import.meta.env 读取;如果硬要兼容旧写法,就需要显式 define。
迁移时要先验证什么
第一看依赖格式,尤其是 CommonJS、动态 require 和只面向 Node 的包。第二看资源导入方式,例如 svg loader、less 全局变量、mdx 或自定义文件类型。第三看构建产物,包括 chunk 大小、路由懒加载是否正常、静态资源路径是否适配 CDN。
Vite 的迁移收益很高,但最好分阶段做。先让 dev server 跑起来,再处理测试、构建、预览和 CI。一次性重写全部构建链,问题会混在一起,很难判断是业务代码、依赖格式还是 Vite 配置导致的。
追问
Vite 一定比 Webpack 快吗?
开发期大多数现代项目会更快,尤其是冷启动和局部 HMR。生产构建不一定总是数量级领先,因为 Vite 默认还是走 Rollup,复杂项目的插件和压缩也会花时间。速度还取决于依赖数量、插件质量和文件系统性能。判断时应该用自己项目的启动、保存更新、build 三组数据,而不是只看 benchmark。
老 Webpack 项目适合直接迁 Vite 吗?
不建议直接大爆炸迁移。老项目通常藏着 loader、全局变量、资源规则和环境变量约定,一次性替换很容易让问题堆在一起。更稳的方式是先做一个最小页面或独立包验证,再逐步迁移入口。取舍点在于:如果构建链已经严重拖慢开发,迁移值得做;如果依赖大量私有插件,维护 Webpack 可能更便宜。
Vite 和 Webpack 的插件能通用吗?
不能直接通用。Vite 插件接口接近 Rollup,并额外提供开发服务器相关钩子;Webpack 插件和 loader 是另一套机制。部分 Rollup 插件能在 Vite 生产构建中使用,但开发期是否可用要看插件有没有处理 ESM 请求模型。迁移时不要只找同名插件,要验证 dev 和 build 两个阶段都正常。
为什么 Vite 生产环境还会打包?
开发环境追求反馈速度,可以让浏览器按需加载很多模块。生产环境要控制请求数、缓存、压缩、兼容性和资源 hash,所以仍然需要打包优化。直接把源码 ESM 发布出去在小 demo 里可行,在真实业务里通常会带来首屏请求过多和缓存不可控。Vite 的取舍是开发期少打包,生产期认真打包。
迁移后线上白屏一般怎么查?
先看构建产物的资源路径,尤其是部署在子路径时 base 是否正确。再看动态导入 chunk 是否 404,很多白屏其实是懒加载文件路径被 CDN 或网关改坏了。然后检查环境变量和浏览器兼容目标,开发环境能跑不代表旧浏览器能执行生产代码。最后用 vite preview 复现构建产物,而不是在 dev server 里反复刷新。