Codegenの使用
このガイドでは、以下の方法を学びます。
- Codegen の設定。
- 各プラットフォームで手動で実行する方法。
また、生成されたコードについても説明します。
前提条件
Codegen を手動で実行する場合でも、コードを適切に生成するためには常に React Native アプリが必要です。
Codegen プロセスはアプリのビルドと密接に関連しており、スクリプトは react-native
NPM パッケージ内にあります。
このガイドのために、以下のように React Native CLI を使用してプロジェクトを作成してください。
npx @react-native-community/cli@latest init SampleApp --version 0.76.0
Codegen は、カスタムモジュールやコンポーネントのためのグルーコード(接着剤の役割を果たすコード)を生成するために使用されます。作成方法の詳細については、Turbo Native Modules と Fabric Native Components のガイドを参照してください。
Codegen の設定
Codegen は、アプリの package.json
ファイルを修正することで設定できます。Codegen は codegenConfig
というカスタムフィールドによって制御されます。
"codegenConfig": {
"name": "<SpecName>",
"type": "<types>",
"jsSrcsDir": "<source_dir>",
"android": {
"javaPackageName": "<java.package.name>"
},
"ios": {
"modules": {
"TestModule": {
"className": "<iOS-class-implementing-the-RCTModuleProvider-protocol>",
"unstableRequiresMainQueueSetup": false,
"conformsToProtocols": ["RCTImageURLLoader", "RCTURLRequestHandler", "RCTImageDataDecoder"],
}
},
"components": {
"TestComponent": {
"className": "<iOS-class-implementing-the-component>"
}
}
}
},
このスニペットをアプリに追加し、様々なフィールドをカスタマイズできます。
name:
codegen 設定の名前。これは codegen の出力(ファイル名やコード)をカスタマイズします。type
modules:
モジュール用のコードのみを生成します。components:
コンポーネント用のコードのみを生成します。all
: 全てのコードを生成します。
jsSrcsDir
: 全ての仕様ファイル (spec) が存在するルートフォルダ。android
: Android 用の Codegen 設定(すべてオプション).javaPackageName
: Android の Java codegen 出力のパッケージ名を設定します。
ios
: iOS 用の Codegen 設定(すべてオプション).modules[moduleName]
.className
: このモジュールの ObjC クラス。または、C++ 専用モジュールの場合は、そのRCTModuleProvider
クラス。.unstableRequiresMainQueueSetup
: JavaScript を実行する前に、このモジュールを UI スレッドで初期化します。.conformsToProtocols
: このモジュールが以下のプロトコルのいずれかに準拠しているかを注釈します:RCTImageURLLoader
,RCTURLRequestHandler
,RCTImageDataDecoder
。
.components[componentName]
:.className
: このコンポーネントの ObjC クラス (例:TextInput
->RCTTextInput
)。
Codegen が実行されると、アプリのすべての依存関係の中から、特定の規約に従った JS ファイルを検索し、必要なコードを生成します。
- Turbo Native Modules では、仕様ファイル名のプレフィックスが
Native
である必要があります。例えば、NativeLocalStorage.ts
は仕様ファイルの有効な名前です。 - Native Fabric Components では、仕様ファイル名のサフィックスが
NativeComponent
である必要があります。例えば、WebViewNativeComponent.ts
は仕様ファイルの有効な名前です。
Codegen の実行
このガイドの残りの部分では、プロジェクトに Native Turbo Module、Native Fabric Component、またはその両方がすでに設定されていることを前提としています。また、package.json
で指定された jsSrcsDir
に有効な仕様ファイルが存在することも前提とします。
Android
Android 用の Codegen は、React Native Gradle Plugin (RNGP) に統合されています。RNGP には、package.json
ファイルで定義された設定を読み取り、Codegen を実行するタスクが含まれています。Gradle タスクを実行するには、まずプロジェクトの android
フォルダに移動します。次に、以下を実行します。
./gradlew generateCodegenArtifactsFromSchema
このタスクは、アプリのすべてのインポートされたプロジェクト(アプリとそれにリンクされているすべての node modules)に対して generateCodegenArtifactsFromSchema
コマンドを呼び出します。対応する node_modules/<dependency>
フォルダにコードを生成します。例えば、Node モジュール名が my-fabric-component
の Fabric Native Component がある場合、生成されたコードは SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen
パスに配置されます。アプリの場合、コードは android/app/build/generated/source/codegen
フォルダに生成されます。
生成されたコード
上記の Gradle コマンドを実行した後、SampleApp/android/app/build
フォルダに codegen コードが見つかります。構造は次のようになります。
build
└── generated
└── source
└── codegen
├── java
│ └── com
│ ├── facebook
│ │ └── react
│ │ └── viewmanagers
│ │ ├── <nativeComponent>ManagerDelegate.java
│ │ └── <nativeComponent>ManagerInterface.java
│ └── sampleapp
│ └── NativeLocalStorageSpec.java
├── jni
│ ├── <codegenConfig.name>-generated.cpp
│ ├── <codegenConfig.name>.h
│ ├── CMakeLists.txt
│ └── react
│ └── renderer
│ └── components
│ └── <codegenConfig.name>
│ ├── <codegenConfig.name>JSI-generated.cpp
│ ├── <codegenConfig.name>.h
│ ├── ComponentDescriptors.cpp
│ ├── ComponentDescriptors.h
│ ├── EventEmitters.cpp
│ ├── EventEmitters.h
│ ├── Props.cpp
│ ├── Props.h
│ ├── ShadowNodes.cpp
│ ├── ShadowNodes.h
│ ├── States.cpp
│ └── States.h
└── schema.json
生成されたコードは2つのフォルダに分かれています。
java
: プラットフォーム固有のコードが含まれています。jni
: JS と Java が正しく連携するために必要な C++ コードが含まれています。
java
フォルダには、Fabric Native Component の生成コードが com/facebook/viewmanagers
サブフォルダ内にあります。
<nativeComponent>ManagerDelegate.java
には、ViewManager
がカスタム Native Component 上で呼び出すことができるメソッドが含まれています。<nativeComponent>ManagerInterface.java
には、ViewManager
のインターフェースが含まれています。
一方、codegenConfig.android.javaPackageName
で設定した名前のフォルダには、Turbo Native Module がタスクを実行するために実装する必要がある抽象クラスがあります。
最後に、jni
フォルダには、JS と Android を接続するためのすべてのボイラープレートコードがあります。
<codegenConfig.name>.h
: カスタム C++ Turbo Native Modules のインターフェースが含まれています。<codegenConfig.name>-generated.cpp
: カスタム C++ Turbo Native Modules のグルーコードが含まれています。react/renderer/components/<codegenConfig.name>
: このフォルダには、カスタムコンポーネントに必要なすべてのグルーコードが含まれています。
この構造は、codegenConfig.type
フィールドに値 all
を使用して生成されました。値 modules
を使用した場合、react/renderer/components/
フォルダは表示されません。値 components
を使用した場合、他のファイルは表示されません。
iOS
iOS 用の Codegen は、ビルドプロセス中に呼び出されるいくつかの Node スクリプトに依存しています。これらのスクリプトは SampleApp/node_modules/react-native/scripts/
フォルダにあります。
メインスクリプトは generate-codegen-artifacts.js
スクリプトです。このスクリプトを呼び出すには、アプリのルートフォルダから次のコマンドを実行します。
node node_modules/react-native/scripts/generate-codegen-artifacts.js
Usage: generate-codegen-artifacts.js -p [path to app] -t [target platform] -o [output path]
Options:
--help Show help [boolean]
--version Show version number [boolean]
-p, --path Path to the React Native project root. [required]
-t, --targetPlatform Target platform. Supported values: "android", "ios",
"all". [required]
-o, --outputPath Path where generated artifacts will be output to.
ここで、
--path
はアプリのルートフォルダへのパスです。--outputPath
は Codegen が生成されたファイルを書き込む場所です。--targetPlatform
はコードを生成したいプラットフォームです。
生成されたコード
これらの引数でスクリプトを実行すると、
node node_modules/react-native/scripts/generate-codegen-artifacts.js \
--path . \
--outputPath ios/ \
--targetPlatform ios
ios/build
フォルダにこれらのファイルが生成されます。
build
└── generated
└── ios
├── <codegenConfig.name>
│ ├── <codegenConfig.name>-generated.mm
│ └── <codegenConfig.name>.h
├── <codegenConfig.name>JSI-generated.cpp
├── <codegenConfig.name>JSI.h
├── FBReactNativeSpec
│ ├── FBReactNativeSpec-generated.mm
│ └── FBReactNativeSpec.h
├── FBReactNativeSpecJSI-generated.cpp
├── FBReactNativeSpecJSI.h
├── RCTModulesConformingToProtocolsProvider.h
├── RCTModulesConformingToProtocolsProvider.mm
└── react
└── renderer
└── components
└── <codegenConfig.name>
├── ComponentDescriptors.cpp
├── ComponentDescriptors.h
├── EventEmitters.cpp
├── EventEmitters.h
├── Props.cpp
├── Props.h
├── RCTComponentViewHelpers.h
├── ShadowNodes.cpp
├── ShadowNodes.h
├── States.cpp
└── States.h
これらの生成されたファイルの一部は、React Native のコアで使用されます。そして、package.json の codegenConfig.name
フィールドで指定したのと同じ名前を持つ一連のファイルがあります。
<codegenConfig.name>/<codegenConfig.name>.h
: カスタム iOS Turbo Native Modules のインターフェースが含まれています。<codegenConfig.name>/<codegenConfig.name>-generated.mm
: カスタム iOS Turbo Native Modules のグルーコードが含まれています。<codegenConfig.name>JSI.h
: カスタム C++ Turbo Native Modules のインターフェースが含まれています。<codegenConfig.name>JSI-generated.h
: カスタム C++ Turbo Native Modules のグルーコードが含まれています。react/renderer/components/<codegenConfig.name>
: このフォルダには、カスタムコンポーネントに必要なすべてのグルーコードが含まれています。
この構造は、codegenConfig.type
フィールドに値 all
を使用して生成されました。値 modules
を使用した場合、react/renderer/components/
フォルダは表示されません。値 components
を使用した場合、他のファイルは表示されません。