Expo:用 React 写一次,跑遍三端的开源框架,它的边界在哪里
用 React 与 JavaScript 构建通用原生应用的框架,同一应用可运行于 Android、iOS 与 Web,内含 SDK、Modules API、CLI 与路由器。
秒懂
- 它是什么?
- Expo 是一个让开发者用 React 和 JavaScript 构建 Android、iOS 和 Web 应用的开放源码框架。本文基于其 README 和仓库结构,分析它的核心机制、上手方式,以及它在原生模块定制上的局限。
- 适合谁用?
- Expo 适合那些希望用单一 React 代码库快速覆盖 iOS、Android 和 Web 的团队,尤其是原型验证、内部工具或对原生功能依赖不深的项目。它不适合需要深度定制原生代码、依赖大量私有原生模块或必须完全掌控原生构建流程的应用。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库在最近一天内有新的提交。
- 用什么语言写的?
- 主要是 TypeScript(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是 React Native 的碎片化问题
Expo 解决的问题很具体:用 React 写原生应用时,开发者需要自己处理原生模块的链接、配置和构建。Expo 把这一整套流程封装成统一的 SDK、CLI 和运行时。它的 README 明确说,目标是让开发者用 React 和 JavaScript 构建原生应用,同时支持 Android、iOS 和 Web。这不是一个 UI 组件库,而是一个平台,它包含了从创建项目到打包上线的完整工具链。对于个人开发者或小团队来说,它省去了配置 Xcode 和 Android Studio 的大量时间。
仓库里藏着它的真实架构
从仓库布局看,Expo 不是一个单体项目。packages 目录存放所有 Expo 模块的源码,apps 目录是链接到这些模块的开发项目,其中 apps/expo-go 是 Expo Go 应用的源码。react-native-lab 目录是专门为 Expo Go 构建的 react-native 分支,这个细节很关键,它说明 Expo Go 运行时并不完全等同于标准 React Native。docs 目录是文档站点的源码,templates 目录是 create-expo-app 生成的模板项目。这种结构意味着,如果你想修改某个模块的行为,你需要进入 packages 目录,而测试则需要在 apps 目录中进行。它还包含 tools 和 template-files 目录,后者存放需要私钥的文件模板,这暗示了构建过程涉及密钥管理。
上手:一条命令,一个模板
README 没有给出完整的安装命令,但提到了 npx create-expo-app 是创建项目的入口,模板项目位于 templates 目录。文档链接指向 docs.expo.dev,其中包含“开始使用”和“API 参考”。根据仓库结构,你可以推断出基本流程:运行 create-expo-app 生成项目,然后用 Expo CLI 启动开发服务器,在 Expo Go 应用中预览。README 提到,Expo Go 应用可以在浏览器中通过 snack.expo.dev 体验,这降低了试错成本。但要注意,模板项目只是起点,实际的模块配置在 packages 目录中,你需要通过文档了解具体的配置键,例如 app.json 中的设置,但 README 本身没有列出这些细节。
Expo Go 的便利与它的隐藏成本
Expo Go 是一个可以在手机上直接运行 Expo 项目的应用,它让开发者免去了本地编译原生代码的步骤。但 react-native-lab 目录揭示了代价:Expo Go 使用的是 fork 过的 react-native 分支,这意味着它可能不会立即支持 React Native 的最新版本。另一个限制是,Expo Go 只能运行纯 JavaScript 模块,任何需要自定义原生代码的功能都无法在 Expo Go 中测试。README 的“使用自定义原生模块”链接暗示了这一点,它指向文档中的“自定义”部分。如果你需要集成一个没有对应 Expo 模块的原生 SDK,你就必须离开 Expo Go 的舒适区,转而使用开发构建。这个转换过程并不轻松,因为你需要管理 Xcode 或 Android Studio 项目。
EAS:开源与托管服务的分界线
README 明确区分了 Expo 开源项目和 EAS,即 Expo Application Services。EAS 是托管服务,提供构建、发布和迭代功能,它与开源工具深度集成。这意味着,你可以在本地使用 Expo CLI 开发,但如果你需要云构建或自动签名,你就得依赖 EAS。这不是一个隐藏的坑,而是一个设计选择:开源部分免费,但便利的托管服务需要付费。对于预算有限的团队,这可能是一个问题,因为你可能需要自己搭建 CI/CD 来处理构建和签名。但另一方面,如果你不想维护自己的构建基础设施,EAS 的价值是实在的。
替代方案:React Native CLI 与原生开发的取舍
与 Expo 最直接的对比是 React Native CLI,即不使用 Expo 的纯 React Native 项目。React Native CLI 让你完全控制原生代码,你可以在项目中自由添加 Swift、Kotlin 或 Java 文件。而 Expo 则抽象了这些,你只能通过 Expo 模块 API 来访问原生功能。这导致了一个核心差异:React Native CLI 的灵活性更高,但你也需要自己处理依赖链接和构建配置。Expo 则牺牲了这种灵活性,换来了开箱即用的体验。如果你的项目需要频繁修改原生代码,React Native CLI 是更合适的选择。但如果你只是需要跨平台的标准 UI 和常见 API,Expo 的效率优势明显。
维护与升级:MIT 许可下的双刃剑
Expo 采用 MIT 许可证,这对商业项目友好,你可以在自己的应用中自由使用和修改源码。但许可证不覆盖所有依赖,README 提到一些依赖使用 BSD 等不同的许可证,这意味着你需要检查每个依赖的条款。维护成本方面,Expo 的更新节奏由 SDK 版本驱动,每个版本可能引入破坏性变更。仓库结构显示,模块代码集中在 packages 目录,这有利于统一更新,但也意味着升级时你需要关注所有模块的兼容性。文档站点的存在表明官方重视版本文档,但你没有本地运行过,无法验证其完整性。建议在升级前查看 docs.expo.dev 的版本日志。
编辑结论
Expo 适合那些希望用单一 React 代码库快速覆盖 iOS、Android 和 Web 的团队,尤其是原型验证、内部工具或对原生功能依赖不深的项目。它不适合需要深度定制原生代码、依赖大量私有原生模块或必须完全掌控原生构建流程的应用。在采用前,先确认你的核心需求是否落在 Expo SDK 和 EAS 覆盖范围内,并检查目标平台所需的原生 API 是否已有对应模块。若需要自定义原生代码,务必提前阅读文档中的“使用自定义原生模块”指南,并评估从 Expo Go 切换到开发构建的复杂度。最终,Expo 的价值在于它把跨平台开发的复杂性集中到一套工具链中,但这也意味着你必须接受它的抽象边界。
社区笔记