将 Expo 工具集成到现有的原生应用中

关于如何将 Expo 工具集成到现有原生应用(“棕地”应用)中的概述。


使用其他技术构建的现有原生应用,其主要入口点不是 React Native 视图,通常被称为“棕地”应用。例如,如果你的应用是使用 UIKit 和 Swift 构建的,并且你想在其中使用 React Native 实现单个屏幕,那么这被视为“现有原生应用”和“棕地”。

🌐 An existing native app that was built using another technology, whose main entry point is not a React Native view, is commonly referred to as a "brownfield" app. For example, if your app was built using UIKit and Swift, and you want to use React Native for a single screen then that is considered an "existing native app" and "brownfield".

相比之下,“新建”应用是从一开始就使用 Expo 或 React Native 创建的,或者 React Native 是入口点,所有其他界面都由此分支。

🌐 In contrast, "greenfield" apps are created using Expo or React Native from the start or where React Native is the entry point and where all other UI branches off from.

根据这些定义,如果你有一个适用于 Android 或 iOS 的“现有原生应用”,并且你想学习如何在项目中使用 Expo 和 React Native(可能是在单个界面甚至单个功能上),那么本指南适合你。

🌐 By these definitions, if you have an "existing native app" for Android or iOS and you want to learn how to use Expo and React Native in your project (perhaps on a single screen or even a single feature), then this guide is for you.

与现有原生应用的兼容性

🌐 Compatibility with existing native apps

信息 将 Expo 模块集成到现有原生项目中的支持仍处于 Alpha 阶段。如果遇到问题,请在 GitHub 上创建一个问题。在现有原生应用的环境中使用时,以下工具和服务的所有功能可能无法完全使用。

Expo 主要是针对全新应用(greenfield apps)构建的,但我们正在逐步加大对已有项目(brownfield)场景的投入。并非所有 Expo 工具和服务都与现有的原生项目兼容。此外,针对已有项目的综合集成文档可能尚未提供,你可能需要将其他相关文档根据你的实际情况进行调整。

🌐 Expo is primarily built with greenfield apps in mind, but we are increasingly investing in brownfield scenarios. Not all Expo tools and services are compatible with existing native projects yet. Additionally, comprehensive documentation for brownfield integrations may not yet available, and you may need to adapt other related documentation to your context.

Tool/ServiceSupports brownfield?
Expo SDK - an extended standard library for React NativeYes
Expo Modules API - build native extensions using an idiomatic Swift/Kotlin APIYes
Expo Router - file-based routing and navigationYes
Expo CLI - tools to run and develop your app from your terminalYes
Expo Dev Client - adds in-app developer tooling to Debug buildsNo
EAS Build - a CI/CD service built specifically for Expo/React NativeYes
EAS Submit - a hosted service that uploads your app to storesYes
EAS Update - instant updates of your app JavaScript and assetsYes

综合方法与孤立方法

🌐 Integrated vs Isolated approaches

当你将 React Native 集成到现有的原生应用中时,你可以在两种主要方法之间进行选择:集成式和独立式。最适合你的方法取决于你的项目结构、团队的工作流程以及你的长期目标。

🌐 When you integrate React Native into an existing native app, you can choose between two main approaches: integrated and isolated. The best approach for you will depend on your project's structure, your team's workflow, and your long-term goals.

综合方法

🌐 Integrated approach

在集成方法中,你的 React Native 代码存在于现有的原生项目中。这允许你的 React Native 代码与原生代码紧密结合。

🌐 In the integrated approach, your React Native code lives inside your existing native project. This allows for a tight coupling between your React Native and native code.

例如,你可以将现有的 Android 或 iOS 原生项目添加到 React Native 项目的子目录中。这是那些最初使用 React Native 开发、后来又添加原生代码的项目的常见设置,但也可以用于现有的原生应用。如果你无法为原生项目使用标准的 androidios 子目录,你可以为你的 React Native 代码配置一个自定义根文件夹,并使用一个简单的单仓库(monorepo)设置。

🌐 For example, you might add your existing Android or iOS native projects to a subdirectory of the React Native project. This is a common setup for projects that started with React Native and added native code later, but it can also be used for existing native apps. If you can't use the standard android and ios subdirectories for your native projects, you can configure a custom root folder for your React Native code, with a simple monorepo setup.

如果符合以下情况,请选择此方法:

  • 你需要经常在本地代码和 React Native 代码上一起迭代。
  • 你有一个团队同时负责原生和 React Native 开发。
  • 你的项目结构允许直接添加一个 React Native 项目。

孤立的方法

🌐 Isolated approach

在隔离方法中,你的 React Native 代码与原生项目分开开发和维护,它可以在单独的代码仓库中维护,也可以在单一仓库中维护。

🌐 In the isolated approach, your React Native code is developed and maintained separately from your native project, and it can be maintained in a separate repository or in a monorepo.

采用这种方法,你可以将你的 React Native 应用打包为原生库(Android 使用 AAR,iOS 使用 XCFramework)。然后,你像集成其他原生依赖一样,将这个库集成到你的原生应用中。

🌐 With this approach, you package your React Native app as a native library (using AAR for Android and XCFramework for iOS). Then, you integrate this library into your native app just like any other native dependency.

这种分离简化了本地开发者的工作流程,因为他们无需搭建 Node.js 环境,也不用处理 React Native 的构建依赖。他们只需将应用的 React Native 部分作为预构建的产物使用即可。

🌐 This separation simplifies the workflow for native developers, as they don't need to set up a Node.js environment, or deal with React Native's build dependencies. They can just consume the React Native part of the app as a pre-built artifact.

如果符合以下情况,请选择此方法:

  • 你有专门负责原生开发和 React Native 开发的团队。
  • 你希望尽量减少在现有原生构建流程中添加 React Native 的影响。
  • 你更倾向于将应用中的 React Native 部分视为一个独立的模块。

下一步

🌐 Next steps

独立方法:将 Expo 打包为原生库

将你的 React Native 代码构建为 AAR/XCFramework 工件,并将它们集成到任何原生应用中。

集成方法:将 Expo 直接添加到你的原生项目中

将现有的原生项目配置为直接使用 React Native 和 Expo。