在終端機中執行

使用 text run,在終端機中全螢幕執行同一個儀表板。

本章的應用程式正在你的主控台執行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 開啟主控台(先啟用開發者功能),然後試用。
觀看本章3:31

本章內容

  • `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 route

text 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),並依視窗大小調整網格,而非依停駐的主控台大小調整。圖片需要像素資料,而非網址。其餘部分,包括這個儀表板,都使用相同的程式碼。

試用

這是本章結束時的 Acme Deploys,正在 DevTools 中執行。點擊操作區,再使用下方按鍵。

▼ 09 · 在終端機中執行

開啟主控台

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

應用程式在 DevTools 中渲染。先在 Safari「設定」→「進階」中開啟「顯示網頁開發者功能」。 接著點擊這裡並按 Enter。

在電腦上開啟

此應用程式在 DevTools 主控台中渲染,需要桌面版瀏覽器。

測驗

2 個問題

回答所有問題以完成本章。

應用程式在終端機執行時,有什麼改變?

 

應用程式如何自行結束?