构建与上架
用 EAS Build、EAS Submit 和 OTA 更新发布 01MVP 移动端
移动端发布要分清三件事:本地能跑、别人能下载、商店能上架。它们不是同一个阶段。
01MVP mobile 使用 EAS Build 生成安装包和商店包,使用 EAS Submit 上传到 App Store Connect 和 Google Play。Web bundle 烟测可以本地跑,iOS 和 Android 原生包建议交给 EAS。
这篇只讲发布链路的判断和大概步骤,不把 Expo 官方文档里的每个交互问题都复制一遍。实际执行时,可以让 AI 按当前 products/01mvp/apps/mobile、app.json、eas.json 和账号状态跑命令、改配置、看日志。遇到账号登录、双重验证、Apple / Google 后台、首次上传、签名凭据或 EAS CLI 交互问题,直接看 Expo 官方文档:
- Build your project for app stores:确认 production build、开发者账号、签名凭据、构建日志和 EAS Workflow。
- Submit to app stores:确认 EAS Submit、App Store Connect、Google Play Console、服务账号和首次提交限制。
三种构建怎么选
development
给开发者用。包含 dev client,用来调原生模块、深链、图标、启动页和真机登录。
preview
给内测用户用。EAS 会生成可下载链接,适合产品验收和早期反馈。
production
给商店发布用。要求正式 URL、稳定 App 身份、商店资料和审核准备都到位。
本地构建烟测
vpr @01mvp/mobile#build这个命令会执行 Expo web export,主要用于确认 JS bundle、路由、样式和静态依赖能被打包。它不是 iOS / Android 原生构建,也不能替代真机测试。
初始化 EAS
进入移动端目录:
cd products/01mvp/apps/mobile
eas initEAS 会写入项目 ID。确认 app.json 中的 extra.eas.projectId 属于你自己的项目。如果你启用了 EAS Update,还要确认 updates.url 指向同一个 EAS project。
如果 app.json 里还是模板默认的 com.01mvp.mobile、01mvp-mobile、01mvp,不要直接拿去上架。先看 App 身份 和 配置 app.json,把名称、Bundle ID、Android package 和 scheme 改成你的产品。
让 AI 或 CI 自动构建前要准备
EAS 本地交互式命令会提示你登录、选团队、生成凭据。AI 或 CI 不能替你完成网页登录和双重验证,所以要提前准备这些:
| 凭证或配置 | 用途 | 没有它会怎样 |
|---|---|---|
EXPO_TOKEN | 非交互触发 EAS Build / Submit | 命令会停在 Expo 登录 |
| EAS Environment | production / preview 构建变量 | 远程构建拿不到你的 API、RevenueCat 等配置 |
| Apple Developer 团队权限 | iOS signing、TestFlight、App Store Connect | iOS 构建或上传失败 |
| App Store Connect API Key | 非交互上传 iOS build | eas submit 需要你手动登录或中断 |
| Google Play service account | 非交互上传 Android build | Android submit 无法自动完成 |
| RevenueCat public SDK key | 内购 entitlement 检查 | App 只能显示未配置或免费状态 |
| 隐私政策和测试账号 | 商店审核 | 上传成功后也无法顺利提交审核 |
如果目标是“明早看到 TestFlight 包”,最低要提前完成 Expo 登录或 EXPO_TOKEN、Apple Developer Program、App Store Connect app record、正确的 Bundle ID 和生产 API 地址。否则 AI 可以把代码、构建和本机验证做到位,但不能越过账号授权。
Development build
vpr @01mvp/mobile#eas:build:development用于真机调试原生模块、RevenueCat、deep link、图标、启动页等 Expo Go 不能完整覆盖的能力。它包含 expo-dev-client,安装后仍然可以连接本地 Expo 开发服务器。
典型流程:
- 先跑
vpr @01mvp/mobile#eas:build:development。 - 从 EAS 控制台或命令行提示下载并安装。
- 再跑
vpr @01mvp/mobile#dev。 - 在开发版 App 里打开当前项目。
只改 JS、样式和普通页面时,不需要每次重建 development build。新增原生依赖、Expo plugin、权限、scheme、图标或启动页时,需要重新 build。
Preview build
vpr @01mvp/mobile#eas:build:preview用于内测分发。preview profile 使用 internal distribution,构建完成后会有下载链接或二维码。
| 平台 | 下载和安装方式 |
|---|---|
| Android | 通常生成 APK,用户下载后按系统提示允许安装 |
| iOS | 通常走 Ad Hoc 或企业分发;Ad Hoc 需要提前登记设备 UDID |
iOS 的 preview build 不是随便发给任何 iPhone 就能安装。Ad Hoc 分发要把测试设备加入 Apple Developer 账号,新增设备后通常要重新构建或重新签名。
preview build 适合这些事情:
- 给团队、设计师、早期用户看真实 App。
- 验证真机登录、会员状态、核心流程和崩溃上报。
- 准备商店截图前做一次产品验收。
preview build 不适合长期公开分发。正式用户下载应该走 App Store、Google Play 或合规的企业内部分发。
Production build
vpr @01mvp/mobile#eas:build:production生产构建前检查:
app.json的 App 名称、slug、scheme、iOS Bundle ID、Android package 已改成你的产品eas.jsonproduction profile 的公开 URL 已改成你的生产地址- 如果启用内购,RevenueCat iOS / Android public SDK key 已放进 production profile 或 EAS 环境
- Web/API 已部署,
EXPO_PUBLIC_SERVER_URL可从公网访问 - Better Auth 的
NATIVE_APP_SCHEME已部署到服务端 - RevenueCat、App Store Connect、Google Play Console 已创建对应产品
- Apple Developer、Google Play Console、隐私政策、商店截图、测试账号和审核备注已经准备好
production build 会生成商店可用的 iOS .ipa 和 Android .aab。iOS 真正给用户下载前还要进入 TestFlight 或 App Store 审核;Android .aab 通常上传到 Google Play 的内部测试、封闭测试、公开测试或正式版轨道。
提交到商店
vpr @01mvp/mobile#eas:submit:productionEAS Submit 负责把构建产物上传到商店后台。上传成功不等于已经公开发布。
iOS:App Store Connect 和 TestFlight
EAS Submit 会把 iOS build 上传到 App Store Connect。上传后通常先进入 TestFlight,你还需要在 App Store Connect 做这些事:
- 等构建处理完成。
- 用 TestFlight 安装并验证核心流程。
- 补应用名称、副标题、截图、隐私问卷、年龄分级、关键词、支持地址和审核备注。
- 创建版本,选择这次构建。
- 提交 App Review。
TestFlight 不是正式上架。只有 App Review 通过并发布后,用户才能在 App Store 下载。
Android:Google Play Console
EAS Submit 会把 Android build 上传到 Google Play Console。首次接入时,Google Play 的部分 API 提交流程可能需要你先在后台手动完成初次上传或应用创建。
上传后继续处理:
- 选择内部测试、封闭测试、公开测试或正式版轨道。
- 填版本说明。
- 补商店详情、截图、隐私政策、数据安全表单和内容分级。
- 提交审核。
Android 的内部测试很适合比 iOS Ad Hoc 更大范围地收集反馈,但也要按 Google Play 的账号和审核规则来。
如果还没有固定 Apple App ID,先完成 Apple 平台配置 和 Apple 与 iOS 配置,再提交第一版商店构建。
可选:把 iOS 发版做成脚本
模板默认推荐 EAS Build / EAS Submit,因为它对小团队更省心:证书、构建机和上传流程都少操心一些。
当项目进入正式产品阶段,你也可以把 iOS 发版固化成产品自己的脚本。它适合这些情况:
- 你已经在 Apple Developer 里手动建好了 App ID、capabilities 和 provisioning profile。
- App 有 widget、extension、App Groups、Associated Domains 等多个 target,需要明确控制每个 target 的 profile。
- 你希望本机、CI 或 Agent 都跑同一条命令,不靠临时网页操作记忆。
- 你不想把每次发版都变成“打开 Xcode、找菜单、导出、再上传”的手工流程。
1
同步版本
app.json、Info.plist、Xcode project 保持一致。
2
代码检查
先跑 type-check,基础错误不要进入打包。
3
Archive
用 xcodebuild archive 生成 .xcarchive。
4
Export
用 App Store profile 导出 .ipa。
5
Upload
上传到 App Store Connect,进入 TestFlight 处理队列。
6
人工收尾
测试、截图、隐私问卷、审核信息仍然要补齐。
脚本建议放在产品自己的移动端目录:
products/<product>/apps/mobile/scripts/ios-release.mjs然后在移动端 package.json 里加命令:
{
"scripts": {
"release:ios": "node ./scripts/ios-release.mjs",
"release:ios:upload": "node ./scripts/ios-release.mjs --upload"
}
}如果这个产品还有 products/<product>/package.json 作为统一入口,可以再接一层:
{
"scripts": {
"release:ios": "vpr @your-product/mobile#release:ios",
"release:ios:upload": "vpr @your-product/mobile#release:ios:upload"
}
}这样以后发版就是一条命令:
vpr @your-product/product#release:ios:upload -- --version 0.1.2 --build 3脚本至少要做这些检查和约束:
| 环节 | 建议 |
|---|---|
| 版本号 | version 和 iOS buildNumber 必须显式传入或从配置读取,不能靠手动改一半 |
| 多 target | 主 App、widget、extension 的 Bundle ID 和 provisioning profile 要分别写清楚 |
| 证书 | 只读取本机 Keychain 或 CI secret,不把证书私钥提交进仓库 |
| 产物 | .xcarchive、.ipa、export plist 等生成文件放进 build/,并加入 .gitignore |
| 上传 | 上传成功只代表 App Store Connect 收到了包,不代表 TestFlight 已可安装 |
| 失败处理 | 构建、签名、上传任一步失败都要直接退出,不能继续跑后续步骤 |
这类脚本不能完全取代 App Store Connect:
- 首次创建 app record、填写隐私问卷、年龄分级、截图、审核备注,仍然要在后台完成。
- Xcode 登录、Apple 账号双重认证、协议更新,可能会打断自动上传。
- TestFlight 构建处理完成需要等待;外部测试还可能触发额外审核。
- 如果 capabilities 改了,要先回到 Apple Developer 更新 App ID 和 profile,再重新打包。
脚本的价值是把“每次都一样”的构建、签名、导出和上传稳定下来;商店资料、审核判断和账号授权仍然要按平台规则处理。
上架前资料清单
| 资料 | iOS | Android |
|---|---|---|
| 商店名称和副标题 | App Store Connect | Google Play Console |
| 截图 | 按设备尺寸准备 | 按手机、平板等设备类型准备 |
| 隐私政策 | 必填,且要和 App 行为一致 | 必填,且要和数据安全表单一致 |
| 测试账号 | 审核员需要能登录 | 审核员需要能登录 |
| 支付和订阅说明 | RevenueCat / App Store 产品要对齐 | RevenueCat / Play 产品要对齐 |
| 审核备注 | 说明登录、付费、特殊功能入口 | 说明登录、付费、特殊功能入口 |
审核前不要只测首页。至少在真机跑一遍登录、退出登录、受保护 API、会员状态、网络失败、空状态和主要业务流程。
OTA 更新
不改原生依赖、不改 app.json 原生字段、不新增 Expo plugin 时,可以用 EAS Update 推 JS 层更新:
vpr @01mvp/mobile#eas:update:productionOTA 适合修文案、改样式、修 JS bug、调整普通页面。新增原生模块、修改 Bundle ID、scheme、权限、图标、启动页、Expo SDK 或 RevenueCat 原生配置时,必须重新 build,并按需要重新提交商店。
常见误区
| 误区 | 实际情况 |
|---|---|
| Web bundle build 通过就能上架 | 还需要原生 production build、商店资料和真机验收 |
| preview link 可以公开发给所有人 | iOS Ad Hoc 有设备登记限制,Android 也不是商店正式分发 |
| EAS Submit 上传成功就是上线 | 还要在 App Store Connect / Google Play Console 完成审核和发布 |
| OTA 可以更新任何内容 | 只适合非原生变更,平台审核规则仍然要遵守 |
| Bundle ID 以后可以随便改 | 上架后修改身份会影响商店、登录、推送、支付和更新链路 |
官方参考
这篇文档有问题?