1. 建立源码地图



第一版 React Native 的目录可以先压成一条主线来记:



rust 复制代码
Examples  ->  Libraries  ->  React  ->  packager
业务示例       JS 框架层      iOS 实现层    打包工具



Examples 是业务示例,Libraries 是暴露给 JS 的框架层,React(旧名 ReactKit)是 iOS Native 实现层,packager 负责把 JS 源码打成 bundle。下面逐个目录拆开看。

1. 根目录概览

源码主线只有四个目录,其余都是工程化辅助:



swift 复制代码
源码主线
  Examples / Libraries / React / packager


工程化辅助
  IntegrationTests   iOS 集成测试
  docs               facebook.github.io 文档源
  website            文档站 Jekyll 源
  react-native-cli   CLI npm 包
  lint               lint 规则配置
  cli.js             顶层 CLI 入口
  init.sh            初始化脚手架脚本
  linter.js          lint 运行脚本
  React.podspec      iOS CocoaPods 集成
  package.json       JS 工程配置
  .flowconfig        Flow 静态类型
  .travis.yml        CI 配置
  jestSupport        Jest 测试支持
  runXcodeTests.sh   Xcode 测试脚本





名称 类型 初步判断
Examples 目录 示例 App / 业务入口
Libraries 目录 JS 框架层
React 目录 iOS Native 实现层(旧称 ReactKit)
packager 目录 JS 打包工具
IntegrationTests 目录 iOS 集成测试
docs 目录 文档源
website 目录 文档站源
react-native-cli 目录 CLI npm 包
lint 目录 lint 规则
jestSupport 目录 Jest 测试支持
cli.js 文件 顶层 CLI 入口
init.sh 文件 脚手架初始化脚本
linter.js 文件 lint 运行脚本
package.json 文件 JS 工程配置
React.podspec 文件 iOS CocoaPods 集成
runXcodeTests.sh 文件 测试脚本
.flowconfig 文件 Flow 类型配置
.travis.yml 文件 CI 配置
.eslintrc 文件 ESLint 规则



阅读时:业务示例 Examples、JS 框架 Libraries、iOS 实现 React、工具与配置(packager / jestSupport / docs / website / CLI)。

2. 从 TicTacToe 看启动链路

入口选 Examples/TicTacToe,理由是它够小:一个井字棋,刚好能完整串起「Native 启动 → JS 渲染」而不被业务逻辑干扰。

它有两个入口文件:



入口 文件 作用
iOS 入口 Examples/TicTacToe/TicTacToe/main.m 启动 iOS App,进入 AppDelegate
JS 入口 Examples/TicTacToe/TicTacToeApp.js 注册并渲染 RN 根组件



整条启动链路:



rust 复制代码
main.m
  -> AppDelegate.m
  -> RCTRootView
  -> 加载 JS bundle
  -> 执行 TicTacToeApp.js
  -> AppRegistry.registerComponent('TicTacToeApp', ...)
  -> 渲染 TicTacToeApp



main.m 是标准 iOS 入口,它启动 AppDelegate:



objectivec 复制代码
int main(int argc, char * argv[]) {
  @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}



真正把 RN 接进来的是 AppDelegate.m:



ini 复制代码
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/TicTacToe/TicTacToeApp.includeRequire.runModule.bundle"];


RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                   moduleName:@"TicTacToeApp"
                                                launchOptions:launchOptions];



这里只有两个关键点:

  • jsCodeLocation 指向 packager / dev server 生成的 JS bundle。
  • moduleName:@"TicTacToeApp" 必须和 JS 里的注册名一致。

JS 侧对应的就是:



javascript 复制代码
AppRegistry.registerComponent('TicTacToeApp', () => TicTacToeApp);



所以 TicTacToe 的意义不在井字棋本身,而是用最小例子把这条链串起来:



rust 复制代码
Native 启动 -> 加载 JS bundle -> 执行 JS -> 找到注册的根组件 -> 渲染 RN 页面



3. Libraries 目录:暴露给 JS 的框架层

Libraries 是第一版 RN 给业务 JS 用的框架层,但它不是纯 JS 目录------Text、Image、Network 这几个目录同时装着 JS 和 Native 两侧的代码。

按能力分组看:



r 复制代码
框架出口
  Libraries/react-native


JS 应用入口
  Libraries/AppRegistry          <- Native 通过它进入业务 JS


组件能力
  Libraries/Components / Libraries/Text / Libraries/Image


样式能力
  Libraries/StyleSheet


通信能力
  Libraries/BatchedBridge


JS 引擎初始化
  Libraries/JavaScriptAppEngine  <- 设置全局对象、JSTimers、错误处理


设备与交互
  Libraries/Device / Libraries/Interaction
  Libraries/Geolocation / Libraries/Vibration / Libraries/AppStateIOS


网络能力
  Libraries/Fetch / Libraries/Network
  (XMLHttpRequest.ios.js 在 Network/ 里,不是独立目录)


调试
  Libraries/RCTWebSocketDebugger


动画
  Libraries/Animation


React 自身
  Libraries/vendor/react         <- 第一版内联 React,不走 npm


工具
  Libraries/Utilities / Libraries/Storage



JS 目录与 Native 实现的对应关系:



能力 JS 目录 对应的 Native 目录 / 文件
框架出口 Libraries/react-native 多个 Native 模块
JS 应用入口 Libraries/AppRegistry React/Base/RCTRootView(Native 触发)
通用组件 Libraries/Components React/Views/RCTViewManager 等
文本组件 Libraries/Text/Text.js Libraries/Text/(含 RCTText、RCTTextManager、RCTShadowText)
图片组件 Libraries/Image/Image.ios.js Libraries/Image/(含 RCTStaticImage、RCTNetworkImageView、RCTImageDownloader)
输入框 Libraries/Components(TextInput) React/Views/RCTTextField*
样式 Libraries/StyleSheet React/Layout/Layout.c
通信 Libraries/BatchedBridge React/Base/RCTBridge
网络 Libraries/Fetch + Libraries/Network Libraries/Network/RCTDataManager.m
JS 引擎初始化 Libraries/JavaScriptAppEngine/Initialization React/Executors/RCTContextExecutor
调试 Libraries/RCTWebSocketDebugger React/Executors/RCTWebViewExecutor
React 自身 Libraries/vendor/react ---



4. React 目录(旧称 ReactKit):iOS Native 实现层

React 是 RN 在 iOS 上的全部 Native 实现。它的职责可以拆成五块:加载并执行 JS(Executors)、维护 Bridge(Base)、创建 Native View(Views)并用 UIManager 调度它们(Modules)、做 Flex 布局(Layout 里的 C 算法),以及通过 UIView+React 这个 Category 给所有 UIView 注入 RN 寻址能力。

子目录职责



markdown 复制代码
Base
  Native 侧基础设施。RCTRootView / RCTBridge 在这里,
  还有 RCTBridgeModule / RCTJavaScriptExecutor 两个协议,
  以及 RCTConvert / RCTLog / RCTAssert / RCTDevMenu / RCTRedBox 等。


Executors
  JS 执行环境。
    RCTContextExecutor   <- JavaScriptCore,生产路径
    RCTWebViewExecutor   <- WebView,调试路径


Views
  iOS 原生视图映射。
    给所有 UIView 注入 reactTag / reactSubviews
    是 Bridge 用 reactTag 寻址 Native 视图的物理基础


Modules
  Native 能力模块。最关键的是 RCTUIManager
    整个 Native UI 调度的总管
    注意:UIManager 在 Modules,不在 Views


Layout
  只有 Layout.h / Layout.c 两个文件
    css-layout(Yoga 前身)的 C 实现
    iOS 直接调用,是第一版 Flex 布局的物理来源



React.xcodeproj 里几个必读类



作用
RCTRootView 根视图
RCTBridge Bridge 调度核心
RCTBridgeModule Native Module 协议(第五/七章 必读)
RCTJavaScriptExecutor JS 执行器协议(第四章第 2 节必读)
RCTContextExecutor JS 执行器 JSC 实现
RCTWebViewExecutor JS 执行器 WebView 实现(调试用)
RCTUIManager Native UI 调度总管(在 Modules,不在 Views)
RCTViewManager Native View 工厂基类
RCTShadowView 影子树(在 Views,不在 Layout)
RCTTouchHandler 触摸事件
RCTEventDispatcher 事件分发
RCTConvert props 类型转换
UIView+React 给所有 UIView 注入 reactTag 的 Category
RCTDataManager 网络模块(实际在 Libraries/Network/,不在 React/Modules/)



持有与调度关系



objectivec 复制代码
RCTBridge ──持有──▶ RCTContextExecutor / RCTWebViewExecutor
RCTBridge ──持有──▶ RCTUIManager
RCTBridge ──持有──▶ RCTTouchHandler / RCTEventDispatcher


RCTUIManager ──调度──▶ RCTViewManager
RCTViewManager ──工厂──▶ RCTView / RCTShadowView


RCTRootView ──持有──▶ RCTBridge
RCTRootView ──持有──▶ RCTTouchHandler


RCTConvert ──被调用──▶ RCTViewManager(解析 props)
RCTShadowView ──调用 C 算法──▶ Layout.c
UIView+React ──注入──▶ 所有 RCTView 系列(Category,物理上修改 UIView 类)



5. packager 目录:把 JS 开发方式带进原生 App

packager 是 RN 能用 JS 写原生 App 的关键工具之一。它做的事只有一句话:

把 JS 源码处理成 iOS App 能请求、能执行的 bundle。

所以后面在 AppDelegate.m 里看到的这个地址,



arduino 复制代码
http://localhost:8081/TicTacToeApp.bundle



不是凭空冒出来的------它就是向 packager / dev server 请求一个动态构建好的 bundle。开发期还能靠它做热重载和快速调试。这一段的细节留到第 7 篇的打包链路展开,这里只需要记住它在地图上的位置。

相关推荐
西部荒野子2 小时前
3.RCTRootView 加载 Bundle 流程
前端
西部荒野子2 小时前
2.iOS 启动到 RCTRootView
前端
scan7242 小时前
SystemMessage,HumanMessage,AIMessage,ToolMessage
开发语言·前端·javascript
AI_零食2 小时前
鸿蒙PC Electron跨平台应用开发:辗转相除法计算器实现详解
前端·学习·华为·electron·开源·鸿蒙·鸿蒙系统
rising start2 小时前
二、Vue3 核心基础:API 对比、Setup 与响应式详解
前端·javascript·vue.js
ofoxcoding3 小时前
MiniMax M3 实测手记:踩完坑之后,我总结了报错处理和省 token 的几个办法
java·前端·人工智能·ai
YG亲测源码屋3 小时前
html表白代码大全可复制免费 html表白网页制作源码
前端·html
夜雪闻竹3 小时前
React Query + REST API 最佳实践
前端·react.js·前端框架
段ヤシ.3 小时前
回顾Java知识点,面试题汇总Day12:tomcat、 Java Web(持续更新)
java·前端·tomcat·java web