本文翻译自 Expo 的一篇博客:You can now use Expo APIs in any React Native app
注: 本文最初于 2019 年 2 月 28 日发布,随后于 2019 年 3 月 14 日更新,以反映 Workflow 的改进。
从今天开始,你可以在任何 React Native 应用程序中使用尽可能少或尽可能多的 Expo SDK。我们已经花了很多时间构建和维护这些包含原生应用特性的跨平台 API,我们很高兴最终实现了向整个 React Native 生态共享这些 API,并将它们作为一个整体继续优化。
Expo 未来的两个主要的工程流分别是 Managed
和 Bare
。Managed 应用程序是通过 expo-cli、移动设备上的 Expo 客户端和我们的各种服务: Push Notifications、构建服务和 无线 (OTA) 更新 构建的。Expo 试图尽可能多地为你管理构建应用程序的复杂性,所以我们称之为 Managed Workflow
。另一方面,Bare 应用程序将所有的控制权 (以及随之而来的复杂性) 交给了开发人员。
关于
Bare Workflow
,可以参考:“Hello World”guide for bare projects in the Expo docs
我们称这个初始版本为预览版,因为还它没有我们希望的那样足够简化,但是我们希望尽快把这些功能交到用户手中,因为它们已经是一个很大的改进了。
Introducing Unimodules
React Native 包一般都是小的整体。如果他们需要与 Filesystem 或 Permissions 进行交互,不同的包将以各自的方式实现这个逻辑。其结果是导致用户需要做不必要的重复工作、处理 bug 以及各种修改。
因为 Expo 最初是作为一个整体建立的,所以自然而然地,我们为 API 的这些基本构建块建立并依赖于一个更通用的解决方案。当涉及到将 Expo 拆分以使开发人员能够按需挑选 SDK 的部分时,我们面临一个决定: 退一步,在每个模块中提供这些构建块的特殊实现?或者构建一个允许模块之间干净利落地交互的工具?
这项工作的成果是一个名为 Unimodules
的项目。Unimodules
是一个 toolchain(工具链)
,用于构建模块化的 React Native 插件,这些插件可以相互交互。我会把这些细节留到下一篇文章中,但是我们很兴奋,因为这有可能解决 React Native 中原生模块存在的一系列问题。它还打开了与其他相邻社区(如 Flutter)共享 cross-platform APIs
实现的可能性ーー我们通过制作一个用于 Flutter
的 Unimodule 适配器和发布一些 Flutter 包来使用 Expo SDK!(如果你好奇的话,可以阅读 How to use Expo Unimodules in Flutter)
让我们来看看这个问题的实质: 如何在应用程序中使用这些 API?
在 React Native 应用程序中安装 Unimodule
1. 获取 react-native-unimodules
如果你通过 react-native init
或者 ignite-cli
之类的工具创建 React Native 项目,那么您需要将 react-native-unimodules
包添加到项目中并首先对其进行配置: 按照 README 中的说明进行操作。这个包提供了其他模块通常依赖的功能(如 Permissions
, Constants
, 和 FileSystem
) : 它是一个构建其他模块的平台。每个应用程序只需要这样做一次。
如果通过运行 expo init
并选择 Bare 模板,通过 expo-cli
创建一个 Bare React Native
项目,那么您的项目将默认安装并配置 react-rative-unimodule
。您可以使用 react-native run-ios
或 react-native run-android
而不是 expo start
来运行这个项目。
2. 查找并安装所需的 packages
在 Expo 文档中的 Expo documentation 部分,找到要添加到项目中的 API。跳转到 Installation 部分,并按照链接进入 Bare React Native
的安装说明。大多数软件包都有相同的简单安装流程,但在少数情况下,除了配置依赖项之外,您还需要添加一些代码。接下来,你就可以应用程序中使用它了。
需要注意的是,SDK 中包含的某些 api 不是 Unimodules: MapView
只是 react-native-maps
,SVG
是 react-native-svg
,Gestorehandler
是 react-native-gesturehandler
,takeSnapshotAsync
是 react-native-view-shot
的包装。所有这些 API 都可以按照相应 READMEs 中的说明进行安装。
在 Managed 应用程序中安装 Unimodule
当你在 expo init 的时候选择 Managed 时,你将得到一个可以在 Expo 客户端打开的项目,其中包括 expo package,它是构成 expo SDK 的包的集合。例如,它依赖于并重新导出 expo-permissions
, expo-file-system
, expo-web-browser
等模块。
在不久的将来,expo package 将只包含最小的核心包,类似于 react-native-unimodules
,要在应用程序中使用其他包,你需要安装 npm 包,但不需要本修改原生代码。这将实现更小的 bundle 大小和更快的构建时间,因为只包含你在应用程序中使用的代码。
社区中的其他人可能开始围绕 Unimodule 工具构建他们的原生模块。我们不能在 Expo 客户端中支持任意的原生模块,同时通过 App Store 发布,所以你现在不能在 Managed 应用中安装这些模块。
Expo 团队设计和创建的 Unimodules 都将作为基础设施,我们将继续为其添加 Web
和 TypeScript
的支持,更多特性,敬请期待。
ExpoKit 的未来
在博客 ExpoKit 2019 中,我有提到我们计划继续支持和改进 ExpoKit 工作流。这是对其进行评估的第一个结果。通过在一个简单的 React Native 应用程序中安装 Unimodules,你已经可以非常接近使用 ExpoKit 的效果了。不过还是缺少了 Expo 里基于 TaskManager
、AppLoading
和 SplashScreen
实现的 notifications services
, background tasks
以及我们的实验性的 AR
相关的 API。我们已经开始着手将后台任务移植到 React Native,并将在之后不久启动 OTA 更新 和 Notifications
的 Unimodules。
What’s next
Update : 2019 年 3 月 14 日,我们发布了这个功能!使用
react-native-unimodules
,大部分 Unimodules 的安装都是为你自动完成原文:我们对接下来要发生的事情非常兴奋:an open pull request 自动将 Unimodules 安装到 iOS 和 Android 项目中,这样在大多数情况下,你只需要从 npm 安装包就可以了。我们希望使 Unimodules 的安装尽可能简单。
我们也期待着将我们的 OTA 更新 和 Background Tasks APIs
交到 Bare 工作流用户手中。最后,我们希望帮助其他人使用 Unimodules 基础设施来建立自己的库,如果这对他们有益的话,因此我们将记录如何从头开始构建自己的 Unimodule,以及如何转换现有的 React Native 库。