基于前不久的项目框架升级和重构,记录一些踩坑和问题;
💡 一句话摘要: 这次升级围绕发布速度、依赖治理、格式化规范化等关键节点展开,从提速到风险控制,都踩过坑也找到了解法。
🧱 背景
- 🚦 项目发布流程缓慢且不稳定,对实际的测试发布效率影响较大
- 📝 格式化没有强制执行,在 codeReview 中会出现大量格式化 diff,review 困难
- 🧟 有大量的幽灵依赖,导致项目体积变大且不易排查问题
- 🧗 升级困难,开发无法享受新技术带来的便利
🎯 目标
- ⚡ 提升项目发布流程的稳定性和效率
- 🧹 强制执行代码格式化,减少 codeReview 中的格式化 diff
- 🧺 清理幽灵依赖,减小项目体积,提升问题排查效率
- 🚀 降低升级成本,让开发者更快享受新技术带来的便利
- 🛡️ 最小化对现有代码的侵入,确保升级过程平滑
⚡️ 优化速度
项目现有的构建工具是vite
, 纯打包时间的话大概是 2m30s左右,这个时间我认为是在能接受的范围内的。但是在实际的发布流程中,整个流程最终可能拉长到最多 10分钟,所以我们对流程分析:
⛽ 环节一:依赖拉取
排查发现,其中有一个依赖 pinyin
内部会有一个 optional
的依赖 node-gyp
(好像是吧,忘了…),这个依赖会在安装时编译一些二进制文件,导致安装时间变长,且不稳定,最长可能达到 5分钟 。
幸运的是,该依赖属于历史依赖,在迭代的过程中可以被移除,所以我们直接移除了该依赖。为了将速度提升到一个更理想的状态,可以顺带将以下优化点一并做了:
- 包管理器: 使用
pnpm
替代npm
作为包管理工具,pnpm
通过硬链接和缓存机制,大幅提升依赖安装速度(虽然我认为在流水线中,pnpm的缓存机制作用有限,因为会在每次install
时删除store) - 依赖镜像切换: 下载源切换为
taobao
镜像,提升下载速度 - node升级: 准备一个
node22
的容器,对新兴前端的工具链支持更好,对后续构建工具的升级也是必要的
在做完这些优化后,幽灵依赖的问题也顺便解决了(之前会有很多依赖通过jest
引入,但实际上并没有安装)。
✅ 结果复盘: 依赖拉取速度由 2 - 5 分钟 提升至 20 秒以内。
🏗️ 环节二:构建速度
当前用的是 vite3
,恰巧的是 vite
最近可以使用 rolldown
引擎的 beta 版本,我尝试了一下,速度提升惊人:从 2m30s 降低到 17s 左右,几乎提升了 7 倍,这是质的提升!。
🚀 叠加依赖和构建的优化,整体流水线时间从 5 - 10 分钟 压缩到 30 秒以内,发布效率瞬间起飞。
✍️ 格式化
项目中使用 prettier
作为代码格式化工具,但是并没有强制执行,导致在 codeReview 中会出现大量的格式化 diff,影响 review 效率。
所以之前都是直接把格式化禁用了,为了不产生大量的diff;但这显然十分影响开发的幸福度,以及代码可读性。
那既然做优化,就彻底一点:
- 强制执行格式化: 在
pre-commit
钩子中添加lint-staged
,对提交的代码进行格式化,确保所有提交的代码都符合规范 - 全量格式化: 对现有代码进行全量格式化,消除历史遗留的格式化问题,避免以后再出现大量的格式化 diff
📦 依赖更新
将整个项目的核心依赖做了同步的更新,比如 vue
系列工具库;一些工具类库,更新最新版本或者使用平替: 移除冗余依赖
vite
→rolldown
🔄js-md5@latest
→esm
更好的代码实现 🔑vue@latest
🆙element-plus@latest
🆙vue draggable
(不再维护&不推荐使用) →vue-draggable-plus
🔃lodash
→es-toolkit
,支持 tree-shaking,性能更好 🌲
⚠️ 风险和踩坑
🧩 UI 框架升级
其实在升级的过程中,很多依赖是被迫升级的,比如 初衷只是提高构建速度,但是构建工具的更新,意味着 node
版本的提升,node
版本的提升,意味着一些依赖也需要同步更新适配。
个人觉得风险最大的应该是 UI
框架的升级,element-plus
的升级,意味着很多组件的 API 可能会有变动,导致现有代码无法正常工作。
UI框架的升级也确实成为了问题集中点,最致命的是,现有客户习惯了以前版本的某种组件操作习惯,但是新版本已经完全不支持了,比如:el-select
组件现在禁用状态下,不能 ctrl+a
复制选择框内的全部内容了,这点在我们的业务中似乎是致命的。
完全回退版本又会和现有构建工具冲突等问题;幸好,在查阅源码知道组件的重构时间后,在 github
上扒拉扒拉版本,找到了一个非常合适的中间版本解决了问题。
现实中也确实会被投诉,有点压力的。。。
✍️ 格式化的风险
私以为格式化的风险应该是最小的,毕竟只是代码风格的问题,但是在实际操作中,还是出现了一些问题:
vue
的props
和attrs
对模版的拼写风格敏感: 像props
其实是没有问题,因为vue
会做归一化处理,无论是kebab-case
还是camelCase
,行为都是一致的;但是attrs
就不行了,attrs
是直接映射到 DOM 属性上的,所以如果格式化工具把kebab-case
转成了camelCase
,那么就会导致属性无法生效的问题。对正则的格式化影响: 我们业务中有大量的正则,有些正则是非常复杂的,格式化工具在格式化时,也许会有问题;之前遇到一个生产 bug 也是因为我格式化了一批正则,最后依赖于后端刷数据解决
✅ 总结
整体升级下来,个人觉得其实算是比较成功的,虽然也出了一些问题,单其实意料之外的可能只有上述风险提到的两个问题,其他问题基本上都是预料之中的(样式、格式化等);总体上问题也不多。
总结一下比较需要注意的点就是:
- ⚠️ UI 框架和格式化风险
- 💭 意料之内的风险和压力~