在 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 bundle、pnpm install、pnpm 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.json的workspaces配置管理apps/*、packages/*等子包。
2.2pnpm setup:native到底做了什么
根 package.json 中定义:
"setup:native": "./scripts/download-dependencies.sh --native && ./scripts/setup-react-android.sh"查看 scripts/download-dependencies.sh 可知,该脚本会:
- 检查
node、npm、direnv三个命令是否存在,缺失则直接报错退出——这就是文档要求先安装 direnv 的原因; - 执行
git submodule update --init初始化所有子模块,并对每个子模块执行git checkout .恢复干净状态(React Native 就是以 Git 子模块形式存在的,见下节); --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-26、build-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 的某个稳定发布版本,并叠加少量待上游合并的提交。
对应文档构建步骤:
- 在 monorepo 根目录执行
pnpm install:react-native-lab(等价于进入react-native-lab/react-native执行yarn install)。根 package.json 中该脚本的实现带有空目录保护:若子模块目录为空则跳过并提示,因此必须先完成--recurse-submodules克隆或git submodule update --init,否则这一步会被静默跳过。 - (可选)在
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 { ... }块将reactNativeDir与codegenDir指向../../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作为applicationId与namespace,应用名版本号为 Expo Go 客户端版本(versionName '56.0.1',versionCode 229),并通过flavorDimensions += "device"声明了mobile与quest(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/home,private: true)声明了对几十个workspace:*模块的依赖,如expo-camera、expo-location、expo-updates、expo-sqlite等,以及react-native 0.87.0、react 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-shot、react-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)
文档给出了三级递进的排障方案,此处完整保留并补充脚本级说明:
C++ 相关编译错误:清理 CMake 构建产物缓存
.cxx:find . -name ".cxx" -type d -prune -exec rm -rf '{}' +Android 构建异常:先尝试干净构建,在
apps/expo-go/android目录执行./gradlew clean后重新编译。"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.json | Expo Go 的 JS 依赖与 autolinking 配置 |
| apps/expo-go/sdkVersions.json | 当前 Expo Go 对应 SDK 版本(57.0.0) |
| apps/expo-go/android/app/build.gradle | Android 构建脚本,含 react-native-lab 路径引用 |
| apps/expo-go/ios/Exponent.xcworkspace | iOS Xcode 工作区入口 |
| react-native-lab/README.md | React Native 子模块(fork)维护策略 |
| scripts/download-dependencies.sh | 子模块初始化与依赖安装(--native/--docs) |
| scripts/setup-react-android.sh | Android SDK/NDK/平台工具自动安装 |
| apps/native-component-list | 用于验证构建产物的组件演示应用 |
| apps/bare-expo | SDK 贡献者的开发测试应用(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),仅供参考