核心差异:
- Webpack是打包构建,全部编译打包后输出;
- Vite开发阶段基于浏览器原生ES Module,按需加载,生产使用Rollup打包。
迁移分:依赖兼容、配置迁移、代码改造、环境变量、插件替换、调试、生产构建验证。
一、前期准备:
1.安装依赖
卸载webpack相关包
javascript
npm uninstall webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin copy-webpack-plugin
安装 Vite
javascript
// vue2 需要vite-plugin-vue2 vue3直接vite react用@vitejs/plugin-react
npm install vite -D
框架对应插件
- Vue3:@vitejs/plugin-vue
- Vue2:vite-plugin-vue2
- React:@vitejs/plugin-react
注意:babel-loader、css-loader、file-loader 等webpack loader 全部删掉,Vite内置处理css、静态资源、json.
2.新增入口文件
Webpack:一般:src/main.js,html在public/html-webpack-plugin生成
Vite默认入口:index.html在项目根目录,html是项目入口
html
<!-- index.html -->
<DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app"></div>
<!-- 直接引入源码入口,不是打包后的文件 -->
<script type="module" src="/src/main.js"></script>
</body>
<html>
注意:webpack经常把index.html放在public,Vite根目录的index.html才是开发入口;public文件夹功能保留,放不编译的静态资源。
二、 vite.config.js配置迁移
Webpack vs Vite 配置对照
| webpack | vite |
|---|---|
entry |
index.html 中 <script type="module" src="/src/main.js"> |
output.path |
build.outDir 默认 dist |
output.publicPath |
base |
resolve.alias |
resolve.alias 格式略有差异 |
devServer |
server |
plugins |
plugins |
module.rules loader |
vite plugins,内置处理大部分资源 |
基础vite.config.js示例
javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
// 等价 webpack publicPath
base: '/',
plugins: [vue()],
resolve: {
alias: {
// webpack: '@': path.resolve(__dirname, './src')
'@': path.resolve(__dirname, 'src')
}
},
// 开发服务器 对应 webpack devServer
server: {
port: 8080,
open: true,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
},
// 生产构建 build,等价 webpack output
build: {
outDir: 'dist',
assetsDir: 'assets',
// 关闭 sourcemap /开启
sourcemap: false,
rollupOptions: {
// rollup 自定义打包,分包配置
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
}
}
})
package.json script 修改
javascript
{
"scripts": {
// webpack旧:"dev":"webpack serve", "build":"webpack"
"dev": "vite",
"build": "vite build",
"preview": "vite preview" // 本地预览dist产物
}
}
三、代码层面改造
1.环境变量
Webpack:process.env.NODE_ENV,自定义变量process.env.VUE_APP_XXX,由DefinePlugin注入
vite:
- 内置:import.meta.env.MODE、import.meta.env.PROD、import.meta.env.DEV
- 自定义变量必须以VITE开头,.env .env.development .env.production
注意:Vite没有process.env,业务代码不能写process.env.VUE_APP_XX,全部替换成import.meta.env.VITE_XX
.env.devlopment
javascript
VITE_API_URL=http://dev.api.com
业务代码使用
javascript
const apiUrl = import.meta.env.VITE_API_URL
如果老项目大量process.env,可以安装vite-plugin-env-compatible兼容旧写法,临时过渡
2.静态资源导入差异
1.图片、资源
javascript
// webpack
import img from './logo.png'
// vite同样支持,但动态require不支持
// webpack动态require:const img = require(`./${name}.png`)
// vite 不支持require动态导入,替换为import或者new URL
const imgUrl = new URL(`./${name}.png`,import.meta.url).herf
Vite是ES Module,不支持webpack的require.context(批量导入)
require.context替换方案:import.meta.glob
javascript
// webpack require.context批量导入
const modules = require.context('./modules',false,/\.js$/)
// Vite 等价写法
const modules = import.meta.glob('./modules/*.js',{eager:true})
3.CommonJS兼容问题
部分老库是CommonJS,Vite开发模式ESM,部分包会报错
插件:@rollup/plugin-commonjs一般新版vite内置,极少数老库需要配置optimizeDeps预构建
javascript
// vite.config.js
export default defineConfig({
optimizeDeps: {
// 强制预构建commonjs依赖,解决开发时依赖报错
include:['lodash-old','xxx-lib']
}
})
4.CSS相关
- webpack:css-loader style-loader mini-css-extract-plugin
- Vite 内置支持 css、scss、less。
javascript
# 使用scss,不需要loader,只需要安装sass
npm install sass -D
- css module:文件名xxx.module.scss,自动启用css modules
- 全局样式直接import,无需额外配置
5.全局变量迁移
webpack
javascript
new webpack.DefinePlugin({
'BASE_URL': JSON.stringify('/api')
})
Vite
javascript
// vite.config.js
export default defineConfig({
define: {
BASE_URL: JSON.stringify('/api')
}
})
四、常用webpack插件替换对照表
| Webpack 插件 | Vite 替代方案 |
|---|---|
| html‑webpack‑plugin | 根目录 index.html,vite 内置;多页面用 vite-plugin-multi-pages |
| copy‑webpack‑plugin | public目录;复杂拷贝 vite-plugin-static-copy |
| clean‑webpack‑plugin | vite build 默认自动清空 dist |
| webpack‑bundle‑analyzer | rollup-plugin-visualizer |
| compression-webpack-plugin | vite-plugin-compression gzip |
| babel | 框架插件内置,一般不需要 babel-loader |
五、Vue 项目迁移典型踩坑清单
- ❌
require.context全部替换为import.meta.glob - ❌
process.env.VUE_APP_*改为import.meta.env.VITE_* - ❌ 动态 require 图片文件,改用
new URL(path, import.meta.url).href - ❌ index.html 必须挪到项目根目录,script type="module" 引入入口
- ❌ 别名 path 在 windows,注意
__dirname,vite 推荐import { fileURLToPath } from 'url'针对 ESM 配置文件
如果 vite.config.js 后缀改为 .mjs,__dirname 会不存在,用:
javascript
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
6.第三方 UI 库按需引入:部分老 webpack 按需组件,vite 不需要 babel-plugin-import,优先使用库提供 esm 版本。
六、迁移步骤建议(工程化落地)
- 新建 vite.config.js,保留原有 webpack 配置不删除,双配置共存。
- 修改 package scripts,新增 vite dev/build,不覆盖旧命令,可以回滚。
- 修复环境变量:优先全局搜索
process.env。 - 修复 require.context、动态 require 批量导入。
- 处理别名、proxy 代理,跑通
npm run dev,逐个修复页面报错。 - 解决第三方依赖 optimizeDeps 预构建问题。
- 执行 vite build,检查产物 dist,对比 webpack 输出资源差异。
- vite preview 预览构建产物,做回归测试。
- 确认稳定后删除 webpack 相关依赖、webpack.config 文件。
七、大型老项目迁移可选方案
- 渐进迁移 :使用
vite-plugin-webpack不推荐;更好方案:子模块逐步迁移,微前端拆分。 - 兼容垫片 :大量老代码不想改:
vite-plugin-env-compatible:兼容 process.envvite-plugin-require-context:兼容 require.context,只做过渡,建议最终替换原生 import.meta.glob。
八、迁移对比优势
✅ 开发启动速度巨大提升,不用全量打包;热更新秒级。 ✅ 移除大量 webpack loader/plugin,配置文件大幅精简。 ✅ 生产底层 Rollup,打包产物优化好。 ⚠️ 坑主要来自 CommonJS 老库、webpack 特有语法 require.context/process.env、动态 require。