添加自定义原生代码

了解如何将自定义原生代码添加到你的 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

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 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 Go你只能访问包含在 Expo SDK 中的原生库,或者不包含任何自定义原生代码的库(了解更多)。创建开发构建允许你像在其他原生应用中一样更改原生代码或配置。

🌐 If you are using 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 (learn more). Creating a development build allows you to change the native code or configuration as you would in any other native app.

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

🌐 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
  • 如果库中包含 config 插件,你可以在应用配置中指定你偏好的配置。
  • 创建一个新的开发版本(可以在本地或使用EAS)。

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

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

关键概念与开发工作流程

开发概览 提供了使用 Expo 开发应用的关键概念以及核心开发循环的流程详情。

编写原生代码

🌐 Writing native code

使用 Expo Modules API 编写 Swift 和 Kotlin 代码,并通过原生模块和视图为你的应用添加新功能。虽然还有其他工具可以用来构建原生模块,但我们认为使用 Expo Modules API 可以让构建和维护几乎所有类型的 React Native 模块变得尽可能容易。我们认为,对于大多数为应用构建原生模块的开发者来说,Expo Modules API 是最佳选择。

🌐 Use the Expo Modules API to write Swift and Kotlin code and add new capabilities to your app with native modules and views. While there are other tools that you can use to build native modules, 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.

我什么时候应该考虑编写本地代码?

在实际使用中,经常会遇到库不能完全满足你需求的情况。例如,某个库可能不能访问特定的平台功能,或者某个第三方服务可能没有为 React Native 提供绑定。

🌐 It's common to encounter situations where a library doesn't quite do what you need. For example, the library might not provide access to a specific platform feature, or a third-party service might not provide bindings for React Native.

你考虑主要用C++来编写一个模块吗?

如果你打算主要用 C++ 编写原生模块,你可能想要探索由 React Native 提供的 Turbo Modules API

🌐 If you intend to write a native module primarily in C++, you may want to explore the Turbo Modules API provided by React Native.

使用 Expo 模块 API

🌐 Using the Expo Modules API

Expo 模块 API:概述

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

教程:创建原生视图

关于使用 Expo 模块 API 创建一个可以保存设置的原生模块的教程。

了解应用大小

关于使用 Expo 模块 API 创建本地视图以渲染本地 WebView 组件的教程。

创建本地模块

🌐 Creating a local module

如果你打算在单个应用中使用你的原生模块(你以后总是可以改变主意),我们建议使用“本地”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 的 packages 目录中(如果你有的话),以便以 类似于本地模块 的方式使用它。

🌐 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.

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

默认情况下,通过 create-expo-app 创建的 Expo 项目使用 CNG,并且在你在项目中运行 npx expo prebuild 命令之前,不包含 androidios 原生目录。在使用 CNG 时,开发者通常不会将 androidios 目录提交到版本控制,也不会在本地生成它们,因为 EAS 构建会在构建过程中自动补齐这些操作。不过,当编写自定义原生代码时,使用 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.

使用配置插件进行本地项目配置

如果你的原生代码需要对项目配置进行修改,例如修改项目的 AndroidManifest.xmlInfo.plist你应当通过配置插件应用这些更改,而不是直接修改 androidios 目录中的文件。请记住,直接对原生项目目录所做的更改在使用 CNG 运行预构建(prebuild)时会被下次覆盖丢失。

🌐 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.

使用事件订阅者来连接应用的生命周期事件

如果你需要挂接到 Android 生命周期事件或 AppDelegate 方法,请使用 Expo 模块为 AndroidiOS 提供的 API 来实现,而不是直接修改本地项目目录中的源文件或使用配置插件添加代码,因为那样与其他插件的兼容性不佳。

🌐 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.