第 02 章:Monorepo 骨架与包边界
1. 根配置告诉我们什么
根 package.json 声明 Yarn 4 workspace:
json
{
"workspaces": ["apps/*", "packages/*"],
"engines": { "node": ">=22.12.0" },
"packageManager": "yarn@4.12.0"
}它不是把每个平台拆成多个仓库,而是让桌面、扩展、移动端、Web 和共享业务包在一个依赖图中协同演进。Native Home 的变更因此会同时触发 JS、Android、iOS、codegen 和 CI 的检查。
2. 与 Native Home 相关的最小子图
| 包/目录 | 在这条链路里的作用 |
|---|---|
apps/mobile | 移动端宿主;在 App.tsx 注册 Native Home renderer;读取原生 intent 并连接导航/Store |
packages/kit | 跨平台业务语义、Home Store、快照缓存、feature flag、页面 surface |
packages/native-components | 性能关键的 HomeContainer;TS 类型、Nitro HybridView、Surface/Slot、Swift/Kotlin |
packages/components | 通用 React Native UI 和导航组件,slot 内容会大量复用它们 |
packages/kit-bg | 后台状态和 Jotai atoms;Home renderer 从这里获取部分持久化状态/服务 |
packages/shared | 钱包/网络/类型/存储等跨端工具,Home ViewModel 用它处理金额、网络、地址 |
nitrogen/generated | Nitro 生成的 C++/Swift/Kotlin glue 和 JSON config,不应手写业务逻辑 |
3. 为什么 native-components 是独立包
packages/native-components/package.json 的描述是“Performance-critical native page containers for OneKey”。它把原生引擎从 kit 中分离,带来三个好处:
kit可以拥有 Home 业务和 React slot,但不需要知道 Swift/Kotlin 的内部 view 层级;- 原生包可以独立运行
tsc、Nitrogen codegen 和原生合同测试; - Nitro 的 peer dependency(React、React Native、Nitro modules、skeleton)可以保持可选,降低非移动端包的耦合。
4. App 入口不是 Home 页面本身
packages/kit/src/views/Home/NativeHomePageView.native.tsx 只做 context lookup:
tsx
const NativeRenderer = useNativeHomeRenderer();
if (NativeRenderer) {
return <NativeRenderer sceneName={sceneName} onPressHide={onPressHide} />;
}
throw new OneKeyLocalError('Native Home renderer is not registered');真正的实现由 apps/mobile/App.tsx 注入 NativeHomeRendererProvider。这样做把“页面抽象”留给 kit,把“当前 app 用什么 renderer”留给宿主;非 native 平台的 NativeHomePageView.tsx 仍然返回 null,避免把移动原生依赖渗透到 Web/桌面运行时。
5. 边界的工程含义
修改 HomeContainer 的 public type 时,至少需要同步:
- TS wrapper 的 props/ref/slot 展开;
HomeContainer.nitro.ts的 HybridView props/methods;- Nitrogen 生成结果;
- Swift 与 Kotlin 解码模型;
- iOS/Android contract tests;
MobileNativeHomeRenderer的 snapshot 生成与 intent 分发。
这就是为什么该功能的 CI workflow 只监听一个目录却能覆盖整个协议边界:.github/workflows/native-home-contract.yml 关注的正是这些跨层文件,而不是所有 wallet 业务代码。