对于vue2的老项目,我们应该怎么做无痛的优化和升级

背景

最近在工作中,接手了个 vue2 的老项目,面对上百个文件项目,而且有一大部分的一个 vue 文件有上万行代码,甚至有几万行代码,让整个前端团队的人都叫苦连连;于是团队决定对这个项目进行一定的升级;

主要问题

面对一个老项目,我们很难做到一步到位,完全升级,不然很可能会造成一些想象不到的问题,对公司造成不必要的损失,俗话说的好能跑的破车,你最好就不要动它;所以只能一步一步的一点点改造;我们先看看老项目面临的问题,及哪些能马上改的,哪些是先不能动的,只能以后长记计议,以后一点一点改;

面临的问题:

  1. 项目依赖老旧,node还是12的,同样 npm 的包也很老旧;这个问题一来会影响项目性能,二来会导致很多新的包没办法使用,而且其它项目都是node20+,开发的时候每次都要切换 node版本也挺麻烦的
  2. 项目启动慢,修改代码的编译慢,上线打包慢,严重影响开发效率;
  3. 新功能开发麻烦,很多社区上的包只支持 vue3了;
  4. 旧的项目,缺少规划,没有封装通用的组件,工具函数,业务组件;

第一,第二个问题,是可以必须着手解决的,因为也没动到实际的代码,风险也比较低,只要能正常跑起来,一般也不会出现问题;第三点可以让完成新功能在 vue3 中开发,但很多情况可能只是部分新功能,会存在两边要写一样的逻辑的时候,所以要考虑到跟旧项目怎么实现代码复用,不然就徒增开发成本;第四点,可能就只能在业务开发中一点点改进了;

解决方案

下面我将说下我们面对上面问题的解决方案;

升级模块

以我升级的经验来说,升级模块,不能一步到位直接升到 node20,直接升到 20 很大可能性是完全跑不起来,而且报错的模块太多,根本不知从何解决;一面是我升级模块的经验;

第一阶段

node,npm模块小升级

  1. 先删除不必要的模块,像这种远旧项目往往会存在很多没有用到的模块,但还在 package.josn 中写着,需要把这些模块先删了,以减少后面升级的模块,但这也是体力活,需要一个个去排查;
  2. 先升级一个中间版本的 node, 这里可以看下 node 每个版本有大的破不性的升级,我们就先升级到前一个版本,我是先升到 node16, 因为 node17和 18 都有比较大的破性升级;过大的版本升级也可以导致 npm包不兼容。
  3. 对于模块的升级,我们先把所有模块,升到当前大版本的最新版本,比如 1.0.0的升到 1.9.0 而不是升到 2点几,这样可以避免了很多跑不起来的情况;升级完先跑一个,然后再一点一点的解决运行时的报错,这里要感谢AI 的时代,帮我排查了很多问题,在以前可能要查更多的资料和时间去解决;
  4. 到这里应该先上一个版本,先在 dev 环境中跑一段时间,然后再上正式环境,并做好通知,和随时回滚的准备,如果的项目用的流量大,影响也大的话,也可以考虑做一部分的灰度;
第二阶段

npm模块大升级

在项目稳定的跑一段时间后,我们可以进行下一阶段的升级;

  1. 这个时候可以尝对 npm 包的大版本升级了,但不要跳级,就是从 1 升到 2 的版本,但不要直接升到 3,因为对于大部分 npm 包是随着 node 的版本一起升级的,过大的版本跳跃可以 node 不支持,也不利于排查问题;

  2. 对于不再维护的模块升级,在这个大版本升级,可能会面临破坏性升级,或不再维护寻找替代方案,比如我在升级中就面临 node-sass不再维护,要用 dist-sass 替代,这一步也是必须的,因为这里不升,后面 Node也升级不动了;面对这样的升级一定要看下官方的迁移文档,看下注意事项;这里最好的方式还是借助 AI, 把迁移文档喂给 AI让 AI写个脚本修改文件,修改后遇到问题,再把问题喂给 AI 修改脚本,这时还原代码再用脚本修改一次,直至没有问题;

  3. 升级完后,和上面同样的方式,让其在线上跑一段时间,确定其没有问题;

第三阶段

node大升级

这个时候,就可以把 node 升到最新的版本了,一般这一步应该是最顺利的,我基本没有在这一步遇到什么大问题;修改完一些小问题后,就可以上线让其在线上跑一段时间,我们就以着手下一阶段的性能优化了。

提升性能

以上node和模块的升级都是为了,我们做性能优化,及下面一些优化做一些先决准备,其它在上面node 及 sass 的升级已经带来了一点代码编译速度的提升;

其实性能主要包括两部分,一部分是代码编译的性能的提升,一部分是用户体验上的性能提升,对于用户性能的提升,主要包括赖加载, 通过webpack配置优化,减少代码量等等一些手段;这部分大家讲得比较多,我就不展开说了;

但对于老项目来说另一大问题就是编译的性能,像我们的项目,打包要好几分钟,改完代码要编译几至 10 几秒,严重影响开发效率和发布效率,特别是要发 hotfix 的时候,头发都多掉几根;

对于编译的性能的优化,一开始我是尝试对 webpack 的配置优化,如打开多核编译,排除一些文件的编译等等,这些优化虽然起到了一定的作用,但到量变的结果,对于开发体验还是很差;我们最终决定改用别的编译工具试试,选择有 vite,rspack,rsbuid,让我们先比较一下

特性 webpack vite rspack rsbuild
语言 JS JS Rust Rust(基于 rspack)
构建速度 开发快,构建一般
热更新 一般 极快(原生 ESM)
生态 最丰富 丰富 逐步兼容 webpack 依赖 rspack
配置 灵活 简单/灵活 类似 webpack 零配置
适用场景 复杂/大型项目 现代前端/中小型 大型/性能敏感 快速开发
插件系统 成熟 丰富 兼容 webpack 兼容 rspack

从这个表格可以看出,rspack和 rsbuild 是最适合我们的项目升级的,因为他兼容 webpack,速度又快;可以让我们项目改动小,又跑得快;在 rspack 和 rsbuild 尝试后,我们选择了用 rsbuild,一来原先的项目并没有过于复杂的 webpack 配制,rsbuild 可以快速替换,并且rsbuild的@sbuild/plugin-vue2插件,可以直接让 vue2 跑起来,而不用过多的配置调试;

在把 webpack 改为 rsbuild后,项目的打包速度变为了秒级,而修改代码后的编译速度更是毫秒级;完全实现了量变,让 vue2的远古项目,也有点现代项目的感觉了;

用微前端

要想在老项目中,用到新技术的选择最好的方式就是用微前端,可以让完全新的需求写在 vue3上,让旧的项目跑在 vue2上;但对于微前端的选择,我们需要看一是否能满足我们的需求,二是社区活跃度,三是框架的问题多不多,下面我们先来,对比一下各框架的性况

框架/方案 技术栈兼容性 子应用隔离性 路由管理 加载性能 开发体验 社区活跃度 典型场景 代表企业/组织
single-spa React/Vue/Angular等 中(需手动处理) 多团队协作、框架混用 Canopy
qiankun React/Vue/Angular等 强(沙箱机制)
iceStark React/Vue/Angular等 强(沙箱机制) 企业级、阿里系 阿里巴巴
micro-app React/Vue/Angular等 强(沙箱机制) 轻量级、灵活 开源社区

这里我们最终选择了micro-app,对于single-spa,配置过于复杂,而我们的项目也没有这么复杂,对于qiankun 需说用的人最多,但库的版本已经两年没更新了,存在很多问题没有解决,遇到问题提issue也没有解决;所以我们最终选择了micro-app,一是用的人相对较多,版本最近也有在更新;

迁移部分模块

虽说我们一般不会去把老的项目的模块,迁移到 vue3 的;因为往往吃力不讨好,但我还是建议可以把一部分迁移了,如首页和登录,注册页及菜单模块,这样能大大的提性能;因为在接入微前端后,我们就以 vue3 项目作为主应用,只要首页和登录,注册页及菜单模块,迁移后,用户进来只需要加载了主应用几k 的代码,就能看到项目内容了;大大提升了,项目的加载性能,之前的 vue2项目,主 js 都有 4m 代码,打开特别慢;

使用模块联邦

什么是模块联邦

模块联邦(Module Federation)是 Webpack 5 引入的一项革命性功能,允许多个独立构建的应用(通常称为"主应用"和"远程应用")在运行时动态共享和加载彼此的模块。这样可以实现微前端架构、代码共享、团队独立开发和部署等目标。

核心特点:

  • 动态加载远程模块:主应用可以在运行时从远程服务器加载其他应用暴露的模块。
  • 共享依赖:可以配置共享依赖库(如 React、Vue),避免重复加载,减少包体积。

基本原理:

  1. 暴露(Expose) :远程应用通过配置将部分模块暴露出去。
  2. 消费(Consume) :主应用通过配置动态加载远程应用暴露的模块。
  3. 共享(Share) :配置共享依赖,确保依赖只加载一次。
为什么要用模块联邦

最后一步的优化,对于这个项目来说,我们肯定会长期存在 vue2 和 vue3的项目的情况,但很多时候我们又不想一样的业务代码写两遍的情况,通过模块联邦我们可以把业务逻辑写在主应的联邦模块上,然后子应用共享,这样就能实现代码复用;并且还可以配置共享依赖库(如 React、Vue),避免重复加载,减少包体积。这也是为什么一定要先升级旧项目的 node 和 模块的原因;

相关推荐
duanyuehuan23 分钟前
Vue 组件定义方式的区别
前端·javascript·vue.js
veminhe27 分钟前
HTML5简介
前端·html·html5
洪洪呀28 分钟前
css上下滚动文字
前端·css
搏博1 小时前
基于Vue.js的图书管理系统前端界面设计
前端·javascript·vue.js·前端框架·数据可视化
掘金安东尼2 小时前
前端周刊第419期(2025年6月16日–6月22日)
前端·javascript·面试
bemyrunningdog2 小时前
AntDesignPro前后端权限按钮系统实现
前端
重阳微噪2 小时前
Data Config Admin - 优雅的管理配置文件
前端
Hilaku2 小时前
20MB 的字体文件太大了,我们把 Icon Font 压成了 10KB
前端·javascript·css
fs哆哆2 小时前
在VB.net中,文本插入的几个自定义函数
服务器·前端·javascript·html·.net
专注VB编程开发20年2 小时前
C# .NET多线程异步记录日声,队列LOG
java·开发语言·前端·数据库·c#