
Expo 开源仓库贡献指南从环境搭建、SDK 包编辑到测试与文档的完整贡献流程【免费下载链接】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 仓库根目录的 CONTRIBUTING.md 编写面向希望向 Expo SDK 提交代码的外部贡献者与团队成员。文章完整覆盖仓库贡献的各个环节开发环境搭建direnv、Ruby、JDK、ccache 等、基于apps/bare-expo沙盒项目的 SDK 包编辑工作流、单元测试与 E2E 测试的编写与运行、文档更新规则以及提交前的检查清单并结合仓库源码补充了各命令背后的实际实现。贡献范围与开发工作流的核心选型Expo 仓库目前接受针对packages/、docs/、templates/、guides/、apps/目录以及 markdown 文件的 PR。整个仓库是一个 pnpm workspace 单仓monorepo根目录 package.json 通过workspaces.packages声明了apps/*、packages/*、packages/expo/*等工作区成员并用 Turborepo根目录 turbo.json统一编排build、typecheck、lint、test等任务且配置了共享远程缓存turbo.json中的remoteCache段因此git pull或切换分支后通常不需要从头重新编译每个包。关键选型SDK 开发请使用apps/bare-expo而不是 Expo Goapps/expo-go。原因有两点Expo Go 应用本身较难搭建且依赖 API tokenapps/bare-expo 项目链接了packages/目录下的绝大部分 Expo SDK 依赖能够直接运行 apps/test-suite 与 apps/native-component-list 两个测试/演示应用方便浏览 SDK 组件与 API、为任意 SDK 包编写并运行 iOS / Android 的 E2E 测试。单元测试则直接写在 SDK 包内部。代码推送到远端后CI 会运行该项目并在 Android/iOS 上执行测试结果回显到你的 PR 上。二者的关系是bare-expo是一个 bare React Native 应用为了能够运行apps/目录下的项目它链接了packages/下的全部 Expo SDK 依赖它导入test-suite应用的根组件并作为自己的根组件使用。test-suite是一个带有少量自定义代码的 Expo 应用被改造成了测试运行器test runner如果在apps/test-suite目录里直接运行expo start也可以把该项目加载到 Expo Go 中。此外apps/native-component-list 中内置了大量人工冒烟测试manual smoke tests非常适合需要真机物理交互的演示或测试场景——当你测试 UI 组件交互、或者某个行为很难自动化但手动交互即可验证时它是首选工具。下载与基础环境搭建注意本仓库的开发环境不支持 WindowsWindows 用户必须使用 WSL 进行贡献。基础步骤如下原文档的完整步骤序列获取代码。Expo 团队成员直接克隆仓库外部贡献者先将仓库 fork 到自己的账号再克隆到本地并添加上游远端git remote add upstream gitgithub.com:expo/expo.git。若希望加速克隆可用git clone --depth 1 --single-branch --branch main gitgithub.com:expo/expo.git跳过大部分分支与历史。安装 direnv。macOS 上执行brew install direnv并记得把 shell hook 安装到你的 shell profile 中。direnv 对本仓库尤为重要根目录 .envrc 会在进入仓库时自动加载环境其中PATH_add bin把仓库根下的bin/加入 PATHet等工具即来自这里导出EXPO_USE_SOURCE1强制所有 Expo 模块从源码编译设置CCACHE_BASEDIR为当前目录使 ccache 缓存可跨 git worktree 共享见下文 Android 加速节校验 Ruby 版本use_ruby 3.3 3.4 4.0不在允许列表内会直接报错退出从secrets/expotools.env加载 expotools 密钥如存在并安装 scripts/git-hooks 下的 Git hooks。安装 Ruby 3.3 或更高版本。macOS 自带的是 ruby 2.6本仓库不支持可用brew install ruby3.3。安装 Node LTS。部分脚本需要 Bun。大多数任务用不到可按需安装。Android 环境配置如果计划贡献 Android 相关代码在仓库根目录运行pnpm run setup:native从根 package.json 可见该脚本实际是./scripts/download-dependencies.sh --native ./scripts/setup-react-android.sh的组合。查看 scripts/download-dependencies.sh 可知它依次完成前置检查 node、npm、direnv 是否安装缺失则报错退出git submodule update --init拉取react-native等子模块确保 pnpm 已安装缺失时通过npm install -g pnpm补装执行pnpm install下载全部 Node 依赖并确保你的电脑满足 React Native 环境要求如缺失会安装 Android NDK。JDK推荐使用 JDK 17如 zulu17brew tap homebrew/cask-versions brew install --cask zulu17安装后在~/.bash_profileZSH 用户为~/.zshrc中设置export JAVA_HOME/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/HomeANDROID_SDK_ROOT需要被设置或者在你所操作的 native 项目的android文件夹下通过local.properties配置。可选用 ccache 加速 Android 原生构建ccache 缓存 C/C 编译结果当源码文件未变化时原生代码的重建几乎是瞬时的。配置步骤安装brew install ccache在~/.zshrc或~/.bashrc中添加export CMAKE_C_COMPILER_LAUNCHERccache export CMAKE_CXX_COMPILER_LAUNCHERccache启用预编译头precompiled header支持expo-modules-core等模块需要ccache -o sloppinesspch_defines,time_macros仓库的 .envrc 会通过 direnv 自动设置CCACHE_BASEDIR因此无需额外配置即可在多个 git worktree 之间共享缓存。iOS 环境配置如果你要开发 iOS 项目确保机器上安装了Ruby 3.3macOS 自带的 ruby 2.6 不受支持Homebrew 用户执行brew install ruby3.3安装最新稳定版 Xcode 及 Xcode 命令行工具command line tools。验证原生安装是否成功进入 bare 沙盒项目cd apps/bare-expo在任意原生平台上运行项目iOSpnpm iosAndroidpnpm android若在 Linux 上工作需把TERMINAL环境变量设置为你的终端应用例如export TERMINALkonsole。此时你运行的就是通过bare-expo承载的test-suite应用可以开始对 SDK 包进行改动。从 apps/bare-expo/package.json 可以看出这些脚本的真实形态ios与android均以NODE_ENVdevelopment调用 scripts/start-simulator.sh 或 scripts/start-emulator.sh而test:ios/test:android则切换为NODE_ENVtest。以start-simulator.sh为例开发模式下它会先执行setup-ios-project.sh再运行npx expo run:ios测试模式下则自动检测/安装 Maestro 与 idb-companion必要时先构建BareExpo.app然后执行 E2E 测试流程——这正是下文 E2E 测试章节的运行入口。若上述流程无法正常工作仓库建议开一个 issue 反馈。编辑 SDK 包所有 Expo SDK 包都位于packages/目录并且自动链接到apps/目录中的项目因此你可以原地编辑并立即在运行中的应用中看到变化。标准工作流进入要编辑的包例如cd packages/expo-constants编辑后编译包的 TypeScriptpnpm build若该包没有这个脚本可跳过在该包的src/目录中修改代码通过bare-expo在模拟器或真机上验证改动添加或修改一个以目标 API 命名的测试文件例如apps/test-suite/tests/Constants.js要验证原生native层改动需用apps/bare-expo工程运行test-suitepnpm android | ios如果只改了 JavaScript也可以直接在apps/test-suite项目中用expo start运行运行完整测试套件pnpm test:android | ios原生代码既可以在packages/目录下的对应包内直接编辑也可以打开bare-expo的原生工程cd apps/bare-expoAndroid Studiopnpm edit:androidXcodepnpm edit:ios任何原生改动之后必须重新构建rebuildnative 工程可选包的文档部分由源码生成运行et generate-docs-api-data -p package-name重新生成文档et是仓库内 tools 目录提供的 expotools CLI对应实现见 tools/src/commands/GenerateDocsAPIData.ts。以 packages/expo-constants/package.json 为例可以看到build脚本实际是expo-build srcdepscheck是expo-module depschecklint使用 oxlint——这些统一行为来自下文提到的expo-module-scripts包。通用包脚本Common package scriptspackages/下几乎每个包都暴露同一组 npm 脚本由 Turborepo 在 monorepo 层面统一编排。编译产物build/不会提交到 Git在.gitignore中Turborepo 按需构建并本地 远程缓存结果避免git pull/git checkout后被迫重建所有包。这与 turbo.json 中的任务定义一一对应build任务声明了build/**等输出产物并依赖上游包的^buildlint/format/test则关闭缓存cache: false。脚本作用build编译src/→build/typecheck用tsc对包做类型检查test运行该包的 Jest 单元测试lint对该包做 lint可传--fix自动修复format格式化该包可传--check只检查不修改depscheck校验包声明的依赖与其实际 import 是否一致两种运行方式从仓库根目录pnpm script如pnpm build、pnpm test、pnpm lint、pnpm format、pnpm typecheck。这会触发turbo task在整个工作区范围内按依赖图和缓存运行脚本从单个包目录pnpm run script如cd packages/expo-constants pnpm run test只运行该包的脚本。对于“我的改动是否通过了构建、类型检查、lint 和测试”的一次性验证跨包使用et check-packages ...packages实现见 tools/src/commands/CheckPackages.ts它运行与 CI 相同的 Turborepo 任务图。如何找到可做的任务如果你暂时没有目标最好的入手点是带有 Issue accepted 标签的 open issues。另外注意仓库一般不接受仅升级原生依赖版本的 PR——这类升级由 Expo 团队在每个 SDK 版本发布流程中统一处理因为引入新版本需要了解相当多的 Expo Go 上下文。代码风格所有模块应遵循以下风格指南Expo Module InfrastructureExpo JS Style Guide大部分规则同样适用于 TypeScriptExpo Swift Style GuideUpdating Changelogs进阶提示Extra CreditReact Native dev tools 目前在仓库的 RN fork 中处于禁用状态对应 issue #5602。可以克隆一份独立于本仓库的 React Native把其react-native/React/DevSupport目录内容复制到react-native-lab/react-native/React/DevSupportbare-expo的 package.json 中也提供了sync:tools脚本做类似同步。这样只能启用 shake 手势CMDR 暂时仍不可用。仓库使用的是react-native的 fork位于 react-native-lab/react-native通过 git submodule 拉取。你可以在这里做修改或 cherry-pick该 fork 与package.json中的react-native版本只保持最小必要的偏离。仓库使用一套统一的基础 Bash 脚本与配置 expo-module-scripts保证 TypeScript、Babel、Jest 等工具链在所有包中行为一致。测试你的改动PR 的Test Plan部分需要写清楚你如何测试了你的改动。让改动被合并的最好方式就是为它构建良好的测试。仓库有三类测试单元测试、自动化 E2E 测试、演示demo。补上你发现的缺失测试是快速熟悉项目的好方式。单元测试在对应包的src/__tests__目录中为功能创建测试若目录不存在就创建文件扩展名使用*-test.ts或*-test.tsx。所有新增的桥接bridged原生函数必须加入 jest-expo 包以确保被 mock。仓库为此提供了专门的工具和指南Generating Jest Mocks。用pnpm test运行测试并确保覆盖 iOS、Android 和 web 各平台。若某功能不支持某平台可将测试放入带平台扩展名的文件中排除例如.test.ios.ts、.test.native.ts、.test.web.ts等。也可以按住X选择要单独测试的平台逐个平台运行。E2E 测试把测试写在apps/test-suite/tests目录中这些测试运行在 Android/iOS 客户端上基于一个功能并不完整的 Jasmine 版本因此快照测试等特殊功能不可用新建的测试文件务必在 apps/test-suite/TestModules.ts 中注册应用才能运行它测试辅助函数位于 apps/test-suite/TestUtils.js若新测试文件应能从bare-expo自动化测试中自动运行将其加入 apps/bare-expo/e2e/TestSuite-test.native.js。从源码可以看到该文件导出一个TESTS名称数组如Constants、Crypto、SQLite等Maestro 测试流程即由这份列表生成添加或移除条目即可同时该测试必须在TestModules.ts中注册。在bare-expo目录本地运行pnpm test:android或pnpm test:ios。务必本地先测native CI 测试可能脆弱、耗时长失败时排查也很麻烦。尽量让功能在尽可能多的平台上运行。更新文档Expo 文档基于 Next.js 构建位于 docs 目录更多细节见 docs/README.md。要点TL;DR运行 docs 的 pnpm 命令要求特定版本的 Node该版本定义在 docs/package.json 的packageManager/engines字段中当前仓库要求 Node 22.13.1 及以上且 docs 包本身声明了更高的 Node 版本要求以该文件为准。操作步骤进入docs目录并运行pnpm install用pnpm dev启动项目确保没有其他服务占用3002端口——dev脚本即为next dev -p 3002并先执行generate-static-resources进入要编辑的文档cd docs/pages/如果你更新的是某个旧版本确保对应的 API 文档改动被拷贝到docs/pages/versions/unversioned/包的 API 文档由源码生成。重新生成et generate-docs-api-data -p package-name面向下一个 SDK 版本或et generate-docs-api-data -p package-name -s number面向指定 SDK 版本。编写 Commit MessageCommit message 最有用的格式是[platform][api] Title。例如修复了expo-video包在 iOS 上的一个 bug可以写[ios][video] Fixed black screen bug that appears on older devices提交前检查清单记得在改动的包的CHANGELOG.md中为任何用户可见的改动添加简明描述若改动不涉及任何包则写入 根目录 CHANGELOG.md。这对破坏性变更breaking changes尤其重要。改动了packages/中的内容时对你改动的包运行et check-packages ...packages等价于pnpm build、pnpm typecheck、pnpm test、pnpm lint、pnpm format参见上文通用包脚本运行pnpm lint --fix和pnpm format修复代码格式并确认两个命令都能无错误、无警告地通过可选包的文档部分由源码生成运行et generate-docs-api-data -p package-name重新生成文档删除所有console.log和被注释掉的代码块。编辑了 docs 目录时针对当前 SDK 版本的文档改动必须同步到 unversioned 副本。当前文档 SDK 版本定义在 docs/package.json 中版本化工作流描述在 docs/README.md。示例你修复了docs/pages/versions/vXX.0.0/sdk/app-auth.md中的拼写错误则需确保把该改动同步到docs/pages/versions/unversioned/sdk/app-auth.md。无需本地运行 docs 测试。只需确保你加入的链接没有断链、格式正确并且改动符合 Expo Documentation Writing Style Guide。提速技巧Extra CreditCI 测试在你未改动某些目录时会提前结束。如果你想更快拿到结果应该把docs目录的改动单独放在一个 PR 中其余改动放在另一个 PR 中。【免费下载链接】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),仅供参考