一、研究背景与动机
近年来,命令行终端(Terminal)作为系统工具与远程交互界面依旧保持强大的生命力。与浏览器相比,终端的约束更强,但同时也具备更高的可控性、可移植性与简洁性。与此同时,现代前端框架(如 React)在状态管理、组件化开发及声明式 UI 构建上拥有成熟的机制,但其主流渲染目标依旧局限于 DOM、Native、Canvas 或 PDF 等。
本项目的目标,是探索一种“非常规”但极具工程与研究价值的体系:
构建一套 DSL → React → TUI 的分层 UI 编译与渲染架构,实现“用 React 管理终端界面”的能力。
此方向具有高度的系统性特征,涉及编译器结构、DSL 设计、UI 抽象、React Reconciler、终端布局引擎等多个层面,非常契合系统方向博士生对于“如何统一抽象层级”的兴趣。尽管它未必产生商业价值,但其在方法论、架构设计与可组合性等层面具有潜在的科研探索空间。
二、问题定义
传统终端 UI 库(如 ratatui/tui-rs)提供的布局系统偏“声明式”,但缺乏现代组件化状态管理、缺乏结构化的 UI diff 能力。另一方面,React 并不能直接渲染进终端。
因此需要解决的核心问题是:
- 能否用 DSL 描述一份 Terminal UI?
- 能否通过 React 管理这份描述,让 UI 更新服从 React 状态机?
- 能否将 React 输出的虚拟节点转换为 TUI 库所能理解的布局结构?
- 能否构建一条类似“编译链”的 UI 流水线?
最终目标是:
输入任何 DSL 界面定义 → React 处理状态与组件 → TUI 库负责绘制。
三、系统架构与技术路线
系统整体结构可视为一个“UI 编译器”,分为前端 / 中端 / 后端三层。
1. 前端:DSL 设计与解析(Parser)
目标是构建一套用于描述终端布局的 DSL。
初期只支持两个组件:
<Grid>:声明布局(方向、行列数、对齐方式等)
<Text>:纯文本组件
DSL 可使用 Lisp 样式、类 JSX 样式或任意你偏好的形式。
流程:
- 编写 DSL(高层语言)
- 解析成 AST(可用 Tree-sitter 或手写 parser)
- 对 AST 中的计算(如 if/else、表达式绑定)进行求值
- 得到纯结构化、无控制流的中间 DSL(IR)
该 IR 是“语义已解析、仅剩结构与属性”的树状数据。
2. 中端:React Reconciler 层(组件状态管理)
React 在本项目中扮演中间层角色:
- 接收 DSL IR 转换的组件对象
- 管理组件生命周期、内部状态、diff 及更新
- 输出一棵“虚拟终端 DOM 树”(abstract layout tree)
你需要实现一个自定义的 React Renderer:
DSL IR → React Elements → Fiber Reconciliation → Abstract UI Tree
这棵树不是 HTML DOM,而是你定义的:
- Grid 节点
- Text 节点
- 节点属性(布局方式、文本内容、对齐方式等)
它就是你整个系统的“中间代码(mid-level IR)”。
3. 后端:TUI 渲染器(与 ratatui 等库对接)
终端库是编译器的后端:负责将中端 IR 转换为具体可执行的绘图指令。
你无需手动输出 ANSI 控制码,因为:
- ratatui / tui-rs 已具备成熟的声明式布局能力
- 你只需将 Grid → Layout、Text → Paragraph 等
对应关系示例:
React 中端节点 | TUI 库组件 |
Grid(dir=row, cols=3) | Layout(flex row, chunks=3) |
Text("hello") | Paragraph("hello") |
输出过程类似后端编译器将 IR 编译成目标机器码:
Abstract UI Tree → TUI Layout Objects → Terminal Rendering
四、预期创新点与研究价值
- 多抽象层统一模型
UI 设计通常割裂于不同工具链,本项目尝试将 DSL / React / Terminal 三层统一在单一编译框架中。
- 探索 React 作为“通用状态机”
验证 React 是否可以作为非 GUI、非 Web 的 UI 状态管理内核。
- 实际构建一条 UI 编译链
将“编译器的思路”用于 UI 渲染,这种模型可能启发更广泛的 UI 研究(跨平台 UI、声明式 UI、函数式 UI 等)。
- 终端 UI 的现代化
让传统终端 UI 获得组件化能力、diff 渲染能力。
- 潜在科研方向拓展
如:
- UI IR 设计
- 高层 DSL 到低层 UI 模型的映射
- 可组合的渲染管线
- UI 的 partial evaluation
- 在资源受限环境(如 SSH pty)中构建交互系统
这些都可以衍生为论文观点、系统设计研究、或学术 workshop demo。
五、实施计划(建议)
第一阶段:原型验证(1–2 周)
- 定义简单 DSL(仅 Grid / Text)
- 手写 parser 或用 Tree-sitter 构建 AST
- 输出纯结构 IR
第二阶段:React 中端实现(2–4 周)
- 使用
react-reconciler构建自定义 renderer
- 将 IR 转换为 React Elements
- 得到 Abstract UI Tree
第三阶段:TUI 后端渲染器(2 周)
- 选择 ratatui 作为渲染库
- 将 Abstract UI Tree 映射到 TUI layout
- 支持基本 diff + 重绘
第四阶段:实验性扩展(长期)
- 增加更多组件(Input、List、Tabs 等)
- 加入事件系统(键盘输入 → React)
- 更复杂的布局 DSL
- 更高效的 diff pipeline(减少 terminal flicker)
六、预期成果
- 一套完整的“终端 UI 编译框架”
- 一个能运行 React + TUI 的 SSH UI demo
- 一套 DSL(可扩展)及其解释器
- 一个中端 Abstract UI Tree 规范
- 和一篇可写成 workshop / demo paper 的研究原型