Expo EAS Build 是 Expo 官方提供的云端编译服务,用于把 React Native 工程打包成可上架 App Store 与 Google Play 的二进制文件,而 EAS Submit 负责把这些产物自动推送到 App Store Connect 与 Google Play Console。我用 EAS 流水线上线过六款应用,从两人小作坊到日活百万的产品都有。下面这套流程,是我现在每个新项目第一周就会落地的「标准动作」,覆盖凭证、构建配置、提交、OTA 更新与回滚。
EAS Build 在 2026 年仍然是 Expo 与裸 React Native 项目最稳的云端构建方案,免费档每月 30 次构建,付费档支持优先队列与 M2 Pro 加速。
用 development、preview、production 三套 profile 区分调试、TestFlight 灰度与正式上架,再配合 channel 字段精确控制 OTA 推送。
EAS Submit 一次性配置后即可全自动上架,iOS 端必须先把 ASC API Key 上传到 EAS。
EAS Update 适合修 JS/资源 bug,但任何原生依赖变更仍然必须重新跑 EAS Build。
使用 runtime version policy fingerprint,是新架构项目最安全的版本兼容策略。
什么是 EAS Build 与 EAS Submit
EAS(Expo Application Services)是 Expo 团队提供的一组云端开发者服务,其中 EAS Build 负责把 React Native 工程编译为 .ipa 或 .aab/.apk,EAS Submit 负责自动提交到 App Store Connect 与 Google Play Console。它的卖点是不再需要自维护一台插着 Apple ID 的 Mac mini:Apple Silicon 构建机由 Expo 托管,凭证由 EAS 加密保管,日志可以在浏览器里直接查看。
buildType: "app-bundle":正式发版必须用 AAB,Google Play 已经禁止纯 APK 上架。
channel:对应 EAS Update 的推送通道,profile 与 channel 必须一一对应,否则 OTA 推送会错位。
iOS 凭证与 Provisioning Profile 实战
iOS 凭证是新手最大的拦路虎。EAS 提供了两种模式:让 EAS 全自动管理(推荐),或者手动上传 .p12。99% 情况下选自动就好。
# 交互式登录 Apple ID 并由 EAS 创建/同步凭证
npx eas-cli credentials
# 或者直接在第一次 build 时由 EAS 引导创建
npx eas-cli build --platform ios --profile production
EAS 会用你的 Apple ID 登录 App Store Connect API,自动创建 Distribution Certificate 与 Provisioning Profile,然后把私钥加密存到 EAS 服务器。整个过程不超过两分钟,关键是不再需要 Keychain 与 Xcode Organizer,这对没有 Mac 的 Windows/Linux 开发者意义重大。
如果开启了 Apple Account 的两步验证(2026 年所有开发者账号都强制开启),推荐改用 App Store Connect API Key:在 ASC 里 Users and Access → Integrations 创建一个 Admin 权限的 Key,把 .p8 文件、Key ID、Issuer ID 通过 eas credentials → "Add new App Store Connect API Key" 录入。后续 Submit 与凭证同步都不再需要交互式 2FA,CI 全自动跑也不会卡。我上一个项目就是因为没切到 API Key,凌晨自动发版被 2FA 卡了快两个小时,那种凌晨三点爬起来手动点验证码的体验,真的不想再来一次。
对于企业内部分发(In-House),需要把 distribution 字段设为 "enterprise",并在 EAS credentials 中切换到 Enterprise Program 账号。注意 Apple 在 2025 年大幅收紧了 In-House 资格审核,新申请的拒批率超过 70%,能用 TestFlight 就别走 Enterprise。
Android Keystore 与签名配置
Android 简单得多。首次运行 eas build --platform android 时 EAS 会提示生成一份新的上传 keystore,默认的 RSA 2048 + 10000 天有效期完全够用。千万记住:上传 keystore 一旦丢失,App ID 实际上就报废了。Google Play 虽然支持 Play App Signing(应用签名密钥与上传密钥分离),但前提是你能继续用原上传密钥签名 AAB。
Play App Signing 是 Google 自 2021 年起的强制要求,EAS 已经默认启用。上传 AAB 后 Google 会用平台层的应用签名密钥重新签名再分发给用户。这意味着,真正能影响安装的不是你的上传密钥,而是 Google 那把你看不到的密钥。所以一旦发版后想切换 App ID 几乎不可能,选 App ID 务必慎重。
另外一个常被忽略的点:android.versionCode 必须严格递增。如果用了 appVersionSource: "remote",EAS 会自动管理;否则建议在 CI 里跑 npx eas-cli build:version:set 把版本号显式同步,避免本地工程师覆盖远程值导致提交被 Play Console 拒。
EAS Update 是 OTA 通道:不走商店审核,直接把新的 JS bundle、图片、字体推到已经安装应用的设备。每次冷启动,RN 运行时会从 Expo CDN 拉取最新 manifest,匹配 channel 与 runtime version 后下载补丁。整个流程类似 Web 的渐进式发布。
# 给 production 渠道推送一次更新
npx eas-cli update --branch production --message "Fix payment screen typo"
# 紧急回滚:把 channel 重新指向更早的发布
npx eas-cli channel:edit production --branch production-rollback