convert wetty from submodule to normal directory

This commit is contained in:
douboer@gmail.com
2026-03-03 16:07:18 +08:00
parent 1db76701a6
commit 0d185d2b3c
131 changed files with 15543 additions and 1 deletions

View File

@@ -0,0 +1,318 @@
# xterminal 与 wetty client 详细差异对比
## 1. 对比范围与结论
本文对比对象:
- `xterminal``/Users/gavin/lab/xterminal`
- `wetty` 当前项目前端 client`/Users/gavin/lab/wetty/src/client/wetty/**`(以及其页面与配置面板)
核心结论:
1. 两者不是同层替代关系。`xterminal` 是前端终端组件库,`wetty client` 是完整 Web SSH 网关客户端。
2. `wetty client` 的核心能力来自 `xterm.js` 真终端仿真;`xterminal` 核心是“CLI 交互组件”,终端协议能力主要由业务层补齐。
3. 若目标是“做 SSH/PTY 级别会话”,`wetty client` 路线更直接;若目标是“嵌入式 Web CLI 组件”,`xterminal` 更轻更可控。
---
## 2. 产品定位与边界
### xterminal组件库定位
- 对外是 `XTerminal` 类 API`mount/write/history/setCompleter/pause/resume/dispose`)。
- 不绑定任何固定后端协议,网络连接由业务方自行实现。
- 证据:
- `source/index.ts:14`(类定义)
- `source/index.ts:95`(挂载)
- `source/index.ts:53`(输出 API
- `source/index.ts:90`(补全)
### wetty client业务客户端定位
- 页面入口直接完成:终端初始化、断线重连 UI、网关连接、数据收发。
- 与运行配置、网关协议、页面 DOM 强耦合。
- 证据:
- `src/client/wetty.ts:26`(启动终端)
- `src/client/wetty.ts:38`socket 事件链)
- `src/client/wetty/socket.ts:43`(网关 socket 实现)
---
## 3. 渲染与终端仿真能力
### wetty clientxterm.js 终端仿真
- 直接继承 `@xterm/xterm``Terminal`
- 加载了 `FitAddon``WebLinksAddon``ImageAddon`
- 原生具备终端仿真语义(光标、控制序列、窗口 resize、链接识别等
- 证据:
- `src/client/wetty/term.ts:13`
- `src/client/wetty/term.ts:21`
- `src/client/wetty/term.ts:23`
- `src/client/wetty/term.ts:24`
### xterminal组件渲染模型
- 输出层以 HTML 片段写入为主。
- 核心库不自带完整 VT/ANSI 终端协议仿真。
- ANSI 处理与网关协议示例主要存在于 demo 脚本,不在库核心 API。
- 证据:
- `source/output/index.ts:40`
- `source/output/index.ts:49`
- `demo/main.js:381`ANSI 转换)
---
## 4. 输入模型差异(交互体验关键)
### wetty client按键流streaming input
- 用户每次按键通过 `term.onData` 立即发送到后端。
- 更接近真实 SSH TTY 行为(如逐字符编辑、交互式全屏程序)。
- 证据:
- `src/client/wetty.ts:60`
### xterminal行输入line-based
- 默认在 `Enter` 时触发 `data` 事件并提交一整行。
- 上下箭头与历史命令是组件内建行为。
- 证据:
- `source/instance.ts:136`Enter 分支)
- `source/instance.ts:141`emit data
- `source/instance.ts:147`(历史导航)
影响:
1. 需要 PTY 级“实时按键”时,`xterminal` 必须由业务层额外桥接按键事件。
2. 需要“类 REPL 文本命令输入”时,`xterminal` 默认体验更简单。
---
## 5. 协议与连接层
### wetty client内置网关协议适配
- 内建 `GatewaySocket`,封装事件 `connect/login/data/logout/disconnect/error`
- 支持 `init/stdin/resize/control` 帧。
- 自动处理 `ping/pong``connected``disconnect` 控制帧。
- 证据:
- `src/client/wetty/socket.ts:3`
- `src/client/wetty/socket.ts:57`
- `src/client/wetty/socket.ts:103`
- `src/client/wetty/socket.ts:238`
### xterminal协议在业务层demo实现
- 核心库无 WebSocket 协议绑定。
- demo 中手工实现网关连接、帧发送、回包处理、排队与批量 flush。
- 证据:
- `demo/main.js:635`connectByConfig
- `demo/main.js:572`handleGatewayFrame
- `demo/main.js:501`stdin 发送)
---
## 6. 配置系统与可配置能力
### wetty client
- 运行时读取 `/terminal.config.json`,并做最小字段校验、选中 server 逻辑。
- 有 iframe 配置面板,可改大量 xterm 选项并持久化 `localStorage.options`
- 证据:
- `src/client/wetty/runtimeConfig.ts:77`
- `src/client/wetty/runtimeConfig.ts:107`
- `src/client/wetty/term/confiruragtion.ts:8`
- `src/client/wetty/term/load.ts:10`
- `src/assets/xterm_config/index.html:62`
### xterminal
- 核心库配置简单(主要是挂载 target
- 无内建“终端参数 GUI 编辑器”,这部分由业务层自行实现。
- 证据:
- `source/types.d.ts:103`
---
## 7. 移动端策略对比
### wetty client
- 对 xterm 屏幕加 `contenteditable` 以触发软键盘。
- 页面内置功能键浮层方向键、Esc、Ctrl、Tab
- 证据:
- `src/client/wetty/mobile.ts:3`
- `index.html:28`
- `src/client/wetty/term.ts:190`
### xterminal
- 核心对移动端做了更系统处理:
- 隐藏 textarea + 自绘光标
- `visualViewport` 监听,动态补偿软键盘遮挡
- 避免 iOS Safari 聚焦导致 body 整体上推
- 证据:
- `source/instance.ts:58`
- `source/renderer/index.ts:27`
- `theme/index.css:68`
结论:
1. `wetty` 的移动端更偏“终端页面增强”。
2. `xterminal` 的移动端更偏“组件内部自洽”。
---
## 8. 安全与风险点
### 8.1 前端渲染安全
- `xterminal` 提供 `writeSafe/escapeHTML`,明确区分不可信文本输出路径。
- 证据:
- `source/index.ts:61`
- `source/output/index.ts:19`
- `wetty` 断线信息使用 `innerHTML` 注入文本,若消息来源不可信有注入风险。
- 证据:
- `src/client/wetty/disconnect.ts:9`
### 8.2 配置泄露风险
- 两边当前 `terminal.config.json` 都包含明文密码,属于高风险配置习惯(即使是开发环境)。
- 证据:
- `/Users/gavin/lab/wetty/terminal.config.json`
- `/Users/gavin/lab/xterminal/terminal.config.json`
---
## 9. 特性差异清单(功能维度)
### wetty client 独有/更强
1. xterm.js 终端仿真与 addon 生态。
2. 现成文件下载控制序列解析(`ESC[5i` / `ESC[4i`)。
3. 完整连接态 UIoverlay、reconnect、配置侧栏
4. 网关初始化载荷构造(含证书/私钥/密码多认证类型)。
证据:
- `src/client/wetty/download.ts:4`
- `src/client/wetty/download.ts:76`
- `src/client/wetty/socket.ts:161`
- `index.html:14`
### xterminal 独有/更强
1. 组件化 API 清晰,易嵌入任意前端。
2. 事件总线与资源释放边界明确(`dispose``register`)。
3. 历史记录与补全接口简洁。
4. 测试覆盖相对更系统input/output/history/emitter/xterminal
证据:
- `source/index.ts:117`
- `source/emitter/index.ts:16`
- `tests/xterminal.test.ts:4`
- `tests/input.test.ts:5`
---
## 10. 工程化与依赖体量
### 依赖与发布目标
- `wetty`
- 运行时依赖较重(含 `@xterm/*``express``socket.io``node-pty` 等)。
- 发布目标是应用(`bin/main` + server + client
- 证据:`package.json:44`dependencies
- `xterminal`
- 核心 runtime 无 dependencies仅 devDependencies
- 发布目标是库UMD + ESM + CSS + types
- 证据:`package.json:64`devDependencies`rollup.config.js:31`
### 产物规模(当前工作区构建结果)
- `wetty` client bundle`build/client/wetty.js``511K`(含 source map 更大)。
- `xterminal` dist`xterminal.esm.js``8.5K``xterminal.umd.js``16K`
结论:
1. 若只需要嵌入命令交互 UI`xterminal` 体量优势明显。
2. 若需要终端仿真,`wetty`/xterm.js 的体量属于能力成本。
---
## 11. 测试对比
- `wetty` 当前仓库测试集中在:
- 客户端 `FileDownloader`
- 服务端 shell escaping
- 证据:`src/client/wetty/download.spec.ts:10``src/server/shared/shell.spec.ts:5`
- `xterminal` 测试覆盖:
- `xterminal/input/output/history/emitter/disposable/reactivity`
- 证据:`/Users/gavin/lab/xterminal/tests/*.test.ts`
---
## 12. 当前项目内一个关键不一致点
在当前 `wetty` 仓库中,前端 client 已改为“网关 WebSocket 帧协议”,但后端原有代码仍是 Socket.IO 事件模型(`input/resize/commit`)。
- 前端证据:`src/client/wetty/socket.ts:97`
- 后端证据:`src/server/spawn.ts:38``src/server/socketServer/socket.ts:38`
这意味着:
1. 当前 client 与本仓库原 server 不天然对接。
2. client 实际更像在对接外部网关服务,而不是本地 wetty server。
---
## 13. 选型建议(按目标场景)
### 选 wetty client 路线
适合:
1. 目标是“浏览器里完整 SSH 终端”。
2. 需要 xterm.js 级别兼容能力(控制序列、终端行为一致性)。
3. 接受更重依赖与更复杂调试链路。
### 选 xterminal 路线
适合:
1. 目标是“可嵌入、可定制、轻量 CLI 组件”。
2. 协议、渲染、会话行为希望完全可控。
3. 可接受自行补齐 SSH/ANSI/PTY 的业务层逻辑。
---
## 14. 如果要做“xterminal + wetty 能力融合”,推荐最小改造路径
1. 保持 `xterminal` 作为 UI 输入输出壳,不直接替换为 xterm.js。
2. 单独抽出 `gateway client` 模块(`connect/send/receive/reconnect`),不要继续写在 demo/page 脚本。
3. 定义统一帧协议适配层,把 `init/stdin/resize/control/stdout/stderr/error` 规范化。
4. 将 ANSI 渲染器从 demo 抽为独立模块补测试尤其是跨帧、退格、CR/LF
5. 最后再评估是否有必要迁移到 xterm.js仅在终端兼容性成为瓶颈时
---
## 15. 风险清单(落地前需确认)
1. 明文密码配置必须替换(令牌化或后端临时凭据)。
2. 断线错误信息渲染方式应改为安全文本输出(避免 `innerHTML` 注入)。
3. 若要支持交互式全屏程序vim/top/tmux需确认输入模型是按键流而非行输入。
4. 若继续沿用移动端触控条,需要统一“焦点不丢失”的处理策略(当前两项目实现不同)。
---
## 16. 快速摘要(一页版)
1. `xterminal` 是“轻量终端 UI 组件库”;`wetty client` 是“完整 Web SSH 客户端”。
2. `wetty` 的强项是 xterm.js 终端仿真;`xterminal` 的强项是组件化、轻量、可嵌入。
3. 两者可融合,但不是无缝替换;最大差异在输入模型、协议耦合、终端仿真深度。
4. 当前 `wetty` 仓库里 client/server 协议模型存在分叉,后续演进需先统一架构方向。