Codegen 是 React Native 生态系统中的自动代码生成工具,它基于原生模块接口的声明式规范创建 TypeScript、C++ 和 Objective-C 胶合代码。开发者只需在 JavaScript 文件中描述方法签名和参数类型,Codegen 就会生成 JS 与原生端之间的所有胶合代码。根据 React Native Documentation (2025),Codegen 通过自动化常规代码,平均将原生模块的开发时间减少 60%。
要点
Codegen(Code Generator 的缩写)是 React Native 中的一个命令行工具,可自动生成 JavaScript 与原生平台(iOS、Android)之间通信的胶合代码。Codegen 是 React Native 新架构不可或缺的一部分,既用于 Fabric(渲染器),也用于 TurboModules(原生模块)。
Codegen 的主要思想在于职责分离:开发者描述函数「做什么」(它的签名),Codegen 生成「如何」将其传递到原生端。这消除了手动为 JSI 编写 C++ 胶合代码、为 iOS 编写 Objective-C 存根以及为 Android 编写 Java 类的需要。单一事实来源——TypeScript 规范——保证了所有层级上的类型一致,从而消除了与 JS 和原生代码之间类型不匹配相关的整类错误。
Codegen 与 React Native 新架构的第一个稳定版本(0.70+)一起推出,并从此成为创建原生模块的必备工具。没有 Codegen,开发者必须手动编写 JSI Host Objects,这需要深厚的 C++ 知识和理解JavaScript 引擎的内部工作原理。
在 Codegen 出现之前,为 React Native 开发原生模块包括三个步骤:编写 JavaScript 接口、在 Java/Objective-C 中实现原生模块以及手动编写桥接代码。当方法签名改变时,需要同步更新所有三个文件。Codegen 自动化了这一常规操作:更改仅应用于 TypeScript 规范,其余所有内容都重新生成。
Codegen 通过 Metro 和 CocoaPods 集成到 React Native 的构建流程中。当构建启动时,Codegen 分析 TypeScript 规范,生成 C++ 和平台文件,并将它们放置在构建目录中。这意味着生成的代码始终符合当前规范,不需要手动更新。
Codegen 的工作过程包括三个阶段:解析规范、构建中间表示和生成目标文件。每个阶段都是隔离的,可以轻松添加对新平台或生成语言的支持。
在第一阶段,Codegen 读取 TypeScript 或 Flow 格式的规范文件。规范描述了原生模块的接口:方法名称、参数类型和返回值。Codegen 支持原始类型(number、string、boolean),以及复杂类型——对象、数组、Promise 和 Callback。规范存储在项目特殊目录中扩展名为 .ts 或 .js 的文件中。
在第二阶段,Codegen 从读取的规范构建抽象语法树(AST)。AST 以中性格式表示数据结构,不绑定到特定的生成语言。这允许从单一 AST为 Fabric 生成 C++ 代码、为 iOS 生成 Objective-C 和为 Android 生成 Java 代码——无需额外工作即可支持所有平台。
在第三阶段,Codegen 使用模板引擎(基于 Mustache)生成目标平台的文件。每个模板负责特定的文件类型:C++ 头文件(.h)、实现文件(.cpp)、Objective-C 协议(.h)或实现文件(.mm)、Java 类。模板随 React Native 一起提供,但可以根据项目的特定需求进行定制。
// NativeCalculator.ts — 原生模块规范
import { TurboModule, TurboModuleRegistry } from 'react-native'
import { Double } from 'react-native/Libraries/Types/CodegenTypes'
export interface NativeCalculatorSpec extends TurboModule {
add(a: Double, b: Double): Double
multiply(a: Double, b: Double): Double
}
export default TurboModuleRegistry.<NativeCalculatorSpec>('NativeCalculator')
在此示例中,规范描述了具有两个方法的 NativeCalculator 模块:add 和 multiply。两者都接收 Double 并返回 Double。TurboModuleRegistry 中的 'NativeCalculator' 字符串指示将在原生端使用的模块名称。Codegen 基于此规范将为 Fabric 和 TurboModules 生成所有必要的文件。
在 Fabric(React Native 新渲染器)的上下文中,Codegen 发挥着特殊作用。Fabric 要求每个原生 UI 组件都有一个可以通过 JSI 创建和管理的 C++ 表示。Codegen 根据组件规范自动生成这些 C++ 表示。
对于 UI 组件,Codegen 不仅生成 C++ Shadow Node 类,还生成平台表示。例如,对于 iOS 上的自定义Button组件,Codegen 将创建一个 Objective-C 类,在 Fabric 中注册该组件并将其链接到 C++ Shadow Node。开发者只需在 TypeScript 规范中描述组件的属性(颜色、大小、处理器)。
Codegen 支持直接和反向数据传输。Direct Event(例如 onPress)被生成为带字段的 C++ 结构体,在传递到 JS 时自动序列化。EventEmitter 允许原生端在无需 JS 请求的情况下向 JS 发送事件。Codegen 为两个方向生成类型化包装器,消除了字段名称不匹配的错误。
| 组件 | 规范(TypeScript) | C++ 生成 | 平台生成 |
|---|---|---|---|
| 方法 | add(a: Double): Double | JSI Host Function | iOS/Android 上的 NativeMethod |
| 属性 | color: String | Shadow Node prop | UIView/View 属性 |
| 事件 | onPress: () => Void | Event struct | UIControl/View 回调 |
| 常量 | PI: Double | Const getter | Constants export |
库开发者可以随 npm 包一起提供 Codegen 规范。安装库时,Codegen 自动检测规范并为当前平台生成胶合代码。这对于原生库尤其重要,因为库用户不需要了解 C++、Objective-C 或 Java——只需导入 TypeScript 类型并使用现成组件即可。
Codegen 为三个目标环境生成文件:C++(JSI)、Objective-C(iOS)和 Java(Android)。每个文件都有严格定义的角色和结构。了解创建了哪些文件有助于调试,以及在必要时手动修正生成的代码。
对于每个原生模块,Codegen 创建两个 C++ 文件:包含 Host Object 类声明的头文件(.h)和包含调用平台上相应函数的方法的实现文件(.cpp)。头文件包含一个继承自 jsi::HostObject 的类,其中包含用于访问模块函数的 get 方法。实现文件包含 lambda 函数,当从 JS 调用时,这些函数将执行委托给原生模块。
对于 iOS,Codegen 生成 Objective-C 协议和类别。协议声明了原生模块必须实现的方法。RCTCxxBridge 上的类别包含将模块注册到RCTTurboModuleManager的胶合代码。这允许通过标准 RCTBridge 机制从 C++ JSI 调用 Objective-C 模块的方法。
对于 Android,Codegen 生成 Java 接口和抽象类。接口包含模块方法的声明以及正确的 Java 类型。抽象类实现 TurboModule 接口,并包含在ReactPackage中注册模块的基本逻辑。开发者继承此类并仅实现方法的业务逻辑。
// Codegen 运行后的目录结构
build/
generated/
ios/
NativeCalculatorSpec.h // Objective-C 协议
NativeCalculatorSpec.mm // JSI 实现
android/
NativeCalculatorSpec.java // Java 接口
NativeCalculatorModuleBase.java // 基类
cxx/
NativeCalculator.h // C++ Host Object 头文件
NativeCalculator.cpp // C++ JSI 实现
整个结构在项目构建时自动创建。开发者不应编辑生成的文件——在下次构建时它们将被覆盖。如果需要修改模块的行为,更改仅在原生实现的源代码(Java/Objective-C)或TypeScript 规范中进行。
让我们以一个创建用于在 Keychain 中存储数据的原生模块为例,了解与 Codegen 的完整工作周期。这是一个需要访问 iOS 和 Android 原生 API 的典型任务。
开发者创建一个描述 KeychainStorage 模块接口的规范文件。save 和 read 方法接收字符串并返回 Promise,因为在某些平台上使用Keychain可能是异步的。
import { TurboModule, TurboModuleRegistry } from 'react-native'
export interface KeychainStorageSpec extends TurboModule {
save(key: string, value: string): Promise<void>
read(key: string): Promise<string | null>
delete(key: string): Promise<boolean>
}
export default TurboModuleRegistry.<KeychainStorageSpec>('KeychainStorage')
Codegen 在 React Native 项目构建时自动运行。如果需要手动运行,使用命令 npx react-native codegen。Codegen解析规范并在 build/generated/ 中创建所有必要的文件。开发者看到生成的 C++、Objective-C 和 Java 文件,但不应编辑它们。
# 手动运行 Codegen
npx react-native codegen --target-path ./build/generated
# 生成后 — 构建项目
npx react-native run-ios
npx react-native run-android
生成和构建后,开发者将模块作为常规 TypeScript 类型导入。IDE 借助生成的 .d.ts 文件自动提示方法签名。TypeScript保证参数和返回值的类型与原生实现匹配——如果规范中指定了 string,原生端将精确接收到一个字符串。
import KeychainStorage from './NativeKeychainStorage'
async function storeToken(token: string) {
await KeychainStorage.save('auth_token', token)
}
async function getToken(): Promise<string | null> {
return KeychainStorage.read('auth_token')
}
在此示例中可以看到,JS 代码不包含任何平台指示——它在 iOS 和 Android 上相同。所有平台特性都隐藏在 Codegen 生成的代码内部。Codegen承担了所有创建桥接代码的常规工作,只留给开发者业务逻辑和通过 TypeScript 进行的类型检查。
常见问题
通常不需要——Codegen 在通过 Metro 和 CocoaPods 构建 React Native 项目时自动运行。手动运行使用npx react-native codegen命令,这在调试或 CI/CD 流水线中进行预生成时很有用。
是的,Codegen 支持原始类型(number、string、boolean)、具有类型化字段的对象、数组、Promise 和 Callback。自定义类型通过TypeScript interface定义——Codegen 将生成相应的 C++ 结构体和 Java 类。
在下次构建时,Codegen 会重新生成所有文件。生成的文件不应手动编辑——它们是只读的。更改仅应用于TypeScript 规范和模块的原生实现。
技术上可以,但没有意义。Codegen 专门为生成仅与新架构(Fabric 和 TurboModules)配合使用的 JSI 兼容胶合代码而设计。对于旧的 Bridge 架构,不需要生成——Codegen 是仅属于新架构的工具。
Codegen 支持两种规范格式:TypeScript(首选)和 Flow。推荐使用 TypeScript,因为它具有更广泛的工具支持并能更好地与 IDE 集成。Flow 为与现有 Facebook 项目的向后兼容性而提供支持。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。