用阿里百炼批量重构 Vue2 到 Vue3(下):选项式路线与现实收尾

这篇是 Vue2→Vue3 迁移系列的实操篇(下),聚焦选项式路线和收尾工作。 上篇讲了 组合式路线的完整流程,这篇则是"能不能用更低成本跑通"的尝试。

组合式路线走完一遍之后,我开始想一个问题:如果只是"先让 Vue3 跑起来",能不能更快?

选项式路线的核心思路是——用 AST 工具做 80% 的规则转换,只让 AI 处理剩下那些工具搞不定的边界场景。

选项式路线的工具链

gogocode:基于 AST 的转换

gogocode 是阿里出的一个基于 AST 的代码转换工具,自带 Vue2→Vue3 和 element-ui→element-plus 的转换插件。

# 安装
npm install gogocode-cli -g
 
# 第一步:Vue2 → Vue3 基本语法转换
gogocode -s ./src -t gogocode-plugin-vue -o ./src-out
 
# 第二步:element-ui → element-plus 转换
gogocode -s ./src-out -t gogocode-plugin-element -o ./src-out-element
 
# 用转换结果覆盖 src
cp -r ./src-out-element/* ./src/

这两步能覆盖大部分机械性转换:this.$emitcontext.emitvalue/input 事件改名、Vue.filter 废弃提示等。

gogocode 搞不定的

用了之后发现,gogocode 的问题清单比预期长:

问题影响范围能否修复
return (<></>) JSX 语法不转换render 函数需要 AI
element-plus 的样式和国际化路径不修正全局样式引用可手动批量
icon 转换时属性会被吞掉使用 icon 的组件需要人工
v-model 转换不完整部分双向绑定需要人工
el-drawer:visible 未转为 :model-value对话框类组件可手动批量
filters 转换不完整(换行导致规则未命中)模板中的过滤器需要 AI
mapState 引入偶尔遗漏vuex 相关文件需要人工
`NumberString` 类型声明变非法props 定义

总结:gogocode 大约能处理 60-70% 的转换,剩下的就是 AI 和人工的战场。

选项式的 Prompt:比组合式简单很多

因为 gogocode 已经处理了大部分语法转换,留给 AI 的 Prompt 可以精简很多:

# 任务
对上面的代码进行如下处理

## vue 版本重构
- 重构为非 TypeScript 的 Vue3 代码
- 必须使用 Vue3 的选项式风格,不允许使用组合式

### render → template
- 如果代码在选项中使用了 render 方式渲染,改为 template 风格
- 如果遇到类似 JSX 的 return (<></>) 语法,改为 h 函数渲染

### message 组件
- element-plus 中 message 改为 import { ElMessage } from 'element-plus'

## 约束
- 多级引用使用 ?. 可选链
- 即使不需要修改也返回原代码
- 只返回代码文本,不返回 markdown 格式

对比一下:

维度组合式 Prompt选项式 Prompt
长度~50 行~20 行
涉及的技能数8 个3 个
需要知识库是(hooks 代码)
处理 this全面重写不用管
处理 mixin先转再喂不用管

选项式路线的 Prompt 几乎不需要处理 this,因为选项式 API 里 this 仍然是有效的上下文引用。也不需要先转 mixin 再当知识库——mixin 在选项式里照常工作。

执行流程对比

选项式路线步骤更少、Prompt 更简单、不需要 mixin 预处理这个前置环节。代价是你得接受代码最终是选项式风格——如果团队已经决定全面拥抱组合式,那这条路就不适合。

通过特征识别需要 AI 处理的文件

gogocode 跑完之后,不是所有文件都需要 AI 再过一遍。理想情况下,应该能通过文件特征自动识别"哪些文件还需要 AI 处理"。

目前能识别的特征:

  • 包含 return (<></>) 的 render 函数
  • 包含 filters 转换不完整的场景
  • 包含 Vue.use 的非入口文件

但说实话,这个特征库还不够完善。实际操作中,更多是在调试过程中发现问题,记录文件路径,再批量交给 AI

收尾:无论哪条路线都要做的事

构建系统改造

无论选哪条路线,你最终都需要有人把项目的构建流程跑通。从 webpack 切到 vite、调整入口文件、配置代理、处理环境变量——这些 AI 帮不了太多,需要对项目构建有理解的人来处理。

Mock 和接口代理

不要期望转完就能跑。准备好 Mock 文件或者配置接口代理,缩小调试范围:

  1. 缩减 router,只保留你要调试的页面
  2. 移除不相关的第三方 SDK 调用
  3. 用代理工具把接口请求转发到可用的环境

样式问题

无论组合式还是选项式,这两条路线都不处理样式

理论上可以让 AI 基于社区信息做兼容,但实际操作中,样式问题的范围太大、项目间差异太大,AI 容易改出新问题。建议从组件库的更新日志入手,定点修复。

两条路线的实际感受

组合式路线选项式路线
AI 参与深度深,全流程依赖浅,只处理边界
Prompt 工程量大,3 套 prompt + 知识库小,1 套简单 prompt
转换质量质量波动大,需要大量 review基础部分稳定,边界需 review
人工调试时间长,到处都可能出意外短,问题集中在特定模式
最终代码风格统一组合式保持选项式
适合场景团队决定统一组合式先跑起来,后续再优化

如果让我重新来一次,我会建议:先用选项式路线跑通,再在后续迭代中逐步把高频模块改成组合式。原因很简单——先跑起来比一步到位更务实。

还没解决的问题

写到最后,诚实地列一下目前还悬着的:

  1. 大文件截断——输出 token 上限导致超长文件转换不完整,目前只能手动拆
  2. 变量名冲突——组合式路线中 ref 解构后的同名变量,AI 偶尔会生成有歧义的代码
  3. 装饰器——没有处理,如果项目用了 TypeScript 装饰器,这是个坑
  4. 端到端验证——目前还没有自动化的验证手段,只能人工对比页面效果
  5. 样式一致性——如上所述,没有好方案

这些问题都不是不可解,只是在当前阶段没有足够的时间去填。如果你的项目遇到了类似的困境,希望这份笔记能帮你少走一些弯路。


系列导航:

  1. 方案推演:Vue2→Vue3 路线选择 — 要不要迁?选哪条路?
  2. 实操(上):组合式路线 — Prompt 工程与完整流程
  3. 实操(下):选项式路线与现实收尾 — 你正在读的这篇

Comments