Skip to main content

使用 Codegen

¥Using Codegen

本指南教你如何:

¥This guide teaches how to:

  • 配置 Codegen。

    ¥Configure Codegen.

  • 为每个平台手动调用它。

    ¥Invoke it manually for each platform.

它还描述了生成的代码。

¥It also describes the generated code.

先决条件

¥Prerequisites

你始终需要一个 React Native 应用来正确生成代码,即使在手动调用 Codegen 时也是如此。

¥You always need a React Native app to generate the code properly, even when invoking the Codegen manually.

Codegen 过程与应用的构建紧密结合,脚本位于 react-native NPM 包中。

¥The Codegen process is tightly coupled with the build of the app, and the scripts are located in the react-native NPM package.

为了本指南的目的,请使用 React Native CLI 创建一个项目,如下所示:

¥For the sake of this guide, create a project using the React Native CLI as follows:

bash
npx @react-native-community/cli@latest init SampleApp --version 0.76.0

Codegen 用于为你的自定义模块或组件生成粘合代码。有关如何创建 Turbo Native 模块和 Fabric Native 组件的更多详细信息,请参阅指南。

¥Codegen is used to generate the glue-code for your custom modules or components. See the guides for Turbo Native Modules and Fabric Native Components for more details on how to create them.

配置 Codegen

¥Configuring Codegen

可以通过修改 package.json 文件在你的应用中配置 Codegen。Codegen 由名为 codegenConfig 的自定义字段控制。

¥Codegen can be configured in your app by modifying the package.json file. Codegen is controlled by a custom field called codegenConfig.

package.json
  "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>"
}
}
}
},

你可以将此代码片段添加到你的应用并自定义各个字段:

¥You can add this snippet to your app and customize the various fields:

  • name: 代码生成配置的名称。这将自定义 codgen 输出:文件名和代码。

    ¥name: Name of the codegen config. This will customize the codgen output: the filenames, and the code.

  • type:

    • modules: 仅为模块生成代码。

      ¥modules: Only generate code for modules.

    • components: 仅为组件生成代码。

      ¥components: Only generate code for components.

    • all:为所有内容生成代码。

      ¥all: Generate code for everything.

  • jsSrcsDir:所有规范所在的根文件夹。

    ¥jsSrcsDir: The root folder where all your specs live.

  • android:Android 代码生成配置(全部可选):

    ¥android: Codegen configuration for Android (all optional):

    • .javaPackageName:配置 Android Java 代码生成输出的软件包名称。

      ¥.javaPackageName: Configure the package name of the Android Java codegen output.

  • ios:iOS 代码生成配置(全部可选):

    ¥ios: Codegen configuration for iOS (all optional):

    • .modules[moduleName]:

      • .className:此模块的 ObjC 类。或者,如果是 纯 C++ 模块,则为 RCTModuleProvider 类。

        ¥.className: This module's ObjC class. Or, if it's a C++-only module, its RCTModuleProvider class.

      • .unstableRequiresMainQueueSetup:在运行任何 JavaScript 代码之前,请在 UI 线程上初始化此模块。

        ¥.unstableRequiresMainQueueSetup: Initialize this module on the UI Thread, before running any JavaScript.

      • .conformsToProtocols:请注明此模块遵循以下哪种协议:RCTImageURLLoaderRCTURLRequestHandlerRCTImageDataDecoder

        ¥.conformsToProtocols: Annotate which of these protocols this module conforms to any of the following protocols: RCTImageURLLoader, RCTURLRequestHandler, RCTImageDataDecoder.

    • .components[componentName]

      • .className:此组件的 ObjC 类(例如:TextInput -> RCTTextInput)。

        ¥.className: This component's ObjC class (e.g: TextInput -> RCTTextInput).

当 Codegen 运行时,它会在应用的所有依赖中搜索,查找遵守某些特定约定的 JS 文件,并生成所需的代码:

¥When Codegen runs, it searches among all the dependencies of the app, looking for JS files that respects some specific conventions, and it generates the required code:

  • Turbo Native 模块要求 spec 文件以 Native 为前缀。例如,NativeLocalStorage.ts 是 spec 文件的有效名称。

    ¥Turbo Native Modules require that the spec files are prefixed with Native. For example, NativeLocalStorage.ts is a valid name for a spec file.

  • Native Fabric Components 要求规范文件以 NativeComponent 为后缀。例如,WebViewNativeComponent.ts 是 spec 文件的有效名称。

    ¥Native Fabric Components require that the spec files are suffixed with NativeComponent. For example, WebViewNativeComponent.ts is a valid name for a spec file.

运行 Codegen

¥Running Codegen

本指南的其余部分假设你已在项目中设置了 Native Turbo 模块、Native Fabric 组件或两者。我们还假设你在 package.json 中指定的 jsSrcsDir 中拥有有效的规范文件。

¥The rest of this guide assumes that you have a Native Turbo Module, a Native Fabric Component or both already set up in your project. We also assume that you have valid specification files in the jsSrcsDir specified in the package.json.

安卓

¥Android

Android 版 Codegen 与 React Native Gradle 插件(RNGP)集成。RNGP 包含一个可以调用的任务,该任务读取 package.json 文件中定义的配置并执行 Codegen。要运行 gradle 任务,首先在项目的 android 文件夹中导航。然后运行:

¥Codegen for Android is integrated with the React Native Gradle Plugin (RNGP). The RNGP contains a task that can be invoked that reads the configurations defined in the package.json file and execute Codegen. To run the gradle task, first navigate inside the android folder of your project. Then run:

bash
./gradlew generateCodegenArtifactsFromSchema

此任务在应用的所有导入项目(应用和链接到它的所有节点模块)上调用 generateCodegenArtifactsFromSchema 命令。它在相应的 node_modules/<dependency> 文件夹中生成代码。例如,如果你有一个 Fabric Native 组件,其 Node 模块名为 my-fabric-component,则生成的代码位于 SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen 路径中。对于应用,代码在 android/app/build/generated/source/codegen 文件夹中生成。

¥This task invokes the generateCodegenArtifactsFromSchema command on all the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding node_modules/<dependency> folder. For example, if you have a Fabric Native Component whose Node module is called my-fabric-component, the generated code is located in the SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen path. For the app, the code is generated in the android/app/build/generated/source/codegen folder.

生成的代码

¥The Generated Code

运行上面的 gradle 命令后,你会在 SampleApp/android/app/build 文件夹中找到 codegen 代码。结构将如下所示:

¥After running the gradle command above, you will find the codegen code in the SampleApp/android/app/build folder. The structure will look like this:

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

生成的代码分为两个文件夹:

¥The generated code is split in two folders:

  • java 包含平台特定代码

    ¥java which contains the platform specific code

  • jni 包含让 JS 和 Java 正确交互所需的 C++ 代码。

    ¥jni which contains the C++ code required to let JS and Java interact correctly.

java 文件夹中,你可以在 com/facebook/viewmanagers 子文件夹中找到 Fabric Native 组件生成的代码。

¥In the java folder, you can find the Fabric Native component generated code in the com/facebook/viewmanagers subfolder.

  • <nativeComponent>ManagerDelegate.java 包含 ViewManager 可以在自定义原生组件上调用的方法

    ¥the <nativeComponent>ManagerDelegate.java contains the methods that the ViewManager can call on the custom Native Component

  • <nativeComponent>ManagerInterface.java 包含 ViewManager 的界面。

    ¥the <nativeComponent>ManagerInterface.java contains the interface of the ViewManager.

codegenConfig.android.javaPackageName 中设置名称的文件夹中,你可以找到 Turbo Native Module 必须实现的抽象类才能执行其任务。

¥In the folder whose name was set up in the codegenConfig.android.javaPackageName, instead, you can find the abstract class that a Turbo Native Module has to implement to carry out its tasks.

jni 文件夹中,最后,有将 JS 连接到 Android 的所有样板代码。

¥In the jni folder, finally, there is all the boilerplate code to connect JS to Android.

  • <codegenConfig.name>.h 包含自定义 C++ Turbo Native 模块的接口。

    ¥<codegenConfig.name>.h this contains the interface of your custom C++ Turbo Native Modules.

  • <codegenConfig.name>-generated.cpp 包含自定义 C++ Turbo Native 模块的粘合代码。

    ¥<codegenConfig.name>-generated.cpp this contains the glue code of your custom C++ Turbo Native Modules.

  • react/renderer/components/<codegenConfig.name>:此文件夹包含你的自定义组件所需的所有粘合代码。

    ¥react/renderer/components/<codegenConfig.name>: this folder contains all the glue-code required by your custom component.

此结构是通过使用 codegenConfig.type 字段的值 all 生成的。如果你使用值 modules,则不会看到 react/renderer/components/ 文件夹。如果你使用值 components,则不会看到任何其他文件。

¥This structure has been generated by using the value all for the codegenConfig.type field. If you use the value modules, expect to see no react/renderer/components/ folder. If you use the value components, expect not to see any of the other files.

iOS

iOS 版 Codegen 依赖于在构建过程中调用的一些 Node 脚本。脚本位于 SampleApp/node_modules/react-native/scripts/ 文件夹中。

¥Codegen for iOS relies on some Node scripts that are invoked during the build process. The scripts are located in the SampleApp/node_modules/react-native/scripts/ folder.

主脚本是 generate-codegen-artifacts.js 脚本。要调用脚本,你可以从应用的根文件夹运行此命令:

¥The main script is the generate-codegen-artifacts.js script. To invoke the script, you can run this command from the root folder of your app:

bash
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.

其中:

¥where:

  • --path 是你应用根文件夹的路径。

    ¥--path is the path to the root folder of your app.

  • --outputPath 是 Codegen 将写入生成文件的目的地。

    ¥--outputPath is the destination where Codegen will write the generated files.

  • --targetPlatform 是你想要为其生成代码的平台。

    ¥--targetPlatform is the platform you'd like to generate the code for.

生成的代码

¥The Generated Code

使用这些参数运行脚本:

¥Running the script with these arguments:

shell
node node_modules/react-native/scripts/generate-codegen-artifacts.js \
--path . \
--outputPath ios/ \
--targetPlatform ios

将在 ios/build 文件夹中生成这些文件:

¥Will generate these files in the ios/build folder:

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 字段中指定的相同名称。

¥Part of these generated files are used by React Native in the Core. Then there is a set of files which contains the same name you specified in the package.json codegenConfig.name field.

  • <codegenConfig.name>/<codegenConfig.name>.h:这包含你自定义的 iOS Turbo Native 模块的接口。

    ¥<codegenConfig.name>/<codegenConfig.name>.h: this contains the interface of your custom iOS Turbo Native Modules.

  • <codegenConfig.name>/<codegenConfig.name>-generated.mm:这包含你自定义的 iOS Turbo Native 模块的粘合代码。

    ¥<codegenConfig.name>/<codegenConfig.name>-generated.mm: this contains the glue code of your custom iOS Turbo Native Modules.

  • <codegenConfig.name>JSI.h:这包含你自定义的 C++ Turbo Native 模块的接口。

    ¥<codegenConfig.name>JSI.h: this contains the interface of your custom C++ Turbo Native Modules.

  • <codegenConfig.name>JSI-generated.h:这包含自定义 C++ Turbo 原生模块的粘合代码。

    ¥<codegenConfig.name>JSI-generated.h: this contains the glue code of your custom C++ Turbo Native Modules.

  • react/renderer/components/<codegenConfig.name>:此文件夹包含你的自定义组件所需的所有粘合代码。

    ¥react/renderer/components/<codegenConfig.name>: this folder contains all the glue-code required by your custom component.

此结构是通过使用 codegenConfig.type 字段的值 all 生成的。如果你使用值 modules,则不会看到 react/renderer/components/ 文件夹。如果你使用值 components,则不会看到任何其他文件。

¥This structure has been generated by using the value all for the codegenConfig.type field. If you use the value modules, expect to see no react/renderer/components/ folder. If you use the value components, expect not to see any of the other files.