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:

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>"
}
},

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

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

  • name: 这是将用于创建包含你的规范的文件的名称。按照惯例,它应该有后缀 Spec,但这不是强制性的。

    ¥name: This is the name that will be used to create files containing your specs. As a convention, It should have the suffix Spec, but this is not mandatory.

  • type:我们需要生成的代码类型。允许的值是 modulescomponentsall

    ¥type: the type of code we need to generate. Allowed values are modules, components, all.

    • 如果只需要为 Turbo Native 模块生成代码,则 modules: 使用此值。

      ¥modules: use this value if you only need to generate code for Turbo Native Modules.

    • 如果只需要为 Native Fabric 组件生成代码,则 components: 使用此值。

      ¥components: use this value if you only need to generate code for Native Fabric Components.

    • all:如果你有组件和模块的混合,请使用此值。

      ¥all: use this value if you have a mixture of components and modules.

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

    ¥jsSrcsDir: this is the root folder where all your specs live.

  • android.javaPackageName:这是一个 Android 特定设置,让 Codegen 生成自定义包中的文件。

    ¥android.javaPackageName: this is an android specific setting to let Codegen generate the files in a custom package.

当 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:

./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 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:

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:

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 Native 模块的粘合代码。

    ¥<codegenConfig.name>JSI-generated.h: this contains the glue code of your custom 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.