expo-module 是做什么的?
使用 Expo Modules API(Swift、Kotlin、TypeScript)创建和编写 Expo 原生模块与原生视图的指南。涵盖模块定义 DSL、原生视图、共享对象、配置插件、生命周期钩子、自动链接和类型系统。在构建或修改 Expo 原生模块时使用。
简介
Expo Modules API 是一个用于在 React Native / Expo 应用中编写原生模块的现代框架。它提供了清晰、类型安全的 API,用于连接 JavaScript 和原生代码。
快速入门
创建模块
使用 npx create-expo-module 命令创建一个新的原生模块:
npx create-expo-module my-module
模块目录结构
my-module/
├── src/
│ └── MyModule.ts
├── ios/
│ └── MyModule.swift
├── android/
│ └── src/main/kotlin/.../MyModule.kt
├── expo-module.config.json
├── package.json
└── README.md
模块定义 DSL
模块通过模块类上的 @ExpoModule 和相关装饰器进行定义。
Swift 示例
import ExpoModulesCore
public class MyModule: Module {
public func definition() -> ModuleDefinition {
Name("MyModule")
Function("hello") { (name: String) in
return "Hello, \(name)!"
}
}
}
Kotlin 示例
package expo.modules.mymodule
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
class MyModule : Module() {
override fun definition() = ModuleDefinition {
Name("MyModule")
Function("hello") { name: String ->
"Hello, $name!"
}
}
}
原生视图
原生视图允许你在 React Native 应用中嵌入自定义的原生 UI 元素。
Swift 视图示例
import ExpoModulesCore
class MyView: ExpoView {
let label = UILabel()
required init(appContext: AppContext) {
super.init(appContext: appContext)
addSubview(label)
}
func setText(_ text: String) {
label.text = text
}
}
在模块定义中注册:
View("MyView") {
Prop("text") { (view: MyView, text: String) in
view.setText(text)
}
}
共享对象
共享对象允许你在 JavaScript 和原生代码之间传递复杂对象,同时保持引用。
class MyObject: SharedObject {
func doSomething() -> String {
return "共享对象的工作结果"
}
}
配置插件
配置插件允许你在原生构建过程中修改 Expo 配置。
// app.plugin.js
const { withAndroidManifest } = require('@expo/config-plugins');
module.exports = function myPlugin(config) {
return withAndroidManifest(config, async (config) => {
config.modResults.manifest['$']['xmlns:tools'] = 'http://schemas.android.com/tools';
return config;
});
};
生命周期钩子
模块支持生命周期钩子,用于管理资源:
OnCreate {
// 模块创建时调用
}
OnDestroy {
// 模块销毁时调用
}
自动链接
Expo 的自动链接系统会自动检测并集成原生模块,无需手动配置。
类型系统
Expo Modules API 使用 TypeScript 生成类型定义,确保类型安全:
export function hello(name: string): string;