news 2026/9/7 14:24:53

在 Expo 仓库中从源码构建 Expo Go:开发环境配置、Android/iOS 编译与 Native Component List 验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Expo 仓库中从源码构建 Expo Go:开发环境配置、Android/iOS 编译与 Native Component List 验证

在 Expo 仓库中从源码构建 Expo Go:开发环境配置、Android/iOS 编译与 Native Component List 验证

【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo

本文基于 Expo 官方 monorepo 中的 Expo Go 开发指南,系统讲解从源码构建 Expo Go 客户端的完整流程:macOS 开发环境如何配置、pnpm setup:native等关键脚本背后的实际行为、Android 与 iOS 两端的具体编译命令,以及如何用 Native Component List 应用验证所构建客户端与 Expo SDK 各模块(workspace 依赖)的联动。读完后,你可以独立搭建 Expo Go 的源码开发环境、定位并解决常见的 C++/缓存构建问题。

一、先判断你是否真的需要构建 Expo Go

官方文档在开篇就给出了明确的分流指引:如果你只是想安装 Expo Go 到模拟器或真机上,无需从源码构建,直接通过 Expo 官方渠道安装即可;只有当你需要开发 Expo Go 本身时,才需要按本文流程操作。

此外文档对贡献者给出了两条边界建议:

  • Expo SDK 的贡献者:开发、测试 SDK 模块改动时应使用仓库中的 Bare Expo 应用(apps/bare-expo),除非你的改动是 Expo Go 应用自身特有的。
  • 普通应用开发者:如果你要构建带自定义图标和名称的独立应用,应使用 EAS Build;如果你需要在 Expo 项目中添加自定义原生模块等原生代码,应创建 development build。这两种场景都不需要构建 Expo Go。

文档同时提醒:向 Expo Go 提交 Pull Request 之前,请先与 Expo 团队沟通,避免重复投入。

一个重要的前提限制:官方仅支持在 macOS 上构建 Expo Go

二、环境配置:官方六步流程与脚本内部行为

文档给出的环境配置步骤为:安装 direnv 与 Homebrew → 克隆仓库(git clone --recurse-submodules,且推荐克隆到完整路径中不含空格的目录)→ 在根目录执行brew bundlepnpm installpnpm setup:native→ 在packages/expo目录执行pnpm build

下面结合仓库源码说明每一步的真实行为与适用前提。

2.1 版本约束

根目录 package.json 的engines字段声明了本仓库的运行时要求:Node.js^22.13.0 || ^24.3.0 || ^26.0.0 || >=27.0.0,pnpm^10.33.0。环境搭建前需先满足这两个版本约束。工作区通过pnpm-workspace.yaml与根package.jsonworkspaces配置管理apps/*packages/*等子包。

2.2pnpm setup:native到底做了什么

根 package.json 中定义:

"setup:native": "./scripts/download-dependencies.sh --native && ./scripts/setup-react-android.sh"

查看 scripts/download-dependencies.sh 可知,该脚本会:

  1. 检查nodenpmdirenv三个命令是否存在,缺失则直接报错退出——这就是文档要求先安装 direnv 的原因;
  2. 执行git submodule update --init初始化所有子模块,并对每个子模块执行git checkout .恢复干净状态(React Native 就是以 Git 子模块形式存在的,见下节);
  3. --native分支下检查 pnpm(缺失时通过npm install -g pnpm全局安装),然后执行pnpm install

而 scripts/setup-react-android.sh 负责 Android 工具链:它要求sdkmanager在 PATH 中(或可通过ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager找到),随后自动接受 Google 许可协议,并依次安装 emulator、NDK21.4.7075529、platform-tools、HAXM、platforms;android-26build-tools;26.0.3等组件。因此执行该脚本前需要先通过 Android Studio 装好 Android SDK 命令行工具。

2.3 根目录其他常用脚本

脚本行为(见根 package.json)
pnpm install:react-native-lab为 React Native 子模块目录安装 Node 依赖并构建 codegen(详见下节)
pnpm build执行turbo build,增量构建各工作区包
pnpm setup:docs./scripts/download-dependencies.sh --docs,仅初始化docs/文档站依赖

三、React Native 实验室:构建 Expo Go 的前置依赖

Expo Go 并不直接使用 npm 上发布的 React Native,而是使用仓库内的react-native-lab。react-native-lab/README.md 说明:react-native-lab/react-native是一个指向 Expo 维护的 React Native 仓库的 Git 子模块,保持在最新的sdk-*分支上,该分支基于上游 React Native 的某个稳定发布版本,并叠加少量待上游合并的提交。

对应文档构建步骤:

  1. 在 monorepo 根目录执行pnpm install:react-native-lab(等价于进入react-native-lab/react-native执行yarn install)。根 package.json 中该脚本的实现带有空目录保护:若子模块目录为空则跳过并提示,因此必须先完成--recurse-submodules克隆或git submodule update --init,否则这一步会被静默跳过。
  2. (可选)在react-native-lab/react-native目录执行./gradlew :packages:react-native:ReactAndroid:buildCMakeDebug预构建 React Native Android 依赖。文档指出这属于可选项,因为构建 Expo Go 时 RN 终归会被编译,但预构建有助于缩小潜在问题的排查范围。

Expo Go 的 Android 工程通过 Gradle 配置直接引用该子模块:apps/expo-go/android/app/build.gradle 中的react { ... }块将reactNativeDircodegenDir指向../../react-native-lab/react-native/packages/...,并配置debuggableVariants覆盖mobileDebug/mobileRelease/questDebug/questRelease四个变体——由于 Expo Go 的 JS 包由 Metro 在运行时提供而非编译期嵌入,所有变体都被标记为 debuggable。

四、编译 Expo Go

4.1 Android

apps/expo-go/android目录执行:

./gradlew app:assembleDebug

该工程(见 apps/expo-go/android/app/build.gradle)使用host.exp.exponent作为applicationIdnamespace,应用名版本号为 Expo Go 客户端版本(versionName '56.0.1'versionCode 229),并通过flavorDimensions += "device"声明了mobilequest(Meta Quest 平台)两个产品风味。当前仓库的 apps/expo-go/sdkVersions.json 声明的 SDK 版本为57.0.0,即该源码构建对应 Expo SDK 57 的 UNVERSIONED 开发态。

4.2 iOS

apps/expo-go/ios目录执行:

pod install

然后用 Xcode 打开并运行ios/Exponent.xcworkspace(对应 apps/expo-go/ios/Exponent.xcworkspace)。iOS 工程目录 apps/expo-go/ios 包含Exponent主 target、ExpoNotificationServiceExtension通知服务扩展、ExponentIntegrationTests集成测试等,注意必须打开.xcworkspace而非.xcodeproj,否则 CocoaPods 依赖无法被正确解析。

4.3 Expo Go 的模块依赖结构

Expo Go 自身作为工作区包 apps/expo-go/package.json(包名@expo/homeprivate: true)声明了对几十个workspace:*模块的依赖,如expo-cameraexpo-locationexpo-updatesexpo-sqlite等,以及react-native 0.87.0react 19.2.3。两个细节值得注意:

  • expo.autolinking.searchPaths配置了../../react-native-lab/react-native/packages./node_modules../../node_modules三个搜索路径,并 exclude 自身(@expo/home),这正是原生侧能从子模块而非 npm 包中解析 React Native 的关键;
  • apps/expo-go/modules 目录存放 Expo Govendored的原生模块(如react-native-view-shotreact-native-webview@react-native-async-storage/async-storage)。按 modules/README.md 的说明,这些模块会被打补丁应用 Expo Go 特有改动,更新时通过工具脚本(如et uvm <module> -c <version>)拉取指定版本并重新应用补丁。

五、验证构建产物:运行 Native Component List

构建完成后,文档建议通过 Native Component List 应用验证 Expo Go 与各 Expo 模块的联通性:

cd apps/native-component-list EXPO_SDK_VERSION=UNVERSIONED npx expo start --clear

随后用你刚刚构建出的 Expo Go 应用扫描终端中的二维码打开该应用,或在 Metro 终端窗口按i/a快捷键在 iOS 模拟器 / Android 模拟器中打开。EXPO_SDK_VERSION=UNVERSIONED表示使用当前源码树中未发版的 SDK 实现,而不是某个已发布 SDK 版本的 API 面——这是开发态验证的核心开关。

apps/native-component-list 内含约数百个src/下的组件演示页面(*.tsx),覆盖相机、定位、传感器、存储等各个模块,是端到端排查"客户端构建是否正常、某模块是否可用"的高价值入口。

六、故障排查(Troubleshooting)

文档给出了三级递进的排障方案,此处完整保留并补充脚本级说明:

  1. C++ 相关编译错误:清理 CMake 构建产物缓存.cxx

    find . -name ".cxx" -type d -prune -exec rm -rf '{}' +
  2. Android 构建异常:先尝试干净构建,在apps/expo-go/android目录执行./gradlew clean后重新编译。

  3. "nuke" 核弹方案git submodule foreach --recursive git clean -xfd以及git clean -xfd,删除全部未跟踪文件。由于这会同时清掉各子模块内未跟踪内容,之后需要重新执行依赖下载脚本 scripts/download-dependencies.sh(即重跑pnpm setup:native前半段),构建耗时也会相应变长,但官方确认该方案有效,适合作为最后的兜底手段。

七、相关文件索引

文件/目录作用
apps/expo-go/README.md本文主体:Expo Go 源码开发指南
apps/expo-go/package.jsonExpo Go 的 JS 依赖与 autolinking 配置
apps/expo-go/sdkVersions.json当前 Expo Go 对应 SDK 版本(57.0.0)
apps/expo-go/android/app/build.gradleAndroid 构建脚本,含 react-native-lab 路径引用
apps/expo-go/ios/Exponent.xcworkspaceiOS Xcode 工作区入口
react-native-lab/README.mdReact Native 子模块(fork)维护策略
scripts/download-dependencies.sh子模块初始化与依赖安装(--native/--docs
scripts/setup-react-android.shAndroid SDK/NDK/平台工具自动安装
apps/native-component-list用于验证构建产物的组件演示应用
apps/bare-expoSDK 贡献者的开发测试应用(Expo Go 的替代入口)

适用前提小结:本文所有命令均以当前仓库实际内容为准,要求 macOS 系统、满足根package.json声明的 Node/pnpm 版本、已完成含子模块的仓库克隆;Android 侧还需预装 Android SDK 命令行工具链。iOS 侧依赖 CocoaPods(pod install)与 Xcode。

【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 14:24:16

游戏实况长对局录制指南:从服务器搭建到低光优化与FFmpeg切片

在“秘密实验室”这类以黑暗环境、多人对抗和长时间生存为主要玩法的游戏里&#xff0c;做一场超长对局实况&#xff0c;真正的难点往往不是操作&#xff0c;而是“录得完、看得清、找得到”。常见情况是&#xff1a;对局推进到七十多回合&#xff0c;室内灯光突然熄灭&#xf…

作者头像 李华
网站建设 2026/9/7 14:24:02

中序遍历与虚函数表:递归栈和动态多态的实现原理

1. 栈、虚表、递归&#xff1a;两个概念为什么值得放在一起嚼 我这篇笔记编号是 1.16&#xff0c;内容看起来有点分裂&#xff1a;前半部分是二叉树中的中序遍历&#xff0c;后半部分是动态多态的实现原理。但那天晚上我其实是把两段代码分别追进汇编之后&#xff0c;才意识到它…

作者头像 李华
网站建设 2026/9/7 14:21:10

嵌入式软硬件一体化:3-5人小团队如何高效落地产品开发

1. 到底什么样的团队才算“软硬件一体化成熟” 1.1 标题说“成熟”&#xff0c;到底在说什么 这几年和不少做智能硬件、工业设备、车载终端的朋友聊下来&#xff0c;发现大家最头疼的其实不是找不到人&#xff0c;而是找到的人凑不成一个能打的团队。单看简历&#xff0c;硬件…

作者头像 李华
网站建设 2026/9/7 14:20:46

书霸AI实践报告:从填表到复盘

写实践报告时&#xff0c;最容易出现的问题不是“写不出来”&#xff0c;而是信息不完整、过程不清楚、内容像流水账。书霸AI的实践报告功能&#xff0c;可以把写作拆成几个明确步骤&#xff0c;适合用来整理实习经历、岗位任务和阶段成果。下面用一份清单&#xff0c;梳理从填…

作者头像 李华
网站建设 2026/9/7 14:18:42

猫抓浏览器资源嗅探扩展:网页视频下载完整指南

猫抓浏览器资源嗅探扩展&#xff1a;网页视频下载完整指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 在视频网站上看到想保留的一段内容&…

作者头像 李华
网站建设 2026/9/7 14:17:24

Mask R-CNN结合TensorFlow与Keras实现矿物图像实例分割实战

简介&#xff1a;面向人工智能、深度学习方向的开发者以及地质矿物研究人员&#xff0c;该项目提供了一套基于Mask R-CNN的显微矿物图像检测与分割实现&#xff0c;使用TensorFlow和Keras框架搭建。该模型在Faster R-CNN基础上扩展出掩模分支&#xff0c;可同步完成目标边界框回…

作者头像 李华