在终端中运行
使用 text run 在终端中全屏运行同一仪表盘。
本章内容
- `text run`
- 按 `q` 退出
- 自己的 CLI
- 差异
text run 在终端中运行同一个应用。布局、组件、按键映射和路由处理程序共用,输出为真彩色 ANSI,而非 %c CSS span。
text run
添加一个脚本并运行:
package.json+2-1json
"scripts": { "dev": "text dev", "build": "text build",移除: "start": "text start"新增: "start": "text start",新增: "tui": "text run" },bun run tui # render ./app at /bun run tui -- --path /deployments # start on another routetext run 导入 app/ 中的所有文件,使用内存中的历史记录挂载 App Router,并全屏绘制。<Link>、useRouter()、notFound() 和 redirect() 的用法不变,同源 fetch("/api/…") 调用会在进程内运行你的路由处理程序。Ctrl+C 退出并恢复终端的回滚缓冲区。此命令需要 Bun。
按 q 退出
终端用户习惯按 q 退出。useApp().exit() 卸载应用并恢复终端;在浏览器中则卸载控制台应用。
app/layout.tsx+3tsx
新增:import { useApp } from "@textjs/app";export default function RootLayout({ children }: { children?: ReactNode }) {新增: const app = useApp(); useInput((e) => { if (e.key === "backspace") router.back();新增: if (e.input === "q") app.exit(); });自己的 CLI
对于单个组件,使用 renderToTerminal。它无需 App Router 即可挂载一个元素,而 fetch("/api/…") 只有在 text run 下才能调用路由处理程序,因此要将数据传给组件:
cli.tsxtsx
import { renderToTerminal } from "@textjs/app/terminal";import { Table } from "@textjs/app";import { DEPLOYMENTS } from "./lib/deployments";const columns = [{ key: "commit", header: "Commit" }, { key: "project", header: "Project", width: 10 }];const app = await renderToTerminal(<Table columns={columns} rows={DEPLOYMENTS} autoFocus />);await app.waitUntilExit();使用 bun cli.tsx 运行。DeploymentsPage 会获取行数据,因此需要 text run。
差异
终端重绘更快(最高 60 fps,而非约 15 fps),网格尺寸随窗口调整,而非随停靠的控制台调整。图像需要像素数据,而非 URL。其余部分,包括这个仪表盘,都使用相同的代码。
试用
这是本章结束时的 Acme Deploys,正在 DevTools 中运行。点击输入区,然后使用下列按键。
▼ 09 · 在终端中运行
打开控制台
⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C
应用在 DevTools 中渲染。先在 Safari 设置 → 高级中开启“显示网页开发者功能”。 然后点击这里并按 Enter。
在桌面端打开
此应用在 DevTools 控制台中渲染,需要桌面浏览器。
测验
2 个问题回答所有问题以完成本章。