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。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学2 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端