添加自定义原生代码

了解如何将自定义原生代码添加到你的 Expo 项目中。


你可以使用以下一种或两种方法添加自定义原生代码:

¥You can add custom native code by using one or both of the following approaches:

  • 使用 Expo Modules API

    ¥Using libraries that include native code

  • 编写原生代码

    ¥Writing native code

使用 Expo Modules API

¥Using libraries that include native code

Expo 和 React Native 开发者通常将大部分时间花在编写 JavaScript 代码和使用通过 expo-camerareact-native-safe-area-contextreact-native 等库本身提供的原生 API 和组件上。这些库允许开发者从他们的 JavaScript 代码访问和使用设备功能(例如相机)。它们还可以提供对以原生代码实现的第三方服务 SDK 的访问(例如 @sentry/react-native,它提供与 Android 和 iOS 的 Sentry 原生 SDK 的绑定)。

¥Expo and React Native developers typically spend the vast majority of their time writing JavaScript code and using native APIs and components that are made available through libraries like expo-camera, react-native-safe-area-context, and react-native itself. These libraries allow developers to access and use device features (such as Camera) from their JavaScript code. They may also provide access to a third-party service SDK that is implemented in native code (such as @sentry/react-native, which provides bindings to the Sentry native SDK for Android and iOS).

如果你使用的是沙盒应用 Expo Go,则只能访问 Expo SDK 中包含的原生库,或者不包含任何自定义原生代码的库。相比之下,通过 创建开发构建,你可以控制应用的任何部分。你可以更改任何其他原生应用中可能的原生代码或配置。有关如何确定第三方库是否依赖于自定义代码的更多详细信息,请参阅 使用第三方库

¥If you are using the sandbox app, Expo Go, you can only access native libraries that are included in the Expo SDK, or libraries that do not include any custom native code. In contrast, by creating a development build, you can control any part of your app. You can change the native code or configuration that is possible in any other native app. For more details on how to determine if a third-party library depends on custom code, see Using third party libraries.

在开发版本中安装带有自定义原生代码的库

¥Installing libraries with custom native code in development builds

使用 开发构建 时,使用带有自定义原生代码的库非常简单:

¥When using development builds, using libraries with custom native code is straightforward:

  • 例如,使用 npm 安装库:npx expo install react-native-localize

    ¥Install the library with npm, for example: npx expo install react-native-localize

  • 如果库包含 配置插件,你可以在应用配置中指定首选配置。

    ¥If the library includes a config plugin, you can specify your preferred configuration in your app config.

  • 创建一个新的开发版本(locallyEAS)。

    ¥Create a new development build (either locally or with EAS).

你现在可以在应用代码中使用该库。

¥You can now use the library in your application code.

Key concepts and development workflow

开发概述 详细介绍了使用 Expo 开发应用的关键概念以及核心开发循环的流程。

¥The development overview provides details on key concepts for developing an app with Expo and the flow of the core development loop.

编写原生代码

¥Writing native code

经常会遇到库无法帮助你完成工作的情况。例如,库可能不提供对特定平台功能的访问,或者第三方库可能不提供 React Native 的绑定。要解决这个问题,你可以编写 Kotlin(或 Java)和/或 Swift(或 Objective-C)代码,以直接向你的应用添加任何原生功能,或为你的 JavaScript 代码提供绑定。你可以在 React Native 中使用不同的工具来实现这一点,我们通常建议使用 Expo Modules API。如果你打算编写 C++ 代码,你可能需要探索 React Native 提供的 Turbo Modules API

¥It's common to encounter situations where a library doesn't help you get your job done. For example, the library might not provide access to a specific platform feature, or a third-party library might not provide bindings for React Native. To solve this, you can write Kotlin (or Java) and/or Swift (or Objective-C) code to add any native functionality to your app directly, or to provide bindings to your JavaScript code. There are different tools you can use for this in React Native, and we typically recommend using the Expo Modules API. If you intend to write C++ code, you may want to explore the Turbo Modules API provided by React Native.

直接使用 VideoPlayer

¥Using the Expo Modules API

Expo Modules API 允许你编写 Swift 和 Kotlin,以使用原生模块和视图为你的应用添加新功能。我们相信使用 Expo Modules API 可以尽可能轻松地构建和维护几乎所有类型的 React Native 模块。我们认为 Expo Modules API 是大多数为其应用构建原生模块的开发者的最佳选择。

¥The Expo Modules API allows you to write Swift and Kotlin to add new capabilities to your app with native modules and views. We believe that using the Expo Modules API makes building and maintaining nearly all kinds of React Native modules about as easy as it can be. We think that the Expo Modules API is the best choice for most developers building native modules for their apps.

Expo 模块 API:概述

概述 Expo 提供的用于开发原生模块的 API 和实用程序。

教程:创建原生视图

关于使用 Expo Modules API 创建保留设置的原生模块的教程。

了解应用大小

关于使用 Expo Modules API 创建渲染原生 WebView 组件的原生视图的教程。

创建本地模块

¥Creating a local module

如果你打算在单个应用中使用原生模块(你以后可以随时改变主意),我们建议使用 使用 "local" Expo 模块 编写自定义原生代码。本地 Expo 模块的功能类似于库开发者使用的 Expo 模块,也类似于 Expo SDK 中的 expo-camera,但它们未在 npm 上发布。相反,你可以直接在项目中创建它们。

¥If you intend to use your native module in a single app (you can always change your mind later), we recommend using a "local" Expo module to write custom native code. Local Expo Modules function similarly to Expo Modules used by library developers and within the Expo SDK, like expo-camera, but they are not published on npm. Instead, you create them directly inside your project.

创建本地模块会在你的项目的 modules 目录中构建 Swift 和 Kotlin 模块,这些模块会自动链接到你的应用。

¥Creating a local module scaffolds a Swift and Kotlin module inside the modules directory in your project, and these modules are automatically linked to your app.

Terminal
npx create-expo-module@latest --local
npx expo run

开始推出

¥Sharing a module with multiple apps

如果你打算在多个应用中使用原生模块,则使用 npx create-expo-module@latest, 省略 --local 标志和 创建独立模块。你可以将包发布到 npm,也可以将其放在 monorepo 中的包目录中(如果有)以在 与本地模块类似的方式 中使用它。

¥If you intend to use your native module with multiple apps, then use npx create-expo-module@latest, leave out the --local flag, and create a standalone module. You can publish your package to npm, or you can put it in a packages directory in your monorepo (if you have one) to use it in a similar way to local modules.

使用持续原生生成 (CNG) 时的注意事项

¥Considerations when using Continuous Native Generation (CNG)

以下建议在使用 CNG 时最为重要,但即使你不使用它,也是很好的指导原则。

¥The following suggestions are most important when using CNG, but are good guidelines even if you don't use it.

本地构建以获得最佳调试体验和快速反馈

¥Build locally for the best debugging experience and fast feedback

默认情况下,使用 create-expo-app 创建的 Expo 项目使用 CNG,并且在你在项目中运行 npx expo prebuild 命令之前不包含 android 或 ios 原生目录。使用 CNG 时,开发者通常不会将 android 和 ios 目录提交到源代码控制中,也不会在本地生成它们,因为 EAS Build 会在构建过程中自动执行此操作。也就是说,在编写自定义原生代码时,通常会生成原生目录并使用 npx expo run 进行本地构建,以便在 Android Studio/Xcode 中获得快速反馈循环和对原生调试工具的完全访问。

¥By default, Expo projects created with create-expo-app use CNG and do not contain android or ios native directories until you've run the npx expo prebuild command in your project. When using CNG, developers typically do not commit the android and ios directories to source control and do not generate them locally, since EAS Build will do it automatically during the build process. That said, it is common to generate native directories and build locally with npx expo run when writing custom native code, to have a fast feedback loop and full access to native debugging tools in Android Studio / Xcode.

使用开发版本

¥Use config plugins for native project configuration

如果你的原生代码要求你更改项目配置,例如修改项目的 AndroidManifest.xml 或 Info.plist,请使用 你应该通过配置插件应用这些更改,而不是直接修改 android 和 ios 目录中的文件。请记住,当你使用 CNG 时,下次运行预构建时,直接对原生项目目录所做的更改将丢失。

¥If your native code requires that you make changes to your project configuration, such as modifying the project's AndroidManifest.xml or Info.plist, you should apply these changes through a config plugin rather than by modifying the files directly in the android and ios directories. Remember that changes made directly to native project directories will be lost the next time you run prebuild when you use CNG.

使用本地模块

¥Use event subscribers to hook into app lifecycle events

此外,如果你需要挂接 Android 生命周期事件或 AppDelegate 方法,请使用 Expo Modules 为 安卓iOS 系统 提供的 API 来实现这一点,而不是直接修改原生项目目录中的源文件或使用配置插件添加代码,这与其他插件不能很好地组合。

¥Additionally, if you need to hook into Android lifecycle events or AppDelegate methods, use the APIs provided by Expo Modules for Android and iOS to accomplish this rather than modifying the source files in your native project directories directly or using a config plugin to add the code, which does not compose well with other plugins.