安装 eas-cli
npm install -g eas-cli eas login eas init # 关联 Expo 项目 ID
eas.json 配置
{
"cli": { "version": ">= 13.0.0" },
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"channel": "development"
},
"preview": {
"distribution": "internal",
"ios": { "simulator": true },
"channel": "preview"
},
"production": {
"autoIncrement": true,
"channel": "production"
}
},
"submit": {
"production": {
"ios": {
"appleId": "dev@myapp.com",
"ascAppId": "1234567890",
"appleTeamId": "AB12CD34EF"
},
"android": {
"serviceAccountKeyPath": "./google-service-key.json",
"track": "production"
}
}
}
}
三个 profile:
development
带 dev-client 的自定义包,可以连本地 Metro,能装任意 native 包。平时开发装这个到真机。
preview
release 模式但内部分发,给团队/客户试用。iOS 可生成模拟器版本。
production
上架商店的包,
autoIncrement 自动递增构建号。云端打包
# 开发包 eas build --profile development --platform ios eas build --profile development --platform android # 生产 eas build --profile production --platform all
EAS 在云端 macOS/Linux 跑 expo prebuild + xcodebuild / gradle,产物 .ipa/.aab 链接给你下载。没 Xcode 也能出 iOS 包(但生产需要 Apple 开发者账号提供证书 — EAS 帮你托管)。
本地打包(对照)
# 生成 ios/android 目录 npx expo prebuild # iOS 开 Xcode,Android 开 Android Studio 打包 cd ios && pod install && xcodebuild ... cd android && ./gradlew bundleRelease
EAS 把这套流水线搬云端而已。你可以手工,也可以让它跑。
提交商店
eas submit --profile production --platform all # iOS 推到 TestFlight,Android 推 Play Console 的指定 track
OTA:expo-updates
OTA(Over-The-Air)= 不发新版,直接把新 JS bundle 推到用户端。适合改文案、修 bug,只要没动 native 代码。
npx expo install expo-updates eas update:configure # 自动改 app.json 加 updates 字段
{
"expo": {
"updates": {
"url": "https://u.expo.dev/your-project-id",
"enabled": true,
"checkAutomatically": "ON_LOAD",
"fallbackToCacheTimeout": 0
},
"runtimeVersion": { "policy": "appVersion" }
}
}
发推送
# 发布到 production channel(对应 production profile 的包) eas update --branch production --message "修复登录 bug" # 发 preview eas update --branch preview --message "内测新功能"
几秒钟后,你的用户下次冷启动 App 会检查新 bundle,下载后下次启动生效。
Channel 与 Branch
Channel
构建产物带的标签,写在 eas.json 的 build.channel。一经打包不可改。
Branch
Update 的分支,可以动态切换 channel 指向哪个 branch。生产事故时,把 production channel 指回旧 branch = 一键回滚。
# 回滚:把 production channel 指回 v1.2 branch eas channel:edit production --branch v1.2 # 查看当前 channel 关联 eas channel:view production
runtimeVersion 与原生代码
OTA 只能推 JS,不能改 native
如果你加了新的 native 模块或升 Expo SDK,runtimeVersion 必须改,旧版本 App 拿不到这次 update——他们得从商店升包。推荐
如果你加了新的 native 模块或升 Expo SDK,runtimeVersion 必须改,旧版本 App 拿不到这次 update——他们得从商店升包。推荐
{"policy": "appVersion"},用 app.json 里 version 字段自动驱动。
生产时代码里兜一下
import * as Updates from 'expo-updates'; async function checkForUpdate() { try { const { isAvailable } = await Updates.checkForUpdateAsync(); if (isAvailable) { await Updates.fetchUpdateAsync(); Alert.alert('有新版本', '重启应用?', [ { text: '稍后' }, { text: '立刻重启', onPress: () => Updates.reloadAsync() }, ]); } } catch (e) { console.warn(e); } }
EAS Workflows:CI/CD 全托管
.eas/workflows/ └── publish.yml
name: Publish
on:
push:
branches: [main]
jobs:
ota:
steps:
- uses: eas/checkout
- uses: eas/install_node_modules
- uses: eas/update
with:
branch: production
message: "auto from ${{ github.sha }}"
或直接用 GitHub Actions 调 EAS CLI:
- name: OTA update
run: eas update --branch production --non-interactive
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
常见坑
iOS 证书
第一次
eas build 会问要不要让 EAS 管证书——选 yes 最省事。想自己管则 eas credentials 手动导入 .p12/Provisioning Profile。Android 签名
EAS 默认生成 keystore 并托管。导出到 Play Console 的 key upload 只有一次机会,存好
eas credentials 里的备份。OTA 老用户不更新
App 启动时会去
u.expo.dev 查 update,网络差时跳过用本地缓存。可以手动 checkForUpdateAsync 触发。苹果拒绝 OTA
苹果审核规则:OTA 只能 JS/资产,不能变业务性质(假比:做的是记账 App,OTA 推成游戏,拒)。保守起见,重大改动仍走商店审核。
成本
- Build:免费 30 次/月(2025)够个人用,商业 Production 套餐 99$/月,无限打包
- Update:免费 MAU 1000 以内,超过按档收费
- Submit:免费(调用商店 API)
自托管方案:@expo/eas-build-action 自建 Runner,或 expo-updates 的协议是公开的,用 S3 自己实现 update server。中型以上团队会走自建。
本章小结
- eas.json 三级 profile:development(带 dev-client)、preview(内部分发)、production(商店)
eas build云打包,eas submit直推 App Store / Play Console- OTA(expo-updates)推 JS bundle 免审核,
runtimeVersion控制版本隔离 - Channel ↔ Branch 分离:一键回滚 =
eas channel:edit --branch - 小团队用 EAS 托管,中型以上可自建 Runner + S3 update server