Skip to content
目录

高频思考题与答题框架

1. React Native 新架构到底“新”在哪?

答题要点:

  • 渲染:Fabric(C++ renderer + 新的 UI 管线)
  • 模块:TurboModules(更明确的接口与调用链)
  • 运行:Bridgeless(弱化/替代传统 bridge 依赖)
  • 调度:RuntimeScheduler + 更明确事件循环语义

2. 为什么 RN 要强推新架构默认化?

答题要点:

  • 降低组合复杂度(避免“半新架构”)
  • 让生态库对齐统一目标
  • 用 interop + feature flags 缓冲迁移

可引用:DefaultNewArchitectureEntryPoint.kt 的校验与 deprecated 重载。

3. RN 如何做 Android 与 iOS 的编译兼容?

答题要点:

  • Android:Gradle 插件注入 codegen/autolinking/hermes 任务
  • iOS:Pods + Xcode 脚本 + post_install 改写编译配置
  • C++:自动生成 CMake/注册代码连接三方库

4. Codegen 在 RN 的意义是什么?

答题要点:

  • 解决跨语言接口一致性问题
  • 减少手写 glue code 与注册样板
  • 把生态库接入标准化(声明配置 -> 自动产物)

5. Autolinking 和 Codegen 的关系?

答题要点:

  • Autolinking 负责“发现与接入依赖”
  • Codegen 负责“生成类型安全/平台所需代码”
  • 两者在 preBuild 前被串联,保证编译图完整

6. Hermes 默认化背后的工程价值?

答题要点:

  • 不仅是性能,更是工具链统一
  • bundle/bytecode/sourcemap/debug 流程一致
  • 降低多引擎分叉维护成本

7. 你如何评价 RN 的工程化成熟度?

答题结构(推荐):

  1. Monorepo 与多包治理
  2. 跨语言构建编排(Gradle/Pods/C++/JS)
  3. 代码生成与自动接入机制
  4. 测试与发布流水线
  5. 生态迁移治理(issue/PR 驱动)

8. 如果你在业务中落地类似体系,会先做什么?

参考回答:

  • 先统一 build pipeline 与产物规范
  • 再把跨语言接口收敛为 schema + codegen
  • 最后把手工接线(autolinking 类问题)插件化

9. 如何回答“新架构有哪些坑”?

建议诚实表达三类风险:

  • 生态库兼容滞后(如 Fabric API 变更)
  • 构建脚本/工具链门槛变高
  • 调度语义变化引发历史时序依赖问题

然后补一句:RN 官方通常通过 RFC、feature flags、兼容回填 PR 来降低迁移摩擦。

10. 一段 40 秒电梯演讲式总结

“我理解的 React Native 已经不是简单的 JS 桥接框架,而是 New Architecture 驱动的跨语言运行时工程。它通过 Fabric/TurboModules/Bridgeless 统一架构方向,用 RuntimeScheduler 明确事件循环语义,再通过 Gradle 插件、Pods 脚本、Codegen 和 Autolinking 把多平台构建工程化。Hermes 默认化与预编译体系则保证了性能和交付效率。我的学习重点不是 API 记忆,而是理解这些设计为什么能在大规模生态下持续演进。”

11. 直接使用 React Native Core 时,有哪些最佳实践和错误用例对照?

结论表述(先说结论)

  • 最佳实践是:遵循官方默认工程链路(New Architecture 默认、Hermes 默认、框架命令驱动 iOS 依赖准备),尽量少做“逆默认”的手工流程。
  • 常见错误是:手工绕开工具链在新架构下沿用旧心智,导致构建失败、崩溃或行为误判。

最佳实践 vs 错误用例(可直接背)

  1. iOS 依赖安装方式
  • 最佳实践:优先用 yarn ios / npx expo run:ios 这类框架命令,由其统一处理 CocoaPods/SPM 过渡。
  • 错误用例:长期直接 pod install 作为唯一入口。
  • 依据:react_native_pods.rb 已有 deprecation 提示;社区讨论也明确“推荐使用框架命令而非直接 pod install”(discussion #924)。
  1. 架构开关认知
  • 最佳实践:按“新架构是主路径”来配置和排查问题。
  • 错误用例:仍试图依赖 RCT_NEW_ARCH_ENABLED=0 作为常态方案。
  • 依据:仓库脚本与默认入口均体现新架构默认化(本仓源码);官方 0.82 语义也强化该方向。
  1. Bridgeless 下 Native Module 访问方式
  • 最佳实践:理解 TurboModule 的 lazy-load 语义,必要时从 prototype 读取方法。
  • 错误用例:直接 Object.keys(nativeModule) 期待拿到完整方法列表。
  • 依据:issue #46779(官方回复:这是设计取舍,建议 Object.keys(Object.getPrototypeOf(nativeModule)))。
  1. 三方库迁移节奏
  • 最佳实践:在升级新架构前先评估关键依赖是否完成迁移。
  • 错误用例:核心库未适配就全量开启 bridgeless,线上/测试环境直接踩崩溃。
  • 依据:issue #46686(iOS bridgeless 崩溃案例,讨论指出 interop gap 与库迁移状态相关)。
  1. iOS Native 模块签名一致性
  • 最佳实践:Swift/ObjC 导出签名严格一致,尤其是 RCT_EXTERN_METHOD 对齐。
  • 错误用例:Swift 方法改成 throws 但导出签名未同步,触发崩溃。
  • 依据:同一 issue #46686 讨论中的实战反馈。

代码级对照(可直接展示)

  1. iOS 依赖准备命令

错误用例(把 pod install 当唯一入口)

bash
cd ios
pod install

最佳实践(走框架命令,兼容 CocoaPods/SPM 迁移)

bash
# Community CLI 路径
yarn ios

# Expo 路径
npx expo run:ios
  1. Bridgeless 下 NativeModule 方法枚举

错误用例(直接枚举实例)

javascript
import {NativeModules} from 'react-native';

const mod = NativeModules.MyNativeModule;
console.log(Object.keys(mod)); // Bridgeless 下可能为空或不完整

最佳实践(枚举 prototype)

javascript
import {NativeModules} from 'react-native';

const mod = NativeModules.MyNativeModule;
console.log(Object.keys(Object.getPrototypeOf(mod)));
  1. iOS NativeModule 签名一致性(Swift + ObjC 导出)

错误用例(Swift 方法改了 throws,导出签名没变)

swift
@objc(MyModule)
class MyModule: NSObject {
  @objc func install(_ viewId: NSNumber, filterOptions: NSArray) throws {
    // ...
  }
}
objc
// RCT_EXTERN_METHOD 没有体现 throws 带来的签名变化,容易崩溃
RCT_EXTERN_METHOD(install:(nonnull NSNumber *)viewId
                  filterOptions:(nonnull NSArray *)filterOptions)

最佳实践(Swift/ObjC 导出签名严格对齐)

swift
@objc(MyModule)
class MyModule: NSObject {
  @objc func install(_ viewId: NSNumber, filterOptions: NSArray) {
    // ...
  }
}
objc
RCT_EXTERN_METHOD(install:(nonnull NSNumber *)viewId
                  filterOptions:(nonnull NSArray *)filterOptions)
  1. Android 打包任务认知(debug/release)

错误用例(把 release 也当成完全依赖 Metro)

gradle
react {
  // 配错后可能导致发布变体缺 bundle
  debuggableVariants = ["debug", "release"]
}

最佳实践(仅将调试变体设为 debuggable)

gradle
react {
  // 默认 debug 走 Metro;release 走 bundle + hermesc
  debuggableVariants = ["debug"]
}

可复述的一句话

“直接用 RN Core 没问题,但要顺着官方默认链路走:新架构/Hermes/工具链命令优先;一旦逆默认或混用旧心智,最容易在 bridgeless 互操作和 iOS 签名细节上出问题。”

12. Android 和 iOS 底层编译、打包分别用什么?

Android(底层工具链)

  • 构建系统:Gradle + Android Gradle Plugin
  • RN 集成层:React Native Gradle Plugin(RNGP)
  • JS 打包:Metro bundling(由 Gradle task 调用 CLI)
  • JS 编译:Hermes 编译器 hermesc(非 debug 变体常见)
  • SourceMap:compose-source-maps 合并 packager 与 compiler map
  • Native/C++:NDK + CMake(新架构库接入含自动生成的 autolinking CMake/CPP)

参考:

  • 官方文档:React Native Gradle Plugin
  • 本仓源码:packages/gradle-plugin/.../ReactPlugin.ktTaskConfiguration.ktBundleHermesCTask.kt

iOS(底层工具链)

  • 构建系统:Xcode / xcodebuild(clang/swiftc/ld)
  • 依赖管理:当前主流仍是 CocoaPods(并在向 SPM 过渡)
  • RN 集成层:use_react_native! + react_native_post_install 脚本体系
  • JS 打包:react-native-xcode.sh 调 Metro CLI 生成 bundle/assets
  • JS 编译:Hermes 开启时调用 hermesc 产出字节码 bundle
  • SourceMap:脚本阶段做 compose,保证调试可追踪

参考:

  • 脚本入口:packages/react-native/scripts/react-native-xcode.sh
  • Pods 入口:packages/react-native/scripts/react_native_pods.rb

标准答法(30 秒)

“Android 侧是 Gradle + RNGP 驱动,RNGP 在变体维度编排 Metro 打包、Hermes 编译、Codegen 和 Autolinking;iOS 侧是 Xcode 构建配合 RN 的 Pods/Xcode 脚本,react-native-xcode.sh 负责 bundle 和 Hermes 字节码。两端都不是‘只打 JS 包’,而是 JS 与 Native/C++ 的联合构建流水线。”

MIT License.