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。

相关推荐
catastrophe_zy1 小时前
如何用 WebCodecs 在浏览器里实现高清录屏 —— 无插件、无水印、直接导出 MP4
前端·javascript·录屏
芳心粽伙饭1 小时前
HTML第七章 表格标签
前端·html
我就是DaLing呀!1 小时前
vue3 + 独立的数据管理 Store实现视频剪辑功能
前端·typescript·vue3·canvas·store
吃杠碰小鸡1 小时前
Wps常用功能介绍
前端·wps
恋猫de小郭1 小时前
聊个比较有意思的 Flutter Web 问题
android·前端·flutter
IT_陈寒1 小时前
Redis持久化配置漏了这一步,线上数据丢了5小时
前端·人工智能·后端
梦曦i1 小时前
create-uni-app v1.2.0:交互体验优化
前端·uni-app
Moment1 小时前
太好了!NestJS 12 大版本转向 ESM,新项目默认构建换 Rspack
前端·javascript·后端
Csvn2 小时前
泛型与条件类型:TypeScript 类型体操的核心
前端