This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

教程:创建内联模块

关于如何在你的 Expo 项目中使用内联模块直接创建原生模块和视图的教程。


警告 内联模块是实验性功能,仅在 Expo SDK 56 及更高版本中可用。该 API 可能会发生重大更改。

在本教程中,你将使用内联模块直接在你的 Expo 项目的 app 目录中创建一个示例原生模块和原生视图。 与标准的 Expo 模块不同,内联模块不需要单独的包或 create-expo-module 脚手架。 你可以将 Kotlin 和 Swift 文件与应用代码一起编写,Expo 会自动发现它们。

🌐 In this tutorial, you will create an example native module and a native view directly inside your Expo project's app directory using inline modules. Unlike the standard Expo Modules, inline modules don't require a separate package or create-expo-module scaffolding. You write Kotlin and Swift files alongside your app code, and Expo discovers them automatically.

1

设置你的项目

🌐 Setup your project

打开 应用配置 并将 expo.experiments.inlineModules.watchedDirectories 设置为 ["app"]

🌐 Open the app config and set the expo.experiments.inlineModules.watchedDirectories to ["app"]:

app.json
{ "expo": { "experiments": { "inlineModules": { "watchedDirectories": ["app"] } } } }

定义 expo.experiments.inlineModules 可以在 Expo 项目中启用内联模块功能。

🌐 Defining expo.experiments.inlineModules enables inline modules functionalities in an Expo project.

expo.experiments.inlineModules.watchedDirectories 中,你可以指定你的内联模块所在的目录。请注意,并非所有目录都被允许。更多信息,请参阅 内联模块参考

🌐 In expo.experiments.inlineModules.watchedDirectories you can specify in which directories your inline modules live. Note that not all directories are allowed. For more information, see the inline modules reference.

2

运行预构建

🌐 Run prebuild

运行预构建命令以使用内联模块设置生成 AndroidiOS 原生项目。

🌐 Run the prebuild command to generate android and ios native projects with the inline modules setup.

Terminal
npx expo prebuild

3

创建一个内联模块

🌐 Create an inline module

对于 Android,在 app 目录下创建一个名为 FirstInlineModule.kt 的 Kotlin 文件,并添加类似于以下的模块:

🌐 For Android, create a Kotlin file called FirstInlineModule.kt inside the app directory and add a module similar to the following:

app/FirstInlineModule.kt
package app import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition class FirstInlineModule : Module() { override fun definition() = ModuleDefinition { Constant("Hello") { -> "Hello Android inline modules!" } } }

对于 iOS,在 app 目录中创建一个名为 FirstInlineModule.swift 的 Swift 文件:

🌐 For iOS, create a Swift file called FirstInlineModule.swift inside the app directory:

app/FirstInlineModule.swift
internal import ExpoModulesCore class FirstInlineModule: Module { public func definition() -> ModuleDefinition { Constant("Hello") { return "Hello iOS inline modules!" } } }

4

在你的应用中使用该模块

🌐 Use the module in your app

在你应用的 TypeScript/JavaScript 代码中,你可以按以下方式使用该模块:

🌐 In your app's TypeScript/JavaScript code you can use the module in the following way:

app/index.tsx
import { requireNativeModule } from 'expo'; import { Text } from 'react-native'; const FirstInlineModule = requireNativeModule('FirstInlineModule'); export default function InlineModulesDemoComponent() { return <Text> {FirstInlineModule.Hello} </Text>; }

现在,你可以运行示例应用:

🌐 Now, you can run the example app:

Terminal
# Run the example app on Android
npx expo run:android

# Run the example app on iOS
npx expo run:ios

在运行上述命令后,你将看到应用中来自原生 Android/iOS 模块的文本常量。

🌐 After running the above command(s), you will see the app with text constant coming from the native android/iOS module.

5

创建本地视图

🌐 Create a native view

要在 app 目录中创建本地视图,让我们使用 ExpoWebView 示例。

🌐 To create a native view inside the app directory, let's use the ExpoWebView example.

对于 Android,在 app 目录下创建一个名为 FirstInlineView.kt 的 Kotlin 文件,并添加类似于以下的视图:

🌐 For Android, create a Kotlin file called FirstInlineView.kt inside the app directory and add a view similar to the following:

app/FirstInlineView.kt
package app import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition import java.net.URL import android.content.Context import android.webkit.WebView import android.webkit.WebViewClient import expo.modules.kotlin.AppContext import expo.modules.kotlin.viewevent.EventDispatcher import expo.modules.kotlin.views.ExpoView class FirstInlineView : Module() { override fun definition() = ModuleDefinition { View(ExpoWebView::class) { Events("onLoad") Prop("url") { view: ExpoWebView, url: URL? -> view.webView.loadUrl(url.toString()) } } } } class ExpoWebView(context: Context, appContext: AppContext) : ExpoView(context, appContext) { private val onLoad by EventDispatcher() internal val webView = WebView(context).also { it.layoutParams = LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) it.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { onLoad(mapOf("url" to url)) } } addView(it) } }

对于 iOS,在 app 目录中创建一个名为 FirstInlineView.swift 的 Swift 文件:

🌐 For iOS, create a Swift file called FirstInlineView.swift inside the app directory:

app/FirstInlineView.swift
internal import ExpoModulesCore import WebKit class FirstInlineView: Module { public func definition() -> ModuleDefinition { View(ExpoWebView.self) { Events("onLoad") Prop("url") { (view, url: URL) in if view.webView.url != url { let urlRequest = URLRequest(url: url) view.webView.load(urlRequest) } } } } } class ExpoWebView: ExpoView, WKNavigationDelegate { let webView = WKWebView() let onLoad = EventDispatcher() required init(appContext: AppContext? = nil) { super.init(appContext: appContext) clipsToBounds = true webView.navigationDelegate = self addSubview(webView) } override func layoutSubviews() { webView.frame = bounds } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { if let url = webView.url { onLoad([ "url": url.absoluteString ]) } } }

6

在你的应用中使用本地视图

🌐 Use the native view in your app

你以类似于内联模块的方式使用内联视图:

🌐 You use the inline view in a similar way to the inline module:

app/index.tsx
import { requireNativeModule, requireNativeView } from 'expo'; import { StyleSheet, Text, View } from 'react-native'; const FirstInlineModule = requireNativeModule('FirstInlineModule'); const FirstInlineView = requireNativeView('FirstInlineView'); export default function InlineModulesDemoComponent() { return ( <> <View style={styles.textBox}> <Text style={styles.text}> {FirstInlineModule.Hello} </Text> </View> <FirstInlineView style={styles.inlineView} url="https://expo.nodejs.cn/modules/" /> </> ); } const styles = StyleSheet.create({ textBox: { height: 100, justifyContent: 'flex-end', alignItems: 'center' }, text: { fontSize: 26 }, inlineView: { flex: 1 }, });

现在通过使用 npx expo run:androidnpx expo run:ios 命令编译来运行你的示例应用。

🌐 Now run your example app by compiling it using npx expo run:android or npx expo run:ios command.

运行上述命令后,你将看到应用,其中包含来自原生 Android/iOS 模块的文本常量,以及来自原生视图的 Web 视图。

🌐 After running the above command(s), you will see the app with a text constant coming from the native android/iOS module and a web view coming from a native view.

恭喜!你已经创建了你的第一个 Expo 内联模块和视图。

🌐 Congratulations! You've created your first Expo inline module and view.

下一步

🌐 Next steps

Expo 内联模块参考

关于如何使用 Kotlin 和 Swift 创建内联模块的参考资料。

教程:创建原生视图

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