Shopify 最近宣布放弃 React Native,转而用 Swift 和 Kotlin 重写其旗舰移动应用。这个决定的重点并不只是技术栈更换,而是一个更值得移动团队关注的判断:当 AI 显著提高原生代码的生产效率后,跨平台抽象层过去节省的成本,可能已经不再足以抵消它带来的限制。
React Native 的价值,正在被重新估算
React Native 的核心吸引力一直很清晰:团队可以使用相对统一的 JavaScript/TypeScript 代码,同时覆盖 iOS 和 Android,减少重复实现,并共享部分业务逻辑。
但抽象层也会带来长期成本。复杂交互、平台特性、性能优化、系统 API 适配和版本升级,往往需要开发者理解 React Native、原生平台以及两者之间的桥接机制。团队规模越大、应用生命周期越长,这些边界成本越容易累积。
Shopify 移动负责人 Mustafa Ali 的重新评估基于一个变化:AI 模型的代码生成、重构和问题定位能力明显提升后,维护两套原生代码库的成本收益比可能已经超过使用抽象层的方案。
这并不意味着 React Native 失去了价值,而是技术选型中的变量发生了变化:原生开发的人工成本下降了,抽象层的维护成本却没有自动消失。
AI 改变的是成本结构,不是平台差异
AI 可以帮助开发者快速生成 Swift、Kotlin、测试代码和平台适配逻辑,但它不会让 iOS 与 Android 变成同一个平台。两边仍然存在不同的生命周期、UI 组件、权限模型、后台机制和发布流程。
因此,原生路线是否更划算,取决于以下几个问题:
- 产品是否高度依赖平台能力,例如支付、推送、相机、蓝牙或系统分享?
- 团队是否能够分别维护 Swift 和 Kotlin 的工程规范?
- 应用是否有足够长的生命周期,能够摊薄重写成本?
- 当前跨平台层是否已经积累了大量桥接代码和平台特判?
- AI 生成的代码是否有稳定的测试、审查和安全检查流程?
AI 最适合削减重复劳动,例如生成基础界面、数据模型、测试样例、迁移脚本和常见 API 调用。它不能替团队决定产品交互,也不能替代对线程、生命周期、内存和权限问题的验证。
用一个简单模型比较两种路线
不要只比较“写一份代码”与“写两份代码”。更实用的方式是估算三年的总工程成本:
跨平台总成本 = 抽象层维护成本 + 原生桥接成本 + 平台特性损耗 + 升级风险
原生总成本 = 双平台实现成本 + 共享业务逻辑成本 + 双平台测试成本
可以把这个模型落到团队自己的数据上。下面的脚本只是一个可修改的估算模板,不代表 Shopify 的实际数据:
#!/usr/bin/env bash
set -euo pipefail
# 单位:人月。请替换成团队过去 12 个月的实际估算。
react_native=24
rn_bridge_and_upgrade=14
native_ios=20
native_android=22
shared_backend_contract=6
native_test_and_release=10
cross_platform_total=$((react_native + rn_bridge_and_upgrade))
native_total=$((native_ios + native_android + shared_backend_contract + native_test_and_release))
echo "React Native route: ${cross_platform_total} person-months"
echo "Native route: ${native_total} person-months"
if (( native_total < cross_platform_total )); then
echo "Result: native may have the lower modeled cost"
else
echo "Result: cross-platform may have the lower modeled cost"
fi
更可靠的做法是把线上缺陷、桥接模块数量、平台特判数量、构建时间和版本升级工时也纳入模型。尤其要避免只计算首次开发,不计算未来两三年的维护。
原生重写不等于复制两份代码
如果团队决定采用 Swift 和 Kotlin,建议把可共享的边界放在业务契约,而不是强行共享 UI 实现。例如,服务端 API 契约、埋点事件、设计令牌和测试数据可以保持一致,而导航、状态管理和系统交互允许遵循各自平台的习惯。
下面是一个简化的跨平台业务契约示例。它不是完整生产代码,但可以作为迁移时的接口约束:
// iOS: Swift
struct CartSummary: Codable {
let itemCount: Int
let totalCents: Int
}
protocol CartService {
func loadSummary() async throws -> CartSummary
}
// Android: Kotlin
@kotlinx.serialization.Serializable
data class CartSummary(
val itemCount: Int,
val totalCents: Int
)
interface CartService {
suspend fun loadSummary(): CartSummary
}
实际项目中,可以用 OpenAPI、JSON Schema 或共享测试夹具保证两个客户端对数据格式的理解一致。这样共享的是稳定的业务边界,而不是把两个平台硬塞进同一套 UI 抽象。
迁移时应避免一次性重写
从 React Native 切换到 Swift 和 Kotlin,最大的风险通常不是新代码写不出来,而是重写期间产品交付停滞、行为出现差异,以及团队同时维护新旧两条路径。
比较稳妥的路线包括:
- 先测量现有 React Native 工程中的桥接模块、平台特判和高频缺陷。
- 选择一个边界清晰、用户影响可控的功能做原生试点。
- 为 iOS 和 Android 建立统一的接口契约、埋点命名和验收用例。
- 让 AI 参与代码生成和迁移,但要求所有生成代码通过编译、测试和人工审查。
- 通过功能开关逐步切换流量,而不是在一个版本中替换整个应用。
- 重写完成后删除旧桥接代码,否则团队会同时承担两套系统的维护成本。
如果应用主要是表单、内容展示和简单业务流程,跨平台方案仍然可能更高效。如果应用高度依赖原生体验、复杂动画或平台 API,原生路线的长期收益则更值得认真评估。
给移动团队的决策清单
在做技术栈决定前,可以用下面的清单进行一次实际盘点:
- 当前跨平台代码中,真正共享的业务逻辑比例是多少?
- 每个月有多少工时花在桥接、补丁和平台差异上?
- AI 是否已经接入代码审查、测试生成和迁移流程?
- 团队能否同时招聘、培养并留住 Swift 与 Kotlin 工程师?
- 原生重写能否按模块发布,并通过指标验证收益?
- 两种路线在性能、崩溃率、发布速度和开发体验上的差异是否可测量?
Shopify 的选择更像是一个信号,而不是一条普适规则:当工具和 AI 改变了生产效率,过去默认成立的抽象层优势也需要重新计算。移动团队不必因为行业巨头转向原生就立即跟随,但应该定期用真实维护数据,而不是历史经验,重新审视跨平台技术的总成本。