メインコンテンツへスキップ

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` というカスタムフィールドによって制御されます。

package.json
  "codegenConfig": {
"name": "<SpecName>",
"type": "<types>",
"jsSrcsDir": "<source_dir>",
"android": {
"javaPackageName": "<java.package.name>"
}
},

このスニペットをアプリに追加して、さまざまなフィールドをカスタマイズできます。

  • name: これは、仕様を含むファイルを作成するために使用される名前です。慣例として、サフィックス `Spec` を付ける必要がありますが、必須ではありません。
  • type: 生成する必要があるコードの種類。許容値は `modules`、`components`、`all` です。
    • modules: Turbo Native Modules のコードのみを生成する場合に使用します。
    • components: Native Fabric Components のコードのみを生成する場合に使用します。
    • all: コンポーネントとモジュールの両方が混在する場合に使用します。
  • jsSrcsDir: すべての仕様ファイルが存在するルートフォルダです。
  • android.javaPackageName: **Codegen** がカスタムパッケージにファイルを生成できるようにするためのAndroid固有の設定です。

**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

このタスクは、アプリのすべてのインポートされたプロジェクト(アプリとそれにリンクされているすべてのノードモジュール)で `generateCodegenArtifactsFromSchema` コマンドを実行します。対応する `node_modules/` フォルダにコードが生成されます。たとえば、ノードモジュール名が `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`
  • JSとJavaを正しく連携させるために必要なC++コードを含む `jni`

`java` フォルダには、`com/facebook/viewmanagers` サブフォルダに生成されたFabric Nativeコンポーネントコードがあります。

  • `ManagerDelegate.java` には、`ViewManager` がカスタムネイティブコンポーネントで呼び出すことができるメソッドが含まれています。
  • `ManagerInterface.java` には、`ViewManager` のインターフェースが含まれています。

`codegenConfig.android.javaPackageName` で設定された名前のフォルダには、Turbo Native Moduleがタスクを実行するために実装する必要がある抽象クラスがあります。

`jni` フォルダには、JSをAndroidに接続するためのすべてのボイラープレートコードがあります。

  • `.h` これは、カスタムC++ Turbo Native Modulesのインターフェースが含まれています。
  • `-generated.cpp` これは、カスタムC++ Turbo Native Modulesのグルーコードが含まれています。
  • `react/renderer/components/`: このフォルダには、カスタムコンポーネントに必要なすべてのグルーコードが含まれています。

この構造は、`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` フィールドで指定したのと同じ名前のファイルセットがあります。

  • `/.h`: これは、カスタムiOS Turbo Native Modulesのインターフェースが含まれています。
  • `/-generated.mm`: これは、カスタムiOS Turbo Native Modulesのグルーコードが含まれています。
  • `JSI.h`: これは、カスタムC++ Turbo Native Modulesのインターフェースが含まれています。
  • `JSI-generated.h`: これは、カスタムC++ Turbo Native Modulesのグルーコードが含まれています。
  • `react/renderer/components/`: このフォルダには、カスタムコンポーネントに必要なすべてのグルーコードが含まれています。

この構造は、`codegenConfig.type` フィールドに `all` を使用して生成されました。`modules` を使用した場合、`react/renderer/components/` フォルダは表示されません。`components` を使用した場合、他のファイルは表示されません。