Shopify 正在把旗下移动应用从 React Native 迁移回 Swift 和 Kotlin。首个完成迁移的 Shop App 借助 AI,在 12 周内从概念验证推进到发布;更复杂的旗舰 Shopify App 也已进入迁移阶段。后者包含 300 多个屏幕,以及主屏幕和锁屏小组件、Apple Watch、Siri 捷径等平台能力,计划在年内发布。
这不是简单的“跨平台失败、原生胜出”。更值得关注的是:当 AI 显著降低代码重写成本后,企业重新评估技术栈时,长期维护成本、平台能力和工程反馈速度可能比代码复用率更重要。
迁移的关键变量不再只是代码复用率
React Native 的核心吸引力是共享业务逻辑和界面代码。但在大型应用里,真正需要计算的并不是“共享了多少行代码”,而是完整交付成本:
- 新版 iOS 或 Android API 出现后,团队多久能够使用?
- 小组件、手表、系统快捷方式等能力需要多少原生桥接代码?
- 跨平台框架、第三方模块和操作系统升级之间会产生多少兼容工作?
- 性能问题发生时,团队需要跨越多少层抽象才能定位?
- 两个平台是否已经形成不同的交互需求,却仍被迫共享组件结构?
Shopify 旗舰应用所覆盖的小组件、Apple Watch 和 Siri 捷径,正好体现了这种压力。这些功能天然依赖 Apple 平台 API。即使主界面可以共享,外围能力仍可能形成大量 Swift、Objective-C、Kotlin 或 Java 代码,最终让团队同时维护跨平台层与原生层。
因此,迁移决策应比较总成本,而不是只统计共享代码比例。可以使用一个简单模型做内部评估:
跨平台总成本 = 共享功能开发 + 原生桥接 + 框架升级 + 兼容性排查 + 平台特性等待
原生总成本 = iOS 实现 + Android 实现 - 可复用规范 - AI 生成收益 - 独立发布收益
这里的“AI 生成收益”不能直接按生成代码行数计算。只有被编译、测试、审查并进入生产的代码,才真正缩短了交付时间。
12 周重写的前提:把迁移拆成可验证的工作单元
从概念验证到发布只用 12 周,说明 AI 可以把已有产品转换成另一种实现形式。但这类速度通常依赖一个重要条件:旧应用本身就是一份可执行规格。
团队已经知道屏幕长什么样、接口返回什么、用户流程如何运转,也拥有线上行为、测试用例和故障记录。AI 不需要从空白处发明产品,只需要在明确约束下完成翻译、补全和修复。
可以把迁移拆成四层:
- 契约层:接口模型、鉴权、分页、错误码和埋点名称保持稳定。
- 领域层:订单、商品、支付等状态转换先用平台无关测试描述。
- 界面层:按完整用户流程迁移,而不是机械地逐文件翻译。
- 平台层:小组件、通知、深链、手表和系统快捷方式单独验收。
AI 适合生成数据模型、基础页面、测试骨架和重复适配代码;架构边界、线程模型、生命周期、无障碍体验以及支付和鉴权逻辑仍需要工程师负责。
可以这样实践:先建立迁移清单和双端契约
在让 AI 批量生成 Swift 或 Kotlin 之前,先盘点当前仓库中的 React Native、桥接层和原生代码。下面的脚本可在 macOS 或 Linux 的 Bash 中运行。将脚本放在项目根目录执行,它会生成按文件类型统计的 mobile-inventory.csv:
#!/usr/bin/env bash
set -euo pipefail
printf 'extension,files,lines\n' > mobile-inventory.csv
for ext in ts tsx js jsx swift m mm kt java; do
files=$(find . -type f -name "*.${ext}" \
-not -path './node_modules/*' \
-not -path './Pods/*' \
-not -path './build/*' | wc -l | tr -d ' ')
lines=$(find . -type f -name "*.${ext}" \
-not -path './node_modules/*' \
-not -path './Pods/*' \
-not -path './build/*' -print0 \
| xargs -0 cat 2>/dev/null \
| wc -l | tr -d ' ')
printf '%s,%s,%s\n' "$ext" "$files" "$lines" >> mobile-inventory.csv
done
cat mobile-inventory.csv
行数不能直接代表迁移难度,但它能帮助团队发现两个问题:原生代码是否早已大量存在,以及所谓共享应用是否已经拥有庞大的平台适配层。
接下来,为每个用户流程建立机器可读的迁移清单:
# migration/shop-home.yaml
flow: shop-home
owner: mobile-commerce
source: react-native
status: validating
contracts:
api_fixture: fixtures/shop-home.json
analytics:
- shop_home_viewed
- product_opened
acceptance:
ios:
implementation: SwiftUI
minimum_version: "17.0"
tests:
- ShopHomeViewModelTests
- ShopHomeSnapshotTests
android:
implementation: Compose
minimum_sdk: 26
tests:
- ShopHomeViewModelTest
- ShopHomeScreenshotTest
platform_checks:
- deep_link
- accessibility
- offline_state
- cold_start
这份文件可以作为 AI 任务的输入,但不要只给模型一句“把这个 React Native 页面改写成 SwiftUI”。更可靠的提示词应包含明确边界:
将 Shop Home 流程迁移到 SwiftUI。
约束:
- API 请求和字段语义必须与 fixtures/shop-home.json 一致。
- 保留 shop_home_viewed 和 product_opened 两个埋点名称。
- UI 状态只能是 loading、content、empty、offline、error。
- 不新增第三方依赖。
- 先生成 ViewModel 单元测试,再生成实现。
- 输出修改文件列表,并标记无法从现有代码确认的行为。
同一任务在 Android 端可以复用接口样例、状态定义和验收标准,但让模型输出 Compose 与 Kotlin 协程实现,而不是强求两个平台共享界面结构。
AI 能加速编码,但不能替代迁移控制面
大规模重写最危险的结果不是编译失败,而是新应用能够运行,却在边缘行为上悄悄偏离旧版本。例如深链参数被忽略、离线缓存失效、埋点字段改变,或者辅助功能标签缺失。
因此,迁移流水线至少应设置这些门槛:
- 每个流程都有旧版行为、接口夹具和验收负责人。
- AI 生成代码必须经过格式化、静态分析、单元测试和人工审查。
- iOS 与 Android 分别运行截图或快照测试,不追求像素完全相同,但要验证状态完整。
- 支付、鉴权、隐私权限和数据删除流程禁止无审查自动合并。
- 新旧版本采用灰度发布,持续比较崩溃率、启动时间、转化率和关键埋点。
- 平台扩展能力尽早制作技术样板,不要留到主应用迁移完成后才验证。
还需要警惕另一种成本转移:AI 可以快速制造大量代码,但生成速度可能超过团队的审查和测试能力。此时瓶颈会从“写代码”转移到“证明代码正确”。控制并行任务数量、限制单次变更范围,通常比一次生成几十个屏幕更可靠。
是否应该跟进这条路线
Shopify 的案例说明,在产品行为已经明确、自动化基础较好、平台能力占比较高时,AI 可以改变原生重写的经济账。但它并不能推出“所有 React Native 应用都应该迁回原生”。
准备做类似决策的团队,可以先回答五个问题:
- 当前最昂贵的问题来自 React Native 本身,还是来自产品复杂度和工程管理?
- 应用是否大量依赖小组件、手表、后台任务、系统快捷方式等平台能力?
- 是否有足够的接口夹具、测试和监控来约束 AI 生成结果?
- 团队能否长期维护 Swift 与 Kotlin 两套实现,而不是只完成一次重写?
- 能否先用一个边界清晰的应用或流程验证速度、质量和维护成本?
更稳妥的采用方式是先选一个可独立发布、指标明确的流程,完成双端原生实现并运行数周,再决定是否扩大迁移范围。12 周是一个醒目的交付数字,但真正决定迁移是否成功的,是发布一年后功能迭代是否更快、平台接入是否更直接,以及两套原生代码是否仍然可控。