升级一个老项目的依赖项版本,升级node版本。从我进公司工作开始,几乎每天都在打交道的一个前端工程。

这个前端工程自2020年开始一直在不断的更新迭代,从6w行代码一路发展到记录时(2024年10月)已经有23w行代码的体量,此间我们在2021年1月份迁移代码仓库的过程中,对node版本进行了升级,升级到了node14。
在这之后的近4年时间内,此前端工程的node版本一直维持在node14。现在很多项目在node14环境下是运行不起来的(如vite 4脚手架项目),主流的node版本的底线已经是node16,因此我们决定对前端工程的依赖项版本进行升级,目标是node16可运行。

先描述一下此前端工程在node14, node16环境下的现状:
node14 可安装依赖,可运行项目。
node16 依赖安装失败,可运行项目。
(如果是node14环境安装了依赖,本地升级到node16,可以在node16环境下运行此项目)
所以这个前端工程出现的最大问题是在node16环境无法安装依赖。
无法安装依赖的原因出在package-lock.json文件。(依赖项是在node14环境下逐步添加进前端工程的,package-lock.json就表示了这棵依赖树。现在node16环境下,假如有一个依赖的版本无法安装,就会导致整棵依赖树异常)
升级思路:

  1. 删除package-lock.json文件。
  2. 拆分dependencies 和 devDependencies (在package.json中保留devDependencies, 备份后删除dependencies部分)
  3. 在node 16环境下 npm install,处理devDependencies 中出现的问题,直到全部的依赖项安装完成。
  4. 删除node_modules。 npm install 全量安装验证。
  5. 逐个锁版本安装dependencies中的各个依赖(归类,归类出来一批之后先执行一批。
    这个工作枯燥,重复,不能出错)。直到所有的dependencies都安装完成。
  6. 删除node_modules。 npm install 全量安装验证。

锁版本安装:
对 "vue": "^2.6.11"
npm install vue@2.6.11

对步骤2的详细说明:
首次npm install的时候,大概率有依赖项无法安装(并导致npm install失败),此时将控制台中出现问题的依赖项从devDependencies中删除(并备份)。
再次npm install,如果有依赖项无法安装,继续删除并备份依赖项。
重复上述步骤,直到npm install可以完成安装。
再锁版本逐个安装备份的依赖项。
如果遇到锁版本的情况下无法安装,就要分已经存在的相同依赖项的版本高低情况来处理。
建议首先尝试首位数字相同时的最大兼容版本安装。
如果依然不行,再看控制台的报错。

对步骤3、5的说明:
我们在升级node版本的时候,就是不想使用
--legacy-peer-deps
--force
这种命令来实现兼容性。
因此要保证项目的依赖可以在新版node下不使用兼容性命令全量安装。而验证全量安装的方式就是删除node_modules,使用npm install全量安装。

举一个详细的拆解升级的例子。
image.png

const dependencies = {
"@wangeditor/editor": "^5.1.15",
  "@wangeditor/editor-for-vue": "^1.0.2",
  "@wangeditor/plugin-formula": "^1.0.11",
  "@wangeditor/plugin-mention": "^1.0.0",

  "katex": "^0.16.2",

"vue-katex": "^0.5.0",
}

上面列举的依赖项一共6项,其中与wangeditor相关的有4个,之后是katex, vue-katex。

// 安装指令
npm install @wangeditor/editor@5.1.15 @wangeditor/editor-for-vue@1.0.2 @wangeditor/plugin-formula@1.0.11 @wangeditor/plugin-mention@1.0.0

npm install katex@0.16.2

在node16环境下,如果先安装了 katex@0.16.2,再安装wangeditor的4个依赖,则发现依赖冲突,安装不了。
此时我的做法是卸载katex,先安装wangeditor的4个依赖,安装结果与原有的依赖项无冲突,不进行验证操作。
在上一步的安装执行完成之后,锁版本安装katex,(npm install katex@0.16.2 )安装成功,但是控制台报冲突。
此时需要进行全量安装验证。删除node_modules文件夹,再次npm install,发现无法全量安装,katex@0.16.2这个版本就是会与其他依赖冲突,这个时候就一定要变更katex的版本或依赖了katex的依赖项的版本。

全量安装的时候可以发现(看控制台输出结果),@wangeditor/plugin-formula@1.0.11依赖了katex@0.15.2,而我们安装的katex@0.16.2出现在了根目录,因此产生了冲突。
image.png

这里我的做法是将katex降级到0.15.2。(npm uninstall katex npm i katex@0.15.2)
安装katex@0.15.2之后,发现没有出现新的冲突,保险起见还是需要全量安装验证。
全量安装验证通过,katex与wangeditor之间的冲突解决。

再处理下一个依赖项vue-katex。
npm install vue-katex@0.5.0 发现控制台报错,出现冲突
image.png

vue-katex@0.5.0 依赖了katex @^0.12系列版本,与现有的katex版本冲突,这时候首先想到的是升级vue-katex这个依赖的版本。
npmjs上去查这个依赖(2024年10月),发现vue-katex早已停止更新,0.5.0已经是最新发布版本。
image.png
即无法通过升级直接依赖项(vue-katex)来处理间接依赖(katex)的版本冲突,这个情况就很棘手了。我们需要用最小的代价,去除这个依赖。
去除这个依赖的内容有:

  1. 用其他依赖替代,需修改代码。
  2. 直接使用katex,需修改代码。
  3. ...
    先看看vue-katex这个依赖做了什么,怎么使用。
    image.png
    image.png

发现它有指令(v-directive) 和 模板()两种使用方式。 再在项目里全局搜索 "v-katex" 发现结果为空。 全局搜索"<katex-element" 发现结果为空。 (都没有,妙啊,可以直接删?) 再搜一下"<KatexElement" 发现有一堆使用的地方。好吧,果然没有那么简单。
到这里我们知道了vue-katex只在项目中以vue组件的方式被使用。那么就有了一个新思路,即在前端工程里使用katex@0.15.2这个版本实现一个KatexElement组件,并注册到全局,实现与vue-katex@0.5.0 相同的功能(包括语法和传参),替代项目中现在的使用的vue-katex。(最终的目标是新增公共组件、注册全局,在此之外,不修改各个子模块中的代码)
这个思路在实现后被证明可行,
(有兴趣的话可以看看下面这个提交
有组件实现、注册全局组件的代码
https://github.com/DiracKeeko/vue2-element-js/commit/995c03e8d3b7b55f29eda4b5b418cdc98065d0b0)
按照这个思路逐个拆解,直到把所有的dependencies依赖项全部安装。
最后再执行一次 "删除node_modules。 npm install 全量安装验证" 的操作,确认无误。
运行项目,此时项目(大概率)已经成功启动,到处点点看页面内容有无异常。我的系统升级是无异常的,这是个好事。升级依赖项的工作到此可以算作成功。
升级工作所带来的影响(变更的产物)是package.json和package-lock.json这两个文件,个人建议分批次安装功能的时候,阶段性提交这两个文件,做备份,方便回退。
后记:
在启动项目时,观察到控制台出现了很多行告警
Deprecation Warning: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
这个报错是由于全量升级devDependencies时sass升级到了1.x.x下的最高版本 (sass@1.79.4) 对一个vue2的老项目,它报这个错没啥问题。(实话说也不影响工程运行后的页面状态。)但是启动项目时控制台极多行告警输出,会导致编译变慢,还是降级吧。 我把sass降级到了项目的初始版本sass@1.33.0。 "删除node_modules。 npm install 全量安装验证" 的操作,也验证通过。

阶段性胜利!撒花!

同步更新到自己的语雀
https://www.yuque.com/dirackeeko/blog/te3b7eod5bg88u30


DiracKeeko
125 声望2 粉丝