恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
从本地打包到EAS云构建:React Native开发者的完整迁移指南
首页
资讯中心
/
从本地打包到EAS云构建:React Native开发者的完整迁移指南
从本地打包到EAS云构建:React Native开发者的完整迁移指南
发布时间:2026/10/14 13:33:53
做了几年React Native开发最让我烦躁的事情之一就是打包。每次要给测试发一个Android包都得先检查本地JDK版本对不对、Android SDK是不是又缺了平台、Gradle源能不能拉通运气好半小时搞定运气不好一上午就搭进去了。后来项目迁到了Expo开始用Expo云平台打包EAS把构建这摊事整个甩到云端才算是真正解脱了。这篇就把我从零折腾EAS的完整经历、配置思路和踩坑记录整理出来给正在犹豫要不要迁移到云构建的朋友做个参考。这套东西适合谁只要你在用Expo开发React Native应用不管项目是纯托管工作流还是后来加的自定义原生代码EAS都能帮你把构建、签名、上架这一整条链路串起来。如果你还在本地手动打包或者正在用通用CI工具自己维护一堆构建脚本看看这篇文章里的方案选型思路大概率能帮你省下不少精力。1. 方案选型为什么从本地打包转向云端构建1.1 本地打包的痛点和隐性成本先说本地打包这件事。表面上你只是执行一条gradle assembleRelease或者让Xcode跑一下Archive但实际上你是在维护一套完整的环境。Android这边你需要匹配的JDK版本需要完整的Android SDK平台还要处理Gradle下载依赖时的网络抽风问题。iOS那边更折腾Xcode版本升级可能导致项目结构变化CocoaPods安装慢得让人怀疑人生证书和描述文件的配置更是劝退一大批新手。更隐蔽的成本在于签名文件和版本管理。团队开发的时候keystore文件得小心翼翼地保管一不小心弄丢了上架应用就没法更新了版本号每次手工递增几个人同时开发经常出现两个人打了两个版本号一样的包测试那边根本分不清哪个是新的。这些琐碎问题单个看都不大但累加起来每周浪费在“打包-等-发现问题-重新打包”上的时间相当可观。1.2 EAS Build与自建CI的取舍有人会说那我不用EAS我用GitHub Actions或者其他CI服务自己搭一套自动化构建不行吗完全可以但这取决于你想维护多少东西。自建CI意味着你得自己写构建脚本处理各种Expo配置的传递维护签名文件的加密存储还要在CI环境里复刻Expo项目的构建条件。说实话任何一个环节出问题排查起来都比本地构建更费劲因为CI环境本身就像一个黑盒。EAS Build的价值在于它是Expo官方的托管构建服务和Expo CLI、应用配置天然打通。它不需要你理解Xcode怎么签名、Gradle怎么配置你在网页端或者命令行发一个构建请求它就在云端把环境准备好、依赖装好、构建跑完最后给你一个可以直接安装的产物。对于不想维护构建环境的人而言这是最省心的一条路。1.3 EAS服务生态的整体认识需要先建立一个全局认识EAS不是一个单一功能而是一套服务组合核心是三个部分EAS Build云构建服务生成Android的APK/AAB、iOS的IPA。EAS Submit应用商店上传服务直接把构建产物推到应用商店后台。EAS Update无线更新服务让JavaScript和资源文件的更新不必重新走应用商店审核流程。我目前用得最多的是前两个尤其是Build。理解它们的协作关系很重要Build负责“把代码变成安装包”Submit负责“把安装包送到商店门口”Update负责“应用上线后继续更新小改动”。这三者可以独立使用也可以组合成完整流水线。2. 核心概念与前置准备EAS Build的模式、配置与账号体系2.1 三种构建档案模式第一次看EAS文档的时候我被development、preview、production这三个概念绕了一下。后来才明白它们的本质差异不在代码而在“这个包给谁用、用在哪里”。development档案给开发人员自己用的调试构建必须配合expo-dev-client使用能连接本地开发服务器方便调试原生模块。preview档案给测试人员和产品经理体验用的预览构建可以独立安装运行但不能直接上架商店。production档案给正式发布用的生产构建会做代码压缩、资源优化提交商店基本都用它。这三个档案不是必须全部配置但建议从一开始就分清楚。我见过有些团队只用一个production档案打了所有环境的包测试装的是生产包结果测试环境的接口地址对不上问题排查了大半天才发现是构建档位的问题。2.2 eas.json配置详解与服务端映射EAS构建的很多行为都体现在项目根目录的eas.json文件里面。这个文件是EAS的构建配置中心我用最常见的配置做个说明{ cli: { version: 3.0.0, appVersionSource: remote }, build: { development: { developmentClient: true, distribution: internal, channel: development, env: { APP_ENV: development } }, preview: { distribution: internal, channel: preview, env: { APP_ENV: preview } }, production: { autoIncrement: true, channel: production, env: { APP_ENV: production } } }, submit: { production: { android: { serviceAccountKeyFile: ./keys/google-play-service-account.json }, ios: { appleTeamId: TEAMID, ascAppId: com.example.app } } } }几个关键字段解释一下developmentClient: true声明这是开发客户端构建构建产物会包含Expo开发客户端运行时能主动连接开发服务器。distribution: internal表示构建产物是内部使用不需要进入应用商店审核流程。channel这个字段我一开始没太理解后来在配合EAS Update时明白了它就是给应用更新打的一个标签客户端通过channel知道自己该从哪个更新通道拉取更新。autoIncrement自动递增构建版本号省去手动改版本号的麻烦后面我会细说。env在云端构建时注入的环境变量这样不同档位的构建天然使用不同环境的接口配置代码里通过process.env.APP_ENV读取即可。2.3 账号、项目关联与必要的命令行准备用EAS之前需要先做一些准备工作。第一步就是安装EAS CLI通常用npm全局安装就行npm install -g eas-cli装完之后登录Expo账号这个账号会和后面所有构建行为绑定eas login接下来需要在项目目录里把项目和EAS平台建立关联。第一次运行eas init会自动申请一个项目ID并在app.json里写入对应的配置。这一步千万别跳过我见过有朋友直接把eas.json配好了就去跑构建结果提示项目没有关联EAS服务构建根本发不出去。如果项目之前没有app.jsonEAS CLI会询问你是否创建Expo项目配置文件选择按默认配置生成就行。整个准备过程大概几分钟但能避免后面各种“这服务不认这个项目”的诡异报错。3. 完整实操流程从初始化到商店提交的一站式构建3.1 初始化项目配置与版本号策略假设你已经有一个Expo项目并且完成了eas init的项目关联。真正开始用EAS之前我建议先想清楚版本号策略。App的版本号分两套维度面向用户的版本名versionName比如 1.2.0用户能在设置页面看到。面向构建系统的版本号versionCode / buildNumber单调递增的整数应用商店用它判断哪个包更新。手动维护这两个数字很痛苦所以我推荐依赖EAS的autoIncrement。配置了autoIncrement: true之后每次构建EAS都会自动读取上一次构建的版本号并递增你再也不用为了“这次testing的包为什么装不上是不是版本号一样导致系统不给装”这类问题发愁了。第一次生产构建时它会把默认版本号设为1之后逐次递增。3.2 发起一次开发构建及其参数语义开发阶段最有用的构建模式是development。发起命令如下eas build --platform android --profile development执行之后EAS CLI会干什么它先读取本地的eas.json配置然后把项目代码连同依赖一起上传到云端云端构建完成后把下载链接显示在终端里同时生成一个二维码供真机扫码安装。这里要注意development构建默认包含expo-dev-client它不是纯应用壳而是带开发调试能力的壳。你安装到手机上之后打开App时可以选择连接本地的开发服务器这样你在电脑上改代码手机应用能实时刷新和用Expo Go的开发体验类似但多了支持原生自定义模块的能力。如果你需要在iOS模拟器上构建命令可以加参数eas build --platform ios --profile development --local--local表示在本地模拟器环境构建EAS会帮你在本地完成Expo的预构建步骤但真正的Xcode构建还是在本地跑。这个选项适合需要快速在模拟器上调试的场景。3.3 构建产物下载与安装构建完成后终端会显示一个链接和二维码。Android设备扫码后可以直接下载APK文件安装注意手机需要允许“安装未知来源应用”才行。iOS平台则受限一些内部测试包通常通过TestFlight分发或者用苹果的设备管理工具直接安装IPA。拿到构建链接后第一次安装的人可能会遇到一个问题安装的development包有时候打不开本地的开发服务器。这种情况通常不是包的问题而是手机和电脑不在同一个局域网或者防火墙拦了8081端口。确保开发服务器是expo start启动的并且手机和电脑连的是同一Wi-Fi再重新开关一次应用基本就能识别到。3.4 生产构建与提交商店的衔接当功能验证完、准备发版时就要构建production包。首次生产构建需要配置签名信息。Android这边EAS提供两种方式托管签名模式EAS帮你生成并保管keystore这是默认方式对新手最友好。手动签名模式你提供自己的keystore文件适用于已有上架应用、需要延续签名的场景。iOS这边核心任务是证书和描述文件。同样可以选择EAS托管管理或者手动上传。注意首次构建时终端会提示你登录Apple账号这一步需要能够正常完成双重认证。日常经验是Apple相关登录偶尔会比较慢多试几次就好。生产构建命令eas build --platform all --profile production构建完成之后如果要提交商店可以直接用EAS Submit它会读取构建产物并提交到应用商店后台。Android需要准备好Google Play服务账号的JSON密钥文件可以通过应用商店后台创建iOS需要Apple Team ID和App Store Connect应用ID。配置已经在前面eas.json里展示过。提交命令也很简洁eas submit --platform android --profile production它问你要不要从最近的构建设置中选择提交时选自己构建出来的那个版本就行。整个提交过程会自动上传二进制文件、填写基础信息提交完成后你可以去商店后台继续完善审核所需的截图和描述。3.5 环境变量与敏感信息的管理技巧实际项目中我们通常有多个环境的后端地址不可能每次构建都手动改配置文件。EAS给了两种主要方式来管理环境变量。第一种是写在eas.json的env字段里这种方式配置简单、直观适合区分不同构建档位的非敏感配置。第二种是通过EAS网页后台配置Environment Variables这种方式适合存储敏感信息比如推送服务密钥、支付密钥等。在项目设置页面找到Environment Variables入口添加键值对然后可以指定它用于哪个环境development、preview、production。这两种方式可以混合使用我自己的习惯是非敏感的不同环境配置放eas.json的env敏感的统一走EAS后台。需要特别注意的一点是不要把API密钥、服务器密码这类信息硬编码在代码仓库里尤其当仓库是多人协作或者开源的时候这一点格外重要。4. 常见问题与排查技巧实录4.1 变更签名方案后的排查思路我们曾经遇到过Android构建当时用了EAS托管签名但团队希望切换到自己维护的keystore结果发现不明所以的签名冲突。这种情况通常是项目已经在EAS侧关联了一个keystoreEAS在后续构建时自动沿用了旧签名当你手动引入新keystore时两者不一致导致构建异常或应用无法覆盖安装。解决办法比较简单在项目根目录执行eas credentials --platform android然后选择清楚已存在的Credentials记录重新配置为你自己的keystore信息。注意这个操作要谨慎如果应用已经上架随便替换签名会导致商店版本更新时签名校验失败那是比较严重的线上事故。务必确认你手头的新keystore和商店当前使用的签名一致再执行清理操作。4.2 云端构建超时与构建队列卡住的处理EAS免费层有构建时间和并发数限制构建任务排队时间过长或者一直停在某个阶段是使用过程中比较常见的问题。首先要分清是“任务没被调度”还是“构建进行中”。我自己的排查顺序登录EAS网页后台查看当前构建队列的任务状态。如果任务一直显示queued大概率是免费层并发已达到上限或者在云端资源高峰期排队。等一会儿通常能恢复。如果任务显示in progress但很久没变化可以打开构建日志看卡在哪一步。常见卡点包括依赖下载慢、CocoaPods安装慢、或者某个环境配置错误导致脚本挂起。确认代码没问题之后实在不行就取消这次构建重新发起一次很多时候第二次能成功。4.3 构建缓存问题带来的诡异报错EAS Build为了提速默认会启用缓存机制。这本来是好事但它偶尔也会带来一些“幽灵问题”比如你明明更新了某个原生依赖构建日志里却显示用的还是旧版本或者某些编译产物残留导致代码变更没有生效。遇到这种情况优先尝试清理缓存重新构建。EAS提供了缓存清理参数eas build --platform android --profile development --clear-cache--clear-cache会让云端清理依赖缓存和编译缓存强制重新拉取依赖。我遇到过本地一切正常、一上云端构建就报resource找不到错误的情况最终是加了这个参数重新构建解决的。日常规律是当构建环境相关的问题无法用常规手段排查时先清缓存重试一遍大概率会省掉很多无谓的日志翻找。4.4 常见问题速查表整理一张平时用得比较多的排查速查表现象可能原因推荐处理方案提示项目未关联EAS未执行项目关联命令执行eas init重新关联Android构建报签名失败签名信息缺失或与云端不一致运行eas credentials --platform android检查签名配置iOS提交商店总是卡在登录Apple双重认证或登录态失效换时间段重试确保使用有上架权限的Apple账号构建成功但安装后无法启动原生依赖与Expo版本不兼容检查expo-doctor输出对齐依赖版本测试包版本号一直不更新未开启版本号自动递增在eas.json对应profile设置autoIncrement: true环境变量在构建中读不到变量作用域或profile配置错误检查env字段或EAS后台环境变量绑定范围4.5 与Expo开发服务器相关的联调细节用EAS做完development构建不太容易绕开的一个环节是和本地开发服务器联调。这个阶段踩坑最多的是网络配置。手机上安装了development构建包之后打开它会自动搜索相同局域网内的开发服务器但有些办公网络会开启AP隔离导致手机和电脑虽然连的是同一个Wi-Fi却互相访问不到。遇到这种情况可以检查一下开发服务器的终端输出确认它监听的IP是否对局域网开放。如果不行考虑用USB连接手机并开启USB调试通过adb反向端口映射来解决但这属于备用方案。日常开发如果不涉及原生模块调试直接用Expo Go也很舒服没必要每次都用development构建省去联调环节的无效折腾。5. 扩展玩法EAS Update实现免审核更新前面主要围绕Build和Submit最后聊一个我很推荐的功能EAS Update。它解决的核心痛点是应用上线后需要频繁发布小改动但走应用商店的审核流程太慢了。EAS Update和EAS Build的channel字段天然配合。生产环境的应用在构建时指定channel: production那么它运行后就会监听production通道的更新。当你修复了一个Bug或者改了样式在本地执行eas update --channel productionEAS会把当前项目的JavaScript bundle和资源上传到云端更新服务已经安装的应用下次启动时就会静默拉取新版本。因为被替换的是JS和资源不涉及原生代码所以不需要重新提交到应用商店。这种检测和更新策略非常适合活动页面调整、文案修改这类轻量场景。不过需要留意的是EAS Update不是万能的。如果你改了原生模块、升级了原生依赖版本就必须走完整的构建流程重新发版更新补丁覆盖不了原生层面的变化。所以我的用法是能用Update解决的用Update涉及原生的就老老实实走EAS Build再Submit各司其职不必强行用一个替代另一个。回过头来看把整个打包流程迁移到EAS之后最大的收益不是“省了本地空间”这种小事而是构建这件事的确定性变高了。在本地打包时环境差异导致的错误五花八门而且往往只有你会碰到切到云端之后环境由EAS统一管理人人都用同一套规则出问题时的排查路径也清晰了很多。我个人在实际操作中最深的体会是不要一上来就追求把所有模式都配全先用development模式把一个平台跑通理解eas.json里每个字段的语义再逐步把preview和production加进来稳妥得多。最后再分享一个小技巧每次构建后养成拖回构建日志的习惯哪怕构建成功了也大致扫一眼时间长了你就会对这些环节的耗时和隐患形成直觉排查问题会快很多。