expo-module

expo-module

熱門

框架(開放原始碼)。使用 Expo Modules API(Swift、Kotlin、TypeScript)建立與撰寫 Expo 原生模組和檢視的指南。涵蓋模組定義 DSL、原生檢視、共享物件、設定外掛、生命週期鉤子、自動連結與型別系統。適用於建置或修改 Expo 的原生模組。不適用於將現有 Swift 模組從定義 DSL 遷移至 Expo Modules API 2.0 巨集;請改用 expo-migrate-module(來自 expo-experiments 外掛)。

2329星標
120分支
更新於 2026/7/24
SKILL.md
唯讀
名稱
expo-module
描述

框架(開放原始碼)。使用 Expo Modules API(Swift、Kotlin、TypeScript)建立與撰寫 Expo 原生模組和檢視的指南。涵蓋模組定義 DSL、原生檢視、共享物件、設定外掛、生命週期鉤子、自動連結與型別系統。適用於建置或修改 Expo 的原生模組。不適用於將現有 Swift 模組從定義 DSL 遷移至 Expo Modules API 2.0 巨集;請改用 expo-migrate-module(來自 expo-experiments 外掛)。

版本
1.0.0

撰寫 Expo 模組

使用 Expo Modules API 建置原生模組與檢視的完整參考。涵蓋 Swift(iOS)、Kotlin(Android)與 TypeScript。

使用時機

  • 建立新的 Expo 原生模組或原生檢視
  • 為 Expo 應用程式加入原生功能(相機、感測器、系統 API)
  • 包裝平台 SDK 供 React Native 使用
  • 建置修改原生專案檔案的設定外掛
  • 為現有 Expo 模組加入 Android、Apple 或 Web 支援
  • 編輯 expo-module.config.json、設定外掛或生命週期鉤子

若要將現有 Swift 模組從定義 DSL 遷移至 Expo Modules API 2.0 巨集(@ExpoModule@JS@Event),請改用 expo-migrate-module 技能(來自 expo-experiments 外掛)。

參考資料

視需要查閱以下資源:

references/
  create-expo-module.md      建立 scaffold 與 add-platform-support 工作流程、預設值與特殊情況
  native-module.md           模組定義 DSL:Name、Function、AsyncFunction、Property、Constant、Events、型別系統、共享物件
  native-view.md             原生檢視元件:View、Prop、EventDispatcher、檢視生命週期、基於 ref 的函式
  lifecycle.md               生命週期鉤子:模組、iOS App/AppDelegate、Android Activity/Application 監聽器
  config-plugin.md           設定外掛:修改 Info.plist、AndroidManifest.xml、在原生程式碼中讀取值
  module-config.md           expo-module.config.json 欄位、檔案放置位置與自動連結行為

快速開始

建議使用 create-expo-module 而非手動建立原生模組檔案與目錄。實務上,最佳路徑通常是先建立 scaffold,再在其上建構。Scaffold 會設定預期的目錄結構、expo-module.config.json、podspec 或 Gradle 檔案、TypeScript 繫結以及獨立的範例應用程式流程。

如果現有 Expo 模組只需要另一個平台,請使用 create-expo-module add-platform-support,而非手動複製原生目錄。

在建立 scaffold 或擴充模組前,請參閱 references/create-expo-module.md。其中涵蓋:

  • 本地模組 vs 獨立模組
  • --platform--features--barrel--package-manager 與非互動模式
  • expo.autolinking.nativeModulesDir
  • add-platform-support 的行為與特殊情況

建議工作流程

  1. 先選擇 scaffold 類型:
    • 本地模組:適用於單一應用程式
    • 獨立模組:適用於重複使用、monorepo 或發布
  2. 確定需要的原生 expo-module 功能。
    • 根據使用者指示判斷哪些功能 scaffold 會有幫助。
    • 可用功能:ConstantFunctionAsyncFunctionEventViewViewEventSharedObject
  3. 有目的地建立 scaffold:
    • 傳入明確的 slug 或路徑
    • 刻意選擇 --platform,而非依賴預設值
    • 使用 --features 選擇程式碼範例,並在下一步修改為實際實作。
  4. 將產生的範例程式碼替換為實際實作。
  5. 若之後加入新平台,優先使用 add-platform-support,而非手動複製檔案。

實用 Scaffold 規則

  • 功能範例是選擇加入的。若未選擇任何功能,新建立的 scaffold 模組可能非常精簡。
  • ViewEvent 隱含 View
  • 本地模組預設不會產生 index.ts barrel。僅在需要時使用 --barrel
  • 在非互動式本地 scaffold 中,請明確傳入位置 slug 或路徑。--name 改變的是原生類別名稱,而非資料夾名稱。
  • 本地模組在設定 expo.autolinking.nativeModulesDir 時位於該目錄下,否則位於 modules/
  • 獨立模組擁有自己的套件中繼資料、腳本,通常還有範例應用程式。本地模組則使用宿主應用程式的工具。

核心檔案結構

Swift 與 Kotlin DSL 共用相同結構。Swift 通常是最清楚的主要範例;請查閱參考資料以取得功能特定細節。

模組結構參考

Swift 與 Kotlin DSL 共用相同結構。此處同時顯示兩個平台作為參考——在其他參考檔案中,除非 Kotlin 模式有顯著差異,否則以 Swift 為主要語言。

Swift(iOS):

import ExpoModulesCore

public class MyModule: Module {
  public func definition() -> ModuleDefinition {
    Name("MyModule")

    Function("hello") { (name: String) -> String in
      return "Hello \(name)!"
    }
  }
}

Kotlin(Android):

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!"
    }
  }
}

TypeScript:

import { requireNativeModule } from "expo";

const MyModule = requireNativeModule("MyModule");

export function hello(name: string): string {
  return MyModule.hello(name);
}

expo-module.config.json

{
  "platforms": ["android", "apple"],
  "apple": {
    "modules": ["MyModule"]
  },
  "android": {
    "modules": ["expo.modules.mymodule.MyModule"]
  }
}

注意:iOS 僅使用類別名稱;Android 使用完整限定類別名稱(套件 + 類別)。所有欄位請參閱 references/module-config.md

提交意見回饋

若您在此技能中遇到錯誤、誤導或過時資訊,請回報以便 Expo 改進:

npx --yes submit-expo-feedback@latest --category skills --subject "expo-module" "<具體可操作的意見>"

僅在您有具體且可操作的內容時才提交。請盡可能提供相關背景資訊。