راهنمای ماژول های توربو در React Native

بهعنوان یک توسعهدهنده React Native، من از انعطافپذیری ناشی از عملکرد متقابل پلتفرم چارچوب قدردانی میکنم. اما، لحظاتی وجود دارد که من نیاز به دسترسی به عملکرد بومی دارم. وارد Turbo Modules شوید، درب جادویی React Native به دنیای بومی.
در این مقاله من با پوشش ماژولهای توربو و نیاز اساسی که منجر به ایجاد آنها شد، شروع خواهم کرد. از آنجا، من شما را از طریق یک مثال گام به گام راهنمایی میکنم که در آن نحوه ایجاد یک ماژول توربو سفارشی و ادغام آن در برنامه React Native خود را آموزش میدهم و امکان دسترسی مستقیم به API Native Android را فراهم میکند. این برنامه سپس می تواند بر روی هر دستگاه Android یا Fire OS اجرا شود، همانطور که در دمو زیر نشان داده شده است:
TLDR: مخزن Github را در اینجا بررسی کنید.
چرا ماژول های توربو مهم هستند – غلبه بر محدودیت های ماژول های بومی
پیش از این هنگام کار با React Native، ارتباط بین لایههای Native و JavaScript برنامهها از طریق پل جاوا اسکریپت – که به عنوان Native Modules نیز شناخته میشود، انجام میشد. با این حال، این رویکرد دارای تعدادی اشکال بود:
- پل به صورت ناهمزمان کار می کرد، به این معنی که چندین تماس را به لایه اصلی ارسال می کرد و آنها را در فواصل از پیش تعیین شده فراخوانی می کرد.
- دادههایی که از پل عبور میکردند باید در سمت اصلی سریالسازی و سریالزدایی میشدند که سربار و تأخیر را معرفی میکرد.
- پل فاقد نوع ایمنی بود. هر داده ای را می توان بدون اجرای دقیق از طریق آن منتقل کرد و آن را به لایه اصلی واگذار کرد تا داده ها را به طور مناسب مدیریت و پردازش کند.
- در طول راه اندازی برنامه، تمام ماژول های بومی باید در حافظه بارگذاری می شدند که باعث تاخیر در راه اندازی برنامه برای کاربران می شد.
برای مقابله با این مشکلات، سازندگان React Native معرفی کردند:
Codegen، Turbo Modules و Fabric که معماری جدید React را تشکیل می دهند.
ماژولهای توربو تکرار بعدی ماژولهای بومی هستند که به مشکلات ناهمزمان و بارگذاری توسط ماژولهای بارگذاری تنبل رسیدگی میکنند و امکان راهاندازی سریعتر برنامه را فراهم میکنند. ماژولهای توربو عملکرد برنامه شما را بهبود میبخشند، زیرا با دور زدن پل جاوا اسکریپت و ارتباط مستقیم با کد بومی، سربار ارتباط بین جاوا اسکریپت و کد بومی را کاهش میدهند.
کدجن مشکل ایمنی نوع را با ایجاد یک رابط جاوا اسکریپت در زمان ساخت برطرف می کند. این رابط ها تضمین می کنند که کد بومی با داده های ارسال شده از لایه جاوا اسکریپت همگام می ماند. علاوه بر این، Codegen ایجاد اتصالات JSI را تسهیل می کند، که تعامل موثر و مستقیم بین جاوا اسکریپت و کد بومی را بدون نیاز به پل امکان پذیر می کند. استفاده از اتصالات JSI به برنامههای React Native اجازه میدهد تا به ارتباطات سریعتر و بهینهتر بین لایههای بومی و جاوا اسکریپت دست یابند.
علاوه بر این، Fabric سیستم رندر جدیدی برای React Native است که از قابلیتهای Turbo Modules و Codegen بهره میبرد. این سه مؤلفه با هم، ستونهای معماری جدید در React Native را تشکیل میدهند که عملکرد بهبود یافته، ایمنی نوع بهبود یافته و قابلیت همکاری ساده بین کد بومی و جاوا اسکریپت را ارائه میدهند.
وای، پیچیده به نظر می رسد! 🤯 بنابراین ممکن است از خود بپرسید:
در چه سناریوهایی به ماژول توربو نیاز دارم؟
- دسترسی به API های دستگاه: ماژولهای توربو میتوانند به شما اجازه دسترسی مستقیم به APIهای دستگاهی را بدهند که از طریق ماژولهای استاندارد جاوا اسکریپت در معرض نمایش نیستند. این به شما امکان می دهد با قابلیت های خاص دستگاه مانند دسترسی به حسگرها، بلوتوث یا سایر ویژگی های سخت افزاری یکپارچه شوید. در حالی که در برخی موارد می توانید از ماژول های استاندارد جاوا اسکریپت استفاده کنید، ممکن است عملکرد بهینه نباشد و ممکن است به تمام ویژگی های پیشرفته ارائه شده توسط API های بومی دسترسی نداشته باشید. ماژول های توربو دسترسی به عملکرد کامل بومی را ایجاد می کنند.
- اجزای UI بومی: ماژولهای توربو را میتوان برای ایجاد مؤلفههای UI بومی سفارشی استفاده کرد که در مقایسه با همتایان مبتنی بر جاوا اسکریپت، تجربه کاربری یکپارچهتر و کارآمدتری را ارائه میدهند.
- وظایف فشرده CPU: اگر برنامه شما کارهای فشرده CPU مانند پردازش تصویر، رمزگذاری صوتی/تصویری یا محاسبات پیچیده را انجام میدهد، استفاده از یک ماژول توربو میتواند به تخلیه این وظایف به کد اصلی، بهرهگیری از قدرت محاسباتی دستگاه و بهینهسازی عملکرد کمک کند.
مراحل ایجاد یک ماژول توربو برای برنامه شما
بیایید به نحوه اضافه کردن یک ماژول توربو سفارشی به یک برنامه React Native که معماری جدید را فعال کرده است، بپردازیم. مثال Turbo Module که ما طراحی خواهیم کرد، شماره مدل یک دستگاه اندرویدی را برای برنامه ما به نمایش در می آورد. سپس میتوانیم برنامه React Native خود را بر روی هر دستگاه Android از جمله دستگاههای Amazon Fire اجرا کنیم.
پیش نیازها
نکته: هر نسخه قدیمی را حذف کنید
react-native-cli package
، زیرا ممکن است باعث ایجاد مشکلات غیرمنتظره در ساخت شود. می توانید از دستور استفاده کنیدnpm uninstall -g react-native-cli @react-native-community/cli
مرحله 1: یک برنامه جدید ایجاد کنید و پوشه های Turbo Module را راه اندازی کنید
- یک پوشه جدید به نام TurboModuleDemo ایجاد کنید و در آن یک برنامه جدید به نام DeviceName ایجاد کنید
npx react-native@latest init DeviceName
نکته: برای جدا نگه داشتن ماژول توربو از برنامه، ایده خوبی است که ماژول را جدا از برنامه تعریف کنید و بعداً آن را به عنوان یک وابستگی به برنامه خود اضافه کنید. این به شما امکان می دهد در صورت نیاز به راحتی آن را به طور جداگانه آزاد کنید.
- در داخل
TurboModuleDemo
، یک پوشه به نام ایجاد کنیدRTNDeviceName
. RTN مخفف “React Native” است و یک پیشوند توصیه شده برای ماژول های React Native است. - در داخل
RTNDeviceName
، دو زیر پوشه ایجاد کنید:js
وandroid
.
ساختار پوشه شما باید به شکل زیر باشد:
TurboModulesDemo
├── DeviceName
└── RTNDeviceName
├── android
└── js
مرحله 2: مشخصات جاوا اسکریپت
همانطور که گفته شد، New Architecture به رابط های مشخص نیاز دارد، بنابراین برای این نسخه ی نمایشی از TypeScript استفاده خواهیم کرد. کدجن سپس از این مشخصات برای تولید کد در زبانهایی با تایپ قوی (C++، Objective-C++، Java) استفاده میکند.
- در داخل
js
پوشه، یک فایل به نام ایجاد کنیدNativeGetDeviceName.ts
. Codegen فقط به دنبال فایلهایی میگردد که با الگوی Native{MODULE_NAME} مطابقت دارند.ts
، یا.tsx
افزونه. - کد زیر را در فایل کپی کنید:
NativeGetDeviceName.ts
import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
import { TurboModuleRegistry } from "react-native";
export interface Spec extends TurboModule {
getDeviceModel(): Promise<string>;
}
export default TurboModuleRegistry.get<Spec>("RTNDeviceName") as Spec | null;
بیایید به کد نگاه کنیم. اول واردات است: نوع TurboModule رابط پایه را برای همه ماژولهای توربو تعریف میکند و ماژول جاوا اسکریپت TurboModuleRegistry شامل توابعی برای بارگذاری ماژولهای توربو است.
بخش دوم فایل شامل مشخصات رابط برای ماژول توربو است. در این مورد، رابط کاربری را تعریف می کند getDeviceModel
تابع، که وعده ای را برمی گرداند که به یک رشته حل می شود. این نوع رابط باید Spec برای یک ماژول توربو نامیده شود.
در نهایت استناد می کنیم TurboModuleRegistry.get
، نام ماژول را ارسال کنید، که در صورت موجود بودن، ماژول بومی توربو بارگیری می شود.
مرحله 3: اضافه کردن تنظیمات
در مرحله بعد، باید تنظیماتی را برای اجرای Codegen اضافه کنید. در ریشه RTNDeviceName
پوشه
- a اضافه کنید
package.json
فایل با محتوای زیر:
package.json
{
"name": "rtn-device",
"version": "0.0.1",
"description": "Get device name with Turbo Modules",
"react-native": "js/index",
"source": "js/index",
"files": [
"js",
"android",
"!android/build"
],
"keywords": [
"react-native",
"android"
],
"license": "MIT",
"devDependencies": {},
"peerDependencies": {
"react": "*",
"react-native": "*"
},
"codegenConfig": {
"name": "RTNDeviceSpec",
"type": "modules",
"jsSrcsDir": "js",
"android": {
"javaPackageName": "com.rtndevice"
}
}
}
Yarn از این فایل هنگام نصب ماژول شما استفاده می کند. همچنین شامل پیکربندی Codegen است – مشخص شده توسط codegenConfig
رشته.
- بعد، a ایجاد کنید
build.gradle
فایل در پوشه اندروید با محتویات زیر:
build.gradle
buildscript {
ext.safeExtGet = {prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
repositories {
google()
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.22")
}
}
apply plugin: 'com.android.library'
apply plugin: 'com.facebook.react'
apply plugin: 'org.jetbrains.kotlin.android'
android {
compileSdkVersion safeExtGet('compileSdkVersion', 33)
namespace "com.rtndevice"
}
repositories {
mavenCentral()
google()
}
dependencies {
implementation 'com.facebook.react:react-native'
}
این مرحله یک کلاس ایجاد می کند که نامیده می شود DevicePackage
، که گسترش می دهد TurboReactPackage
رابط. این کلاس به عنوان پل ارتباطی بین Turbo Module و اپلیکیشن React Native عمل می کند. جالب اینجاست که لزوماً مجبور نیستید کلاس بسته را به طور کامل پیاده سازی کنید. حتی یک پیاده سازی خالی برای برنامه کافی است تا ماژول توربو را به عنوان یک وابستگی React Native بشناسد و سعی کند کد داربست لازم را تولید کند.
React Native بر روی DevicePackage
رابط برای تعیین اینکه کدام کلاس های بومی باید برای ViewManager و Native Modules صادر شده توسط کتابخانه استفاده شوند. با گسترش TurboReactPackage
رابط، اطمینان حاصل می کنید که Turbo Module به درستی در معماری برنامه React Native ادغام شده است.
این به این معنی است که حتی اگر کلاس بسته خالی یا فاقد پیادهسازی به نظر برسد، برنامه React Native همچنان ماژول توربو را شناسایی و پردازش میکند و تلاش میکند کد مورد نیاز را برای کاربردی کردن آن تولید کند.
- یک پوشه به نام ایجاد کنید
rtndevice
زیر:android/src/main/java/com
. در داخل پوشه، a ایجاد کنیدDevicePackage.kt
فایل.
DevicePackage.kt
package com.rtndevice;
import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReacTurboModuleoduleInfoProvider
class DevicePackage : TurboReactPackage() {
override fun getModule(name: String?, reactContext: ReactApplicationContext): NativeModule? = null
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider? = null
}
در پایان این مراحل، پوشه اندروید باید به شکل زیر باشد:
android
├── build.gradle
└── src
└── main
└── java
└── com
└── rtndevice
└── DevicePackage.kt
مرحله 4: اضافه کردن کد بومی
برای آخرین مرحله در ایجاد ماژول توربو، باید مقداری کد بومی بنویسید تا سمت جاوا اسکریپت را به پلتفرم های اصلی متصل کنید. برای تولید کد برای اندروید، باید Codegen را فراخوانی کنید.
- از
DeviceName
اجرای پوشه پروژه:
yarn add ../RTNDeviceName
cd android
./gradlew generateCodegenArtifactsFromSchema
نکته: با نگاه کردن به زیر می توانید تأیید کنید که کد داربست تولید شده است:
DeviceName/node_modules/rtn-device/android/build/generated/source/codegen
نکته: باز کن
android/gradle.properties
فایل را در برنامه خود (DeviceName) قرار دهید و مطمئن شویدnewArchEnabled
دارایی درست است
کد اصلی برای سمت Android یک ماژول توربو از شما می خواهد که یک DeviceModule.kt ایجاد کنید که ماژول را پیاده سازی می کند.
- در
rtndevice
پوشه ایجاد یکDeviceModule.kt
فایل:
android
├── build.gradle
└── src
└── main
└── java
└── com
└── rtndevice
├── DeviceModule.kt
└── DevicePackage.kt
- کد زیر را به the اضافه کنید
DeviceModule.kt
فایل:
DeviceModule.kt
package com.rtndevice
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.rtndevice.NativeGetDeviceNameSpec
import android.os.Build
class DeviceModule(reactContext: ReactApplicationContext) : NativeGetDeviceNameSpec(reactContext) {
override fun getName() = NAME
override fun getDeviceModel(promise: Promise) {
val manufacturer: String = Build.MANUFACTURER
val model: String = Build.MODEL
promise.resolve(manufacturer + model)
}
companion object {
const val NAME = "RTNDeviceName"
}
}
این کلاس پیاده سازی می کند DeviceModule
که گسترش می دهد NativeGetDeviceNameSpec
رابطی که توسط کدژن از فایل مشخصات NativeGetDeviceName TypeScript ایجاد شده است. همچنین کلاسی است که شامل ماست getDeviceModel
تابع، که یک وعده را با مدل دستگاه به عنوان یک رشته برمی گرداند.
package com.rtndevice;
import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.module.model.ReactModuleInfo
class DevicePackage : TurboReactPackage() {
override fun getModule(name: String?, reactContext: ReactApplicationContext): NativeModule? =
if (name == DeviceModule.NAME) {
DeviceModule(reactContext)
} else {
null
}
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf(
DeviceModule.NAME to ReactModuleInfo(
DeviceModule.NAME,
DeviceModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
true // isTurboModule
)
)
}
}
مرحله 5: ماژول توربو را به برنامه خود اضافه کنید
- برای افزودن Turbo Module به برنامه خود، از پوشه برنامه DeviceName خود، دوباره اجرا کنید:
yarn add ../RTNDeviceName
نکته: برای اطمینان از اینکه تغییرات TurboModule شما در برنامه شما منعکس می شود، برنامه خود را حذف کنید
node_modules
قبل از اجرای نخ اضافه کنید.
اکنون می توانید از ماژول توربو خود برای استفاده از آن استفاده کنید getDeviceName
عملکرد در برنامه شما!
- در شما
App.tsx
با … تماس بگیرgetDeviceModel
روش:
App.tsx
import React from 'react';
import {useState} from 'react';
import {SafeAreaView, StatusBar, Text, Button} from 'react-native';
import RTNDeviceName from 'rtn-device/js/NativeGetDeviceName';
const App: () => JSX.Element = () => {
const [result, setResult] = useState<string | null>(null);
return (
<SafeAreaView>
<StatusBar barStyle={'dark-content'} />
<Text style={{marginLeft: 20, marginTop: 20}}>
{result ?? 'Whats my device?'}
</Text>
<Button
title="Compute"
onPress={async () => {
const value = await RTNDeviceName?.getDeviceModel();
setResult(value ?? null);
}}
/>
</SafeAreaView>
);
};
export default App;
با دویدن، ماژول توربو خود را در عمل بررسی کنید npm run android
در هر دستگاه اندرویدی از جمله دستگاه های سیستم عامل آمازون Fire:
تبریک برای اجرای موفقیت آمیز یک ماژول ساده توربو در یک برنامه! امیدواریم با این مقاله و کد نمونه اکنون درک بهتری برای نحوه ادغام ماژول های توربو در پروژه های خود داشته باشید.
در نظرات به من اطلاع دهید که ماژول توربو را برای چه چیزی ایجاد می کنید!
📣 من را در anisha.dev دنبال کنید
📺 در کانال یوتیوب AmazonAppstoreDevelopers ما مشترک شوید
📧 برای خبرنامه توسعه دهندگان آمازون ثبت نام کنید