Webpack 如何迁移重构到 Vite

核心差异:

  • 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 项目迁移典型踩坑清单

  1. ❌ require.context 全部替换为 import.meta.glob
  2. ❌ process.env.VUE_APP_* 改为 import.meta.env.VITE_*
  3. ❌ 动态 require 图片文件,改用 new URL(path, import.meta.url).href
  4. ❌ index.html 必须挪到项目根目录,script type="module" 引入入口
  5. ❌ 别名 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 版本。

六、迁移步骤建议(工程化落地)

  1. 新建 vite.config.js,保留原有 webpack 配置不删除,双配置共存。
  2. 修改 package scripts,新增 vite dev/build,不覆盖旧命令,可以回滚。
  3. 修复环境变量:优先全局搜索 process.env。
  4. 修复 require.context、动态 require 批量导入。
  5. 处理别名、proxy 代理,跑通 npm run dev,逐个修复页面报错。
  6. 解决第三方依赖 optimizeDeps 预构建问题。
  7. 执行 vite build,检查产物 dist,对比 webpack 输出资源差异。
  8. vite preview 预览构建产物,做回归测试。
  9. 确认稳定后删除 webpack 相关依赖、webpack.config 文件。

七、大型老项目迁移可选方案

  1. 渐进迁移 :使用 vite-plugin-webpack 不推荐;更好方案:子模块逐步迁移,微前端拆分。
  2. 兼容垫片 :大量老代码不想改:
    • vite-plugin-env-compatible:兼容 process.env
    • vite-plugin-require-context:兼容 require.context,只做过渡,建议最终替换原生 import.meta.glob。

八、迁移对比优势

✅ 开发启动速度巨大提升,不用全量打包;热更新秒级。 ✅ 移除大量 webpack loader/plugin,配置文件大幅精简。 ✅ 生产底层 Rollup,打包产物优化好。 ⚠️ 坑主要来自 CommonJS 老库、webpack 特有语法 require.context/process.env、动态 require。

相关推荐
Csvn8 小时前
WASM
前端
修己xj9 小时前
我用 AI 给自己写了一个 Markdown 编辑器,然后把它开源了
前端
FRing0310 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿10 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
moshuying12 小时前
网购能买Token了!
前端
h_654321012 小时前
echarts实现柱状图加一条横线
前端·echarts
爱聊灵光的维C12 小时前
从看见世界到重构认知:在视觉与硬件的交汇处,寻找我们这代人的北极星
c语言·物联网·计算机视觉·重构·硬件工程·射频工程
风骏时光牛马12 小时前
生成一个后端标题,只需要一个标题,不需要其他的任何文本。
前端
子非鱼@Itfuture12 小时前
关于前后端联调中登录状态/登录信息失效?
java·前端
郭小李12 小时前
openFeign入门
java·开发语言·前端