面试官:说说 Webpack 和 Vite 的区别
按"真实项目里踩过的坑"来回答,分 7 个场景
1. 第一次 npm run dev
-
Webpack
公司老项目(约 4 万行业务代码 + Ant Design Pro):
shell> webpack serve 95% emitting CompressionPlugin
冷启动 38 s,M1 芯片 + SSD。
原因:
- 要解析 2 300 个模块的依赖图;
- ts-loader、babel-loader、eslint-loader 串行排队;
- 每次新增文件,图重新计算。
-
Vite
同一套代码迁移到 Vite:
arduino> vite ready in 823 ms
预构建依赖(esbuild 一次性把
lodash-es
、antd
等打包成 ESM)只要 200 ms,剩下的模块按浏览器请求懒编译。
2. 热更新(HMR)
-
Webpack
修改一个
Button
组件样式:- 触发
less-loader → css-loader → MiniCssExtractPlugin
; - 全量 diff 依赖图,平均 2.8 s 浏览器才刷出来。
如果改的是公共 util,时间飙到 6 s+。
- 触发
-
Vite
只编译改动的那 1 个
.vue
文件,esbuild 把<style>
内联成 ESM,200 ms 内浏览器收到更新。实测:React 项目 300+ 路由页,HMR 稳定在 300 ms 内。
3. 配置地狱
-
Webpack
为了兼容 IE11,我们写了 160 行的
webpack.config.js
:cssmodule.exports = { entry: { main: ['core-js/stable', 'regenerator-runtime/runtime', './src/index.tsx'] }, output: { publicPath: process.env.ASSET_PATH || '/' }, module: { rules: [ { test: /\.tsx?$/, use: ['babel-loader', 'eslint-loader'] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader'] }, { test: /\.(png|jpg|jpeg|gif|svg)$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 8192 } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './public/index.html' }), new CompressionPlugin({ algorithm: 'gzip' }) ], optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', priority: 10 } } } } };
新人 2 天才能跑起来。
-
Vite
phpexport default defineConfig({ plugins: [react()], server: { port: 3000 }, build: { outDir: 'dist' } });
30 秒上手,剩下交给官方插件。
4. 生产构建
-
Webpack
npm run build
跑 3 min 10 s,产物 4.2 MB(gzip 后 1.1 MB)。- 需要手动配
SplitChunksPlugin
、BundleAnalyzerPlugin
做体积优化; - 多入口时要做
runtimeChunk: 'single'
,否则重复 polyfill 爆炸。
- 需要手动配
-
Vite
同一套代码,Rollup 构建 38 s,产物 3.8 MB(gzip 后 0.9 MB)。
- 默认 tree-shaking 更激进,Ant Design 的未使用组件直接消失;
- 动态 import 自动拆包,无需手写魔法注释。
5. 兼容性
-
Webpack
能无痛打到 ES5,IE11 白屏率 < 1%。
代价:polyfill + 降级语法,打包体积 +25%。
-
Vite
开发阶段默认只支持现代浏览器(ES2020+)。
需要 IE11 时:
- 装
@vitejs/plugin-legacy
; - 会自动生成 legacy bundle + polyfill,构建时间 + 40%,但 DX 仍比 Webpack 快。
- 装
6. 微前端/Module Federation
-
Webpack 5
我们主应用用ModuleFederationPlugin
动态加载子应用:cssnew ModuleFederationPlugin({ name: 'host', remotes: { marketing: 'marketing@http://localhost:3001/remoteEntry.js' } })
子应用独立部署,共享 React、antd,节省 300 KB 流量。
Vite 目前社区有vite-plugin-federation
,但功能、稳定性还没对齐 Webpack,复杂场景慎入。
7. 迁移成本
- Webpack → Vite
我们 3 人 2 周把 70% 的子项目迁完:- 把
webpack-dev-server
代理配置抄到vite.config.ts
; - 把
file-loader/url-loader
换成import.meta.glob
; - 遇到 CommonJS 老库(如
moment
)加optimizeDeps.include
强制预构建。
遗留的 30%(Module Federation 子应用、低版本浏览器)继续留在 Webpack。
- 把
一句话总结
- 新项目、小团队、追求开发效率 → 直接上 Vite。
- 要 IE11、Module Federation、超大型 monorepo → 继续 Webpack,或两者并存:主应用 Webpack,子应用 Vite。