跳转至

Ink React 调和器专题

重要性:⭐⭐⭐⭐(React 终端渲染核心——yoga-layout + 字符输出 + 事件 + 焦点) 真实位置src/ink/(30+ 文件) 角色:Ink 是 React 的终端渲染器 —— 仿照 react-dom 但输出到 ANSI 关联topics/yoga-layout.mdtopics/yoga-layout-deep-dive


1. Ink 是什么

Ink = React for CLI - 写 React 组件 → 输出 ANSI 字符 - 同样的 JSX / hooks / state 模型 - 但 render 到 terminal buffer 而非 DOM

Claude Code 用 Ink —— 所有 UI 都是 React/Ink 组件。


2. src/ink/ 目录(30+ 文件)

ink/
├── ink.tsx                    ← 入口(导出 Box, Text, useInput, ...)
├── reconciler.ts              ← React reconciler(核心)
├── renderer.ts                ← 渲染器
├── root.ts                    ← Root container
├── instances.ts               ← Instance 类型
├── dom.ts                     ← DOM 抽象(484 行)
├── node-cache.ts              ← Node 缓存
├── output.ts                  ← Output 抽象
├── render-to-screen.ts        ← 渲染到屏幕
├── render-node-to-output.ts   ← 单 node 渲染
├── render-border.ts           ← 边框
├── line-width-cache.ts        ← 行宽缓存
├── measure-element.ts         ← 元素测量
├── measure-text.ts            ← 文本测量
├── colorize.ts                ← 颜色化(231 行)
├── Ansi.tsx                   ← ANSI 组件
├── bidi.ts                    ← BiDi(双向文本,139 行)
├── focus.ts                   ← 焦点管理(181 行)
├── hit-test.ts                ← 命中测试(130 行)
├── frame.ts                   ← 帧(124 行)
├── parse-keypress.ts          ← 按键解析
├── log-update.ts              ← log 更新
├── clearTerminal.ts           ← 清屏
├── get-max-width.ts           ← 最大宽度
├── optimizer.ts               ← 输出优化
├── constants.ts
├── components/                ← 基础组件
├── events/                    ← 事件系统
├── hooks/                     ← hooks
└── layout/                    ← 布局

30+ 文件 —— 完整 React 终端渲染器。


3. 4 大核心模块

3.1 reconciler.ts — React 调和器

Ink 的核心 —— 实现 React Reconciler API: - createInstance() —— 创建 instance - appendChild(), removeChild(), insertBefore() - commitUpdate() —— 更新 props - prepareUpdate() —— 检查是否需要更新 - getPublicInstance(), getRootHostContext(), getChildHostContext()

与 react-dom 类似 —— 但 host 是 terminal。

3.2 renderer.ts — 渲染器

rendering pipeline: - 创建 root - schedule updates - 应用到 terminal buffer - 写入 stdout

3.3 dom.ts — DOM 抽象(484 行)

虚拟 DOM —— 树形结构: - 节点(Box, Text, Custom) - 父子关系 - props - children

3.4 output.ts — Output 抽象

多输出目标: - stdout - stderr - string(测试用) - buffer


4. 渲染 pipeline(推测)

React.createElement()
reconciler.createInstance()
dom.ts 创建 node
yoga-layout 计算布局
render-to-screen 渲染
output 写入 buffer
stdout 输出

5 步 pipeline


5. 字符宽度处理

5.1 双宽字符

// measure-text.ts
function measureText(text: string): number {
  // CJK = 2, ASCII = 1
}

CJK 2 倍宽度 —— 终端兼容。

5.2 emoji

// emoji 宽度处理

emoji 1-2 宽度 —— 取决于终端。

5.3 ANSI escape

// colorize.ts 处理 \x1b[...

转义序列 —— 不计入显示宽度。

5.4 line-width-cache.ts

// 缓存行宽计算

缓存 —— 避免重复计算。


6. 6 大子系统

6.1 布局子系统

yoga-layout —— flexbox 算法。 - 已拆解(deep-dive-yoga-layout.md) - 4-slot cache - 60+ exports

6.2 输出子系统

output —— 写入 stdout。 - buffer 模式 - diff 模式(只写变化) - alternate screen

6.3 事件子系统

events —— 键盘 / 鼠标。 - useInput —— 全局键盘 - parseKeypress —— 按键解析 - 鼠标支持(推测)

6.4 焦点子系统

focus.ts(181 行)—— 焦点管理。 - 哪个 component 接收输入 - Tab 切换 - blur / focus 事件

6.5 测量子系统

measure-element + measure-text —— 动态测量。 - 异步测量(callback) - 缓存 - Yoga Measure function

6.6 边框 / 装饰

render-border + Ansi —— 视觉装饰。 - <Box borderStyle="round"> 之类 - 颜色 / 背景色 - 装饰字符


7. 优化子系统

7.1 optimizer.ts

输出优化 —— 减少 IO。 - diff 旧 vs 新 - 只写变化 - 重用字符串

7.2 node-cache.ts

节点缓存 —— 复用计算结果。

7.3 line-width-cache.ts

行宽缓存 —— 避免重复 measure。

7.4 log-update.ts

log 更新 —— 不重绘整屏。


8. 高级特性

8.1 AlternateScreen

<AlternateScreen mouseTracking={...}>
  {mainReturn}
</AlternateScreen>

备用屏幕 buffer —— 切换时不留痕迹。

8.2 Mouse Tracking

isMouseTrackingEnabled()  // 鼠标事件

鼠标支持 —— 推测实验性。

8.3 BiDi

// bidi.ts (139 行)
// 双向文本(阿拉伯 / 希伯来)

RTL 支持 —— 已实现。

8.4 Hit Test

// hit-test.ts (130 行)
// 哪个 node 在 (x, y) 位置

鼠标命中 —— 推测与 mouse 配合。


9. 与 react-dom 的对比

维度 react-dom Ink
目标 浏览器 terminal
节点 DOM node Yoga node
布局 CSS flexbox (Yoga)
输出 pixel ANSI chars
事件 DOM events stdin / mouse
测量 ResizeObserver Measure function
焦点 tabindex focus.ts
动画 CSS animation frame.ts

9 大差异 —— 但 React 模型一致。


10. 与 Claude Code 的集成

App.tsx (REPL)
<Box>, <Text>, <PromptInput>...
Ink 渲染
terminal

所有 UI 走 Ink。


11. 关键设计模式

11.1 Reconciler pattern

仿 react-dom —— 标准 React 渲染器。

11.2 Yoga 集成

flexbox 布局 —— 复用 Web 概念。

11.3 Buffer 模式

写整个 buffer —— 简单一致。

11.4 Diff 优化

只写变化 —— 减少 IO。

11.5 异步测量

callback 测量 —— Yoga Measure function。

11.6 AlternateScreen

不影响 scrollback —— 用户友好。


12. 关键洞察

12.1 Ink = React for CLI

React 模型一致 —— 开发者友好。

12.2 30+ 文件反映复杂度

简单"渲染"实则复杂 —— 30+ 子系统。

12.3 Yoga 是核心

布局 决定一切。

12.4 Buffer 模式 vs DOM

不增量 DOM —— 写整个 buffer 简单。

12.5 Diff 优化关键

不重写 —— 性能核心。

12.6 字符宽度处理

CJK / emoji / ANSI —— i18n 细节。

12.7 焦点系统独立

focus.ts 181 行 —— 单独子系统。

12.8 BiDi / RTL 完整

139 行 bidi.ts —— 罕见细节。

12.9 Hit Test 鼠标支持

130 行 —— 实验性。

12.10 AlternateScreen UX

干净切换 —— 商业级。


13. 阅读建议

  1. reconciler.ts —— 核心
  2. dom.ts —— DOM 抽象
  3. output.ts + render-to-screen.ts —— 渲染
  4. bidi.ts + focus.ts —— 高级特性
  5. optimizer.ts —— 性能

14. 与其他专题的关系

文件 关系
yoga-layout.md 布局算法
terminal-compatibility.md 终端兼容
error-codes.md Ink 错误