一、环境搭建(一次性配置)
1.1 WSL2 与基础工具链
# PowerShell 中执行
wsl --install && wsl --set-default-version 2
1. 在 WSL (Ubuntu) 内安装 nvm(版本号以 nvm-sh/nvm 官方 README 为准,此处以 v0.40.8 为例)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
source ~/.bashrc
nvm install --lts && nvm use --lts
1. 安装 Git 与 EAS CLI(云端构建提交要用)
sudo apt-get install git
npm i -g eas-cli
核心原则:JS 工具链(Node、npm、Git、Expo CLI)全部装在 WSL 内,Metro 也从 WSL 启动,避免 Windows 路径污染导致 Metro Bundler 异常;Android Studio、SDK 与模拟器留在 Windows 侧,两边通过 ADB 互通(见 1.2)。
1.2 Android 环境(本地测试闭环)
- Windows 侧:安装 Android Studio(非 C 盘)和 Java 17
- 配置系统变量:
ANDROID_HOME = D:\Android\Sdk
Path 追加 %ANDROID_HOME%\platform-tools
- WSL 侧:只需安装 ADB 客户端
sudo apt-get install android-tools-adb
adb start-server # 连接 Windows 侧 ADB 服务
说明:按这套分工——Windows 负责 Android 编译、模拟器与真机调试,WSL 负责 JS 工具链与 Metro——ADB 互通之后整个 Android 测试链路在本地闭环,无需云端。
1.3 iOS 环境(不可本地)
WSL 无法运行 Xcode 或 iOS 模拟器。所有 iOS 测试必须依赖:
- Expo Go App(JS 层预览)
- EAS 云端构建(真机原生测试)
- 云真机服务(可选验证)
二、开发测试阶段(核心限制详解)
2.1 可测试的范围(Expo Go)
以下功能在 Expo Go 中可实时热更新测试:
- React 组件、JS 业务逻辑、网络请求
- Expo SDK 内置模块:相机、相册、定位、传感器、SQLite、Asset 等
- 第三方纯 JS 库:axios、lodash、redux 等
2.2 不可测试的原生模块(iOS & Android)
iOS 专属限制:
- 推送通知(APNs):Expo Go 无法注册设备 Token,无法接收生产/测试推送
- 原生 UI 组件:自定义 Objective-C/Swift 组件(如自定义地图、图表)
- 后台任务:
UIBackgroundModes(后台定位、音频播放、数据同步) - Keychain 存取:安全存储密码、证书,Expo Go 的沙盒无法访问
- App Groups / Widget:与主 App 共享数据、桌面小组件
- 私有 API:如 IAP 内购、Apple Pay、Sign in with Apple
- 硬件深度集成:蓝牙 BLE 高级功能、NFC 后台读取
Android 专属限制:
- 第三方厂商推送:华为 Push、小米 Push、OPPO Push(需集成原生 SDK)
- 自定义原生模块:用 Java/Kotlin 写的模块(如支付宝 SDK、指纹识别封装)
- 后台服务:
ForegroundService、WorkManager保活任务 - 系统级权限:
SYSTEM_ALERT_WINDOW(悬浮窗)、WRITE_SECURE_SETTINGS - Root 设备检测:安全支付、防作弊逻辑
- 多进程:运行在不同进程的原生服务
双平台共同限制:
- 原生代码热更新:修改
android/或ios/目录代码后,必须重新构建原生包(npx expo prebuild) - 性能调试:Expo Go 的沙盒性能与生产包差异大,无法准确测试启动时间、内存占用
三、真机测试方案(生产环境验证)
3.1 Android(本地闭环)
# 生成内测 APK:走 EAS 云端构建,WSL 内执行即可
eas build --platform android --profile preview
1. 或走本地 Gradle:Android SDK 在 Windows 侧,需切到 Windows 终端执行
1. PowerShell: cd android; .\gradlew assembleRelease
分发:通过 Firebase App Distribution、蒲公英或直接发送 APK。
3.2 iOS(必须云端)
# 云端构建 TestFlight 包
eas build --platform ios --profile production
1. 自动提交到 TestFlight
eas submit --platform ios
测试:在 App Store Connect 添加内部测试员,通过 TestFlight App 安装。
验证清单:
- 推送通知能否收到
- 后台定位是否持续
- IAP 内购流程是否走通
- App 冷启动时间是否在可接受范围
四、打包上架(EAS 云原生)
4.1 配置 eas.json
{
"build": {
"production": {
"android": {"buildType": "app-bundle"},
"ios": {"distribution": "app-store"}
}
},
"submit": {
"production": {
"ios": {"appleId": "your-apple-id@example.com"},
"android": {"serviceAccountKeyPath": "./play-api-key.json"}
}
}
}
4.2 一键发布
# 双平台构建 + 提交
eas build --platform all --profile production --auto-submit
流程:WSL 发指令 → Expo 云端编译 → 生成 .ipa 和 .aab → 自动上传商店 → 人工填写元数据 → 等待审核。
五、核心风险:开发者账号治理
技术链路打通之后,真正决定项目能否持续运营的是账号本身。一个被封禁的开发者账号意味着已上架应用下架、收入中断,重建账号的成本远高于修复一个技术问题。这一节讲清楚三件事:风险从哪来、哪些做法反而会放大风险、以及怎么正向运营。
5.1 账号被关联的真实原因
Apple 与 Google 都会识别「同一个实际控制人持有多个账号」的情况。一旦账号之间呈现关联特征,新账号在提交阶段就可能被要求提供额外证明,严重时会被直接拒绝。
需要明确的是:多账号本身不是违规行为。合理的情形很常见——公司不同业务线用不同账号、个人开发者同时维护多个产品。问题出在账号之间共享了本应独立的身份要素。
5.2 各类身份要素与合规处理方式
| 要素 | 说明 | 合规做法 |
|---|---|---|
| 开发者身份 | 姓名、邮箱、电话、证件 | 如实填写。多个账号可属于同一主体,但需在 App Store Connect 的组织结构中如实关联,或分别提供真实可验证的联系人 |
| 支付方式 | 银行卡、企业资质 | 企业账号统一走公司主体与对公支付。若确需多个独立主体,请使用真实存在的不同主体,而不是同一人的多个支付工具 |
| Bundle ID 与 App 内容 | 包名、名称、图标、截图、功能 | 每个 App 提供独立的产品价值与品牌。指南 4.3(Spam)明确禁止为同一款 App 创建多个 Bundle ID |
| 构建环境 | 打包所用机器与网络 | 使用 EAS 云端构建可以让多个项目的构建环境天然一致,无需刻意区分本地机器与网络 |
5.3 哪些做法反而会放大风险
网上流传的「马甲包隔离清单」——换信用卡、换账单地址、换手机号、换网络环境、抹盘重装、批量改类名与资源哈希——这类做法不建议采用,原因是:
- 它本身可能构成协议违规。Apple 与 Google 的开发者协议都禁止试图规避平台的风控与审核机制,账号被永久取消的风险由此上升。
- 它解决不了根因。账号被封通常是因为应用本身违反了某条具体的审核条款或存在欺诈行为。换个身份重新提交同一款应用,往往只是重复触发同一个问题,还可能因为多次拒审累积更严重的记录。
- 成本极高且不可持续。批量改哈希需要持续维护,一旦遗漏就会在版本更新时暴露,反而更容易被判定为刻意伪装。
如果账号已经被封禁,正确做法是:
- 在 App Store Connect 的 Resolution Center 中查看具体的拒审条款与审核员说明,确认问题落在哪一条guideline上。
- 针对该条款修改应用或元数据,在同一个账号下重新提交。
- 如果认为判定有误,通过 Resolution Center 提交申诉,说明你依据的条款与事实依据。
- 只有当账号已被官方确认无法恢复,且应用本身完全合规时,才考虑以新的真实主体重新提交——此时必须确保新的 App 提供独立的产品价值,而不是同一款应用的复制品。
5.4 正向的账号运营习惯
- 每个开发者账号只承载一类产品,账号与业务结构保持一致;
- 使用企业账号时,把公司主体、联系方式、税务信息一次性填准确,避免后续因信息不一致被要求补充材料;
- 日常构建统一走 EAS,减少本地环境差异带来的不可复现问题;
- 定期检查隐私标签(Privacy Nutrition Labels)与隐私政策是否与实际行为一致,这是 5.1.1 项下最常见的拒审原因。
六、常见问题排坑
6.1 Expo Go 连接失败
# WSL2 获取 IP
ip addr | grep eth0
1. 强制 Metro 监听所有网络接口
expo start --host lan
6.2 EAS 构建失败
错误:Unable to resolve module @some/native-module
原因:使用了非 Expo 管理的原生依赖
解决:npx expo prebuild 生成原生代码,再 eas build
6.3 Apple 审核被拒
常见条款与对应处理:
- 4.3 Spam:不要为同一款 App 创建多个 Bundle ID,也不要在已饱和的品类里堆砌相似应用。有差异化版本时应提交单个 App,差异部分用内购实现。
- 3.1.1 In-App Purchase:应用内销售数字内容与订阅必须走 IAP。销售实物商品或线下服务则不适用,但要在审核备注里写清楚,便于审核员判断。
- 2.5.1 Private APIs:不能调用 Apple 未公开的接口。Expo 已屏蔽大部分私有 API,但自定义原生模块和第三方 SDK 仍需自检——拒审邮件通常会指出具体符号名,可据此定位依赖并升级或替换。
- 5.1.1 Data Collection and Storage:必须提供可访问的隐私政策链接,隐私标签需如实覆盖所有第三方 SDK 的数据收集行为,涉及账号创建时还要提供应用内注销账号的入口。
- 4.2 Minimum Functionality:应用不能只是网页的壳,需要提供浏览器做不到的能力(通知、离线、相机、后台同步等)。
6.4 Google Play 下架风险
- 权限滥用:不要申请
READ_PHONE_STATE等高危权限 - 数据安全:必须提供隐私政策,且与 App 行为一致
七、一句话总结
Windows + WSL + Expo 实现了技术链路的完全闭环,但 iOS 原生模块测试必须依赖云端;真正的生死门槛是“账号身份隔离”,把每个开发者账号当作独立公司运营,才能避免“一人违规,全家连坐”。
延伸阅读
- React Native 环境搭建——三端工具链的搭建步骤
- 第一个 React Native 应用——Metro 启动链路与真机调试