
Expo EAS 构建与部署:从开发到应用商店
Expo Application Services (EAS) 已成为 React Native 构建和部署的黄金标准。EAS Build 处理云端原生编译,EAS Submit 自动化商店提交,EAS Update 实现即时空中更新。
设置 EAS
安装与初始化
npm install -g eas-cli
eas login
eas init --id your-project-id
eas.json 配置
{
"cli": {
"version": ">= 7.0.0",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"env": {
"APP_ENV": "development",
"API_URL": "https://api-dev.example.com"
}
},
"staging": {
"distribution": "internal",
"env": {
"APP_ENV": "staging",
"API_URL": "https://api-staging.example.com"
},
"android": {
"buildType": "apk"
},
"ios": {
"simulator": false
}
},
"production": {
"autoIncrement": true,
"env": {
"APP_ENV": "production",
"API_URL": "https://api.example.com"
},
"android": {
"buildType": "app-bundle"
}
}
},
"submit": {
"production": {
"android": {
"serviceAccountKeyPath": "./service-account.json",
"track": "internal"
},
"ios": {
"appleId": "your@apple.com",
"ascAppId": "1234567890",
"appleTeamId": "TEAM123"
}
}
}
}
多环境配置
使用环境变量的 app.config.js
// app.config.js
const IS_DEV = process.env.APP_ENV === 'development';
const IS_STAGING = process.env.APP_ENV === 'staging';
export default {
name: IS_DEV ? 'MyApp (Dev)' : IS_STAGING ? 'MyApp (Staging)' : 'MyApp',
slug: 'my-app',
version: '1.0.0',
icon: IS_DEV ? './assets/icon-dev.png' : './assets/icon.png',
android: {
package: IS_DEV
? 'com.example.myapp.dev'
: IS_STAGING
? 'com.example.myapp.staging'
: 'com.example.myapp',
},
ios: {
bundleIdentifier: IS_DEV
? 'com.example.myapp.dev'
: IS_STAGING
? 'com.example.myapp.staging'
: 'com.example.myapp',
},
extra: {
apiUrl: process.env.API_URL,
appEnv: process.env.APP_ENV,
eas: { projectId: 'your-project-id' },
},
updates: {
url: 'https://u.expo.dev/your-project-id',
},
runtimeVersion: {
policy: 'appVersion',
},
};
EAS Build 工作流
构建所有平台
# 开发构建
eas build --platform all --profile development
# 预发布构建
eas build --platform android --profile staging
# 生产构建
eas build --platform all --profile production --non-interactive
自定义构建钩子
// eas.json 附加配置
{
"build": {
"production": {
"buildArtifactPaths": ["ios/build/MyApp.ipa"],
"prebuildCommand": "node scripts/pre-build.js",
"cache": {
"key": "my-cache-key-v1",
"paths": [
"node_modules",
"ios/Pods"
],
"disabled": false
}
}
}
}
EAS Update:OTA 更新
配置
npx expo install expo-updates
eas update:configure
在应用中:
import * as Updates from 'expo-updates';
async function checkForUpdates() {
if (__DEV__) return;
try {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
await Updates.fetchUpdateAsync();
await Updates.reloadAsync();
}
} catch (error) {
console.error('Update check failed:', error);
}
}
// 在 App.tsx 中
useEffect(() => {
checkForUpdates();
}, []);
更新频道与回滚
# 发布更新到 staging 频道
eas update --channel staging --message "修复登录错误"
# 发布到生产环境
eas update --channel production --message "v1.2.1 热修复"
# 列出更新
eas update:list --channel production
# 回滚(重新发布之前的更新)
eas update:republish --channel production --group <update-group-id>
运行时版本策略
// eas.json
{
"build": {
"production": {
"channel": "production",
"runtimeVersion": "1.0.0"
}
}
}
应用签名管理
Android 密钥库
# EAS 自动管理凭据
eas credentials --platform android
# 或提供自己的凭据
eas credentials --platform android --profile production
iOS 证书和配置文件
# 自动管理 iOS 凭据
eas build --platform ios --profile production
# EAS 会自动创建/更新证书
# 查看凭据
eas credentials --platform ios
CI/CD 集成
GitHub Actions 工作流
# .github/workflows/eas-build.yml
name: EAS Build
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: \${{ secrets.EXPO_TOKEN }}
- name: Build on EAS
run: eas build --platform all --profile production --non-interactive
- name: Submit to stores
if: github.ref == 'refs/heads/main'
run: eas submit --platform all --profile production --non-interactive
应用商店提交
# 构建成功后提交
eas submit --platform ios --latest --profile production
# 提交特定构建
eas submit --platform android --id <build-id> --profile production
# 构建后自动提交
eas build --platform all --profile production --auto-submit
监控与分析
import * as Updates from 'expo-updates';
import * as Sentry from '@sentry/react-native';
// 跟踪更新采用情况
Sentry.setTag('update_id', Updates.updateId ?? 'embedded');
Sentry.setTag('runtime_version', Updates.runtimeVersion);
Sentry.setTag('channel', Updates.channel);
Sentry.setTag('app_env', process.env.APP_ENV);
结论
EAS Build 和 Deploy 为 React Native 应用提供了完整的、生产级的 CI/CD 管道。云端构建、OTA 更新、自动签名和商店提交的结合,消除了移动部署的大部分操作复杂性。团队可以专注于构建功能,而 EAS 处理基础设施,使其成为从代码到用户设备的最有效路径。