Vue 2 老项目从 webpack 4 迁移到 Vite 4 的实战记录

举报
yd_236978410 发表于 2026/11/03 08:05:31 2026/11/03
【摘要】 背景上周帮一个朋友的 Vue 2 老项目升级构建工具链,原先是 webpack 4,构建一次要三分多钟,改一行代码热更新也要十几秒。趁着周末把整套构建迁到 Vite,顺手记录了完整的迁移过程和踩到的坑,给有同样需求的同学一个可以照着做的路线。 为什么是 ViteVue 2 默认的脚手架绑死了 webpack 4,node 17 以上还会报 ERR_OSSL_EVP_UNSUPPORTED ...

背景

上周帮一个朋友的 Vue 2 老项目升级构建工具链,原先是 webpack 4,构建一次要三分多钟,改一行代码热更新也要十几秒。趁着周末把整套构建迁到 Vite,顺手记录了完整的迁移过程和踩到的坑,给有同样需求的同学一个可以照着做的路线。

为什么是 Vite

Vue 2 默认的脚手架绑死了 webpack 4,node 17 以上还会报 ERR_OSSL_EVP_UNSUPPORTED 的错,因为新版 OpenSSL 不再支持 webpack 4 用的哈希算法。与其打补丁,不如直接换 Vite。Vite 用 esbuild 做依赖预构建,开发模式按需编译,冷启动基本是秒开。

需要说明的是,Vue 2 用 Vite 要靠 vite-plugin-vue2 这个社区插件,官方的 @vitejs/plugin-vue 只支持 Vue 3。虽然是非官方方案,但生产环境跑了大半年没有出过问题。

迁移步骤

第一步:装依赖

npm i -D vite@4 vite-plugin-vue2
npm i -D @vitejs/plugin-legacy

装 legacy 插件是因为项目还要兼容 Chrome 60 之类的老浏览器,esbuild 默认只输出 ES2015+ 的产物。

第二步:新建 vite.config.js

import { defineConfig } from 'vite'
import vue from 'vite-plugin-vue2'
import legacy from '@vitejs/plugin-legacy'

export default defineConfig({
  plugins: [
    vue(),
    legacy({ targets: ['Chrome >= 58', 'IE >= 11'] })
  ],
  resolve: {
    alias: { '@': '/src' }
  },
  server: {
    port: 8080,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  }
})

alias 里的 @ 原来是 webpack 的 resolve.alias 配的,Vite 用 resolve.alias 承接,注意路径前要不要加 / 取决于你原项目怎么引用的。

第三步:处理入口

index.html 要从 public/ 挪到项目根目录,并把引用入口的 script 改成 module:

<script type="module" src="/src/main.js"></script>

原来 webpack 通过 HTMLWebpackPlugin 注入的 <%= %> 模板语法全部删掉。

第四步:环境变量改名

webpack 的 process.env.VUE_APP_xxx 要改成 import.meta.env.VITE_xxx,全局搜索替换即可,.env.production 里的前缀也从 VUE_APP_ 改成 VITE_。

踩到的四个坑

第一,require 语法。 老代码里有不少 require('./assets/logo.png'),esbuild 不认。图片引用统一改成 import logo from '@/assets/logo.png';JSON 文件同理,require('./a.json') 改成 import a from './a.json'。

第二,CommonJS 依赖。 有一个只提供 CJS 的老依赖,开发模式会报 default is not exported。在 optimizeDeps.include 里把它加进去让 esbuild 预构建一次就正常了。

第三,全局挂载的库。 项目里 echarts 是在 main.js 里 Vue.prototype.$echarts = echarts 挂的,迁移时漏了 import echarts from 'echarts',因为原来写在 webpack 的 ProvidePlugin 里。这类隐式注入要挨个排查。

第四,动态路由的懒加载。 () => import(/* webpackChunkName */ '@/views/' + name + '.vue') 这种拼路径的动态导入,Vite 的 glob 导入写法是:

const modules = import.meta.glob('@/views/**/*.vue')
const comp = modules['/src/views/' + name + '.vue']

变量拼路径 Vite 是支持静态分析的,但混合了 webpack 注释就要重写。

迁移结果

指标 webpack 4 Vite 4
冷启动 约 45s 约 1.2s
热更新 10~15s 300ms 内
生产构建 3min20s 52s
产物体积 4.1MB 3.7MB

产物变小的原因主要是 legacy 插件把 polyfill 拆成了按浏览器加载的两份,现代浏览器只下载轻的那份。

小结

整个迁移花了一个下午加一个晚上,其中一大半时间耗在排查 require 和动态导入上。如果项目本身就是 Vue 3 + 新脚手架,迁移成本会低很多。建议先在新分支上做,用 Vite 的 dev server 和原 webpack 的 dev server 并行跑几天,逐页对比再切流量。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。