convert wetty from submodule to normal directory
This commit is contained in:
318
wetty/xterminal-wetty-diff.md
Normal file
318
wetty/xterminal-wetty-diff.md
Normal 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 client:xterm.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. 完整连接态 UI(overlay、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 协议模型存在分叉,后续演进需先统一架构方向。
|
||||
|
||||
Reference in New Issue
Block a user