1. expo module
플러터에서는 네이티브 코드를 호출하려면 메소드 채널, 이벤트 채널이라는걸 사용했는데 rn에서는 모듈이라는걸 사용한다.
먼저 프리빌드를 한 뒤 모듈을 설치해준다
npx expo prebuild
npx create-expo-module@latest --local
2. module의 구조
모듈을 설치하면 아래와 같은 폴더구조가 생긴다
module/
모듈폴더/
android/
네이티브모듈.kt
네이티브뷰.kt
ios/
네이티브모듈.swift
네이티브뷰.swift
src/
타입스크립트.types.ts
타입스크립트모듈.ts
expo-module.config.json
index.ts
여기서 index.ts가 가장 최상단 구조이고 여기서 export한걸 expo에서 임포트 할 수 있다.
index.ts
여기서 ABC는 MyModule 익스포트한걸 ABC로 바꾼건데 이를 expo단에서 ABC로 임포트해서 사용 가능
TestModule은 디폴트 모듈 이외에 본인이 추가하고 싶은게 있다면 저런식으로 추가하면 된다.
// Reexport the native module. On web, it will be resolved to DbbeatsModule.web.ts
// and on native platforms to DbbeatsModule.ts
export * from './src/Dbbeats.types';
export { default as ABC } from './src/MyModule';
export { default as MyView } from './src/MyView';
export { default as TestModule } from './src/TestModule';
타입스크립트모듈.ts
타입스크립트모듈.ts는 파일이 여러개여도 된다.(모듈이 여러개라는 뜻) 그에맞춰 네이티브 모듈 파일수도 늘어나야 한다.
여기서 위 코드를 보면 모듈이름이 Test라는걸 읽어오겠다는 뜻이고, declare class 부분은 함수 목록을 나타낸다.
모듈을 추가할때는 반드시 expo-module.config.json에서 모듈을 추가로 등록해주어야 빌드된다!
import { NativeModule, requireNativeModule } from 'expo';
import { TestModuleEvents } from './Test.types';
declare class TestModule extends NativeModule<TestModuleEvents> {
PI: number;
hello(): string;
setValueAsync(value: string): Promise<void>;
}
// This call loads the native module object from the JSI.
export default requireNativeModule<TestModule>('Test');
네이티브모듈.kt
앞서 타입스크립트 모듈에서 문자열로 이름을 지정해서 네이티브 모듈을 읽어오는걸 보았다.
아래 코드는 그 내용을 나타낸다.
- 먼저 Name('Test')로 이름을 정해서 타입스크립트 모듈에서 읽어갈 수 있도록 한다
- Function을 이용해서 타입스크립트에서 정의했던 함수 모양과 맞추어 함수를 작성해준다
class TestModule : Module() {
// Each module class must implement the definition function. The definition consists of components
// that describes the module's functionality and behavior.
// See https://docs.expo.dev/modules/module-api for more details about available components.
override fun definition() = ModuleDefinition {
// Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument.
// Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
// The module will be accessible from `requireNativeModule('Dbbeats')` in JavaScript.
Name("Test")
// Defines constant property on the module.
Constant("PI") {
Math.PI
}
// Defines event names that the module can send to JavaScript.
Events("onChange")
// Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
Function("hello") {
"Hello Test!! 👋"
}
// Defines a JavaScript function that always returns a Promise and whose native code
// is by default dispatched on the different thread than the JavaScript runtime runs on.
AsyncFunction("setValueAsync") { value: String ->
// Send an event to JavaScript.
sendEvent("onChange", mapOf(
"value" to value
))
}
// Enables the module to be used as a native view. Definition components that are accepted as part of
// the view definition: Prop, Events.
View(DbbeatsView::class) {
// Defines a setter for the `url` prop.
Prop("url") { view: DbbeatsView, url: URL ->
view.webView.loadUrl(url.toString())
}
// Defines an event that the view can send to JavaScript.
Events("onLoad")
}
}
}
모듈 여러개 등록하기
expo module을 설치하면 기본적으로 하나의 모듈만 등록되어있다. 폴더 구조를 보면 여러개를 등록 가능해보이고 실제로 가능하다.
앞서 설명된 내용으로 이미 유추 가능하겠지만 아래와 같은 flow로 진행된다.
- expo-module.config.json에서 먼저 네이티브 모듈 파일을 등록한다.
- src 폴더 밑에 타입스크립트 모듈파일을 만들고 네이티브 모듈을 name을 통해 읽어오도록한다
- 네이티브 모듈을 작성한다
- index.ts에 모듈을 노출시킨다.
expo-module.config.json은 아래와 같은 형태로 생겼다.
{
"platforms": ["apple", "android", "web"],
"apple": {
"modules": ["MyModule", "TestModule"]
},
"android": {
"modules": ["expo.modules.dbbeats.MyModule", "expo.modules.dbbeats.TestModule"]
}
}'React Native' 카테고리의 다른 글
| Flutter에서 RN으로 넘어오며 느낀 장단점들 (3) | 2025.12.10 |
|---|---|
| React Native Skia에서 uniform에 애니메이션 주기 (0) | 2025.11.10 |
| flutter개발자의 RN 애니메이션 적응하기 (0) | 2025.11.05 |
| ReactNative Firebase 구글 로그인 (2) | 2023.07.13 |
| React Native 카카오 로그인 + Firebase 연동 (0) | 2023.07.01 |
댓글