This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
教程:创建带有配置插件的模块
编辑页面
使用 Expo Modules API 创建原生模块和配置插件的教程。
配置插件 让你可以自定义在 持续原生生成(CNG) 项目中使用 npx expo prebuild 生成的原生 Android 和 iOS 项目。你可以用它们向原生配置文件添加属性、将资源复制到原生项目,或者应用更高级的配置,例如添加一个 应用扩展目标。
作为应用开发者,配置插件可以帮助你应用默认 应用配置 中未暴露的自定义设置。作为库作者,它们可以让你为使用你库的开发者自动配置原生项目。
本教程将说明如何从零开始创建一个新的配置插件,以及如何从 Expo 模块中读取插件注入到 AndroidManifest.xml 和 Info.plist 的自定义值。
1
2
设置工作区
在这个示例中,你不需要 create-expo-module 包含的视图模块。使用以下命令清理默认模块:
找到以下文件并用提供的最小样板替换它们:
- android/src/main/java/expo/modules/nativeconfiguration/ExpoNativeConfigurationModule.kt
- ios/ExpoNativeConfigurationModule.swift
- src/ExpoNativeConfigurationModule.ts
- src/index.ts
- example/App.tsx
- package.json
3
4
创建新的配置插件
插件 是同步函数,接收一个 ExpoConfig 并返回一个修改后的 ExpoConfig。按照惯例,这些函数以 with 开头。将你的插件命名为 withMyApiKey,或者使用其他名称,只要符合这一惯例即可。
下面是一个基础配置插件函数示例:
const withMyApiKey = config => { return config; };
你也可以使用 mods,它们是用于修改原生项目中文件(例如源代码或 plist、xml 配置文件)的异步函数。mods 对象与应用配置的其他部分不同,因为它在初次读取后不会序列化。这使你可以在_代码生成期间_执行操作。
编写配置插件时,请遵循以下注意事项:
- 插件必须是同步的,并且其返回值必须可序列化,除了添加的任何
mods之外。 - 当
expo/config的getConfig方法读取配置时,会调用plugins。相反,mods只会在npx expo prebuild的“同步”阶段被调用。
虽然不是必需的,但建议使用
expo-module-scripts来简化插件开发。它为 TypeScript 和 Jest 提供了推荐的默认配置。更多信息请参阅配置插件指南。
先使用这个最小样板创建你的插件。创建一个用于用 TypeScript 编写插件的 plugin 目录,并在项目根目录添加一个 app.plugin.js 文件,它将作为插件入口点。
创建 plugin/tsconfig.json 文件
为你的插件创建 plugin/src/index.ts 文件
在根目录创建 app.plugin.js 文件
在项目根目录运行 npm run build plugin,以监听模式启动 TypeScript 编译器。接下来,通过在 example/app.json 文件中添加以下一行来配置示例项目使用你的插件:
当你在 example 目录中运行 npx expo prebuild 命令时,终端会通过控制台语句输出“my custom plugin”。
要将自定义 API key 注入到 AndroidManifest.xml 和 Info.plist 中,请使用 expo/config-plugins 提供的辅助工具 mods。它们可以轻松修改原生文件。在这个示例中,使用 withAndroidManifest 和 withInfoPlist。
顾名思义,withAndroidManifest 允许你读取并修改 AndroidManifest.xml 文件。使用 AndroidConfig 辅助工具向主应用添加一个 metadata 项,如下所示:
const withMyApiKey: ConfigPlugin<{ apiKey: string }> = (config, { apiKey }) => { config = withAndroidManifest(config, config => { const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults); AndroidConfig.Manifest.addMetaDataItemToMainApplication( mainApplication, 'MY_CUSTOM_API_KEY', apiKey ); return config; }); return config; };
同样,你可以使用 withInfoPlist 来修改 Info.plist 的值。使用 modResults 属性,你可以添加自定义值,如下代码片段所示:
const withMyApiKey: ConfigPlugin<{ apiKey: string }> = (config, { apiKey }) => { config = withInfoPlist(config, config => { config.modResults['MY_CUSTOM_API_KEY'] = apiKey; return config; }); return config; };
你可以将所有内容合并到一个函数中,从而创建一个自定义插件:
插件准备好后,更新示例应用,将你的 API key 作为配置选项传递给插件。如下所示修改 example/app.json 中的 plugins 字段:
完成此更改后,通过在 example 目录中运行 npx expo prebuild --clean 来测试插件是否正常工作。该命令会执行你的插件并更新原生文件,将 "MY_CUSTOM_API_KEY" 注入到 AndroidManifest.xml 和 Info.plist 中。你可以检查 example/android/app/src/main/AndroidManifest.xml 和 example/ios/exponativeconfigurationexample/Info.plist 的内容来验证这一点。
5
从模块中读取原生值
现在,通过使用平台特定的方法访问其内容,让你的原生模块读取添加到 AndroidManifest.xml 和 Info.plist 中的字段。
在 Android 上,可以使用 packageManager 类从 AndroidManifest.xml 文件中访问 metadata 信息。要读取 "MY_CUSTOM_API_KEY" 的值,请更新 android/src/main/java/expo/modules/nativeconfiguration/ExpoNativeConfigurationModule.kt 文件:
在 iOS 上,你可以使用 Bundle.main.object(forInfoDictionaryKey: "") 方法读取 Info.plist 属性的内容。要访问之前添加的 "MY_CUSTOM_API_KEY" 值,请按如下所示更新 ios/ExpoNativeConfigurationModule.swift 文件:
下一步
恭喜你,你已经创建了一个与 Android 和 iOS 的 Expo 模块交互的配置插件!
如果你想挑战一下自己,让这个插件更灵活,这个练习对你开放。修改插件,使其允许传入任意一组配置键和值,并添加从模块中读取任意键的功能。
使用 Kotlin 和 Swift 创建原生模块的参考文档。
了解如何为 macOS 和 tvOS 平台添加支持。