開發

第一次 checkout#

依照 root README 安裝 vp。這個 checkout 需要 Node 24;Bun 是選用的。在 repository 根目錄執行:

vp i
vp run dev

開啟 dev runner 印出來的 pairing URL。只有 origin、不帶其他資訊的網址,沒辦法讓新的瀏覽器通過驗證。

比較想用 container 嗎?VS Code 與 Codespaces 的設定方式見 Dev container。

選擇要跑哪個開發行程#

要跑 server 和 web 就用 vp run dev,要跑 Electron client 就用 vp run dev:desktop。dev:server 和 dev:web 會分別單獨啟動這兩個行程。原生 build 與 Metro 請看 mobile README。

旗標直接接在 task 名稱後面,例如 vp run dev --home-dir /tmp/t3code-dev。加上 --browser 會自動開啟瀏覽器。

狀態與 port#

Linked worktree 預設使用它自己的 .t3/userdata,就算設定了 T3CODE_HOME 也一樣。主要的 checkout 預設使用 ~/.t3/dev/userdata。明確指定的 --home-dir 在兩種情況下都優先。絕對不要讓開發用的 server 對著正式使用中的 ~/.t3/userdata 執行。要複製一份一致的資料庫 snapshot,請看測試資料。

Port 請從 [dev-runner] 的輸出讀取。Worktree 會從自己的路徑推導出穩定的偏好 port,但被佔用的 port 會讓它們位移。需要時,可以用 T3CODE_PORT_OFFSET 或 T3CODE_DEV_INSTANCE 選擇不同的偏好值。

分享與遠端除錯#

vp run dev --share 會把 web 的 port 發佈到這台機器的 tailnet 上,並印出對應那個 origin 的 pairing URL。請把完整的 URL(包含裡面的 token)交給測試的人。Dev runner 結束時會移除它建立的對應。

VITE_HTTP_URL 和 VITE_WS_URL 請保持未設定。Vite 會透過瀏覽器的 origin 代理 backend,所以同一個 build 在 localhost 和遠端連線下都能運作。

分享模式會啟用 bundled dev,避免每一層 import 都要多一次網路來回。要除錯 bundler 之間的差異時,可以用 T3CODE_BUNDLED_DEV=0 關掉它。修改這套設定時,有兩個和 reload 有關的陷阱要注意:

  • Web 的進入點必須用 dynamic import 載入 app,這樣 React refresh 才會在應用程式的 chunk 之前完成初始化。Static import 可能在第一次載入時正常,卻在 route 拆分之後失敗。
  • Bundled dev 是透過監看檔案來重新 build Tailwind 的。Tailwind 一般的 Vite hot-update hook 需要 server/module graph,而 Rolldown 並不提供。

這些因應做法放在 web 進入點和 Tailwind plugin 裡。

可重複使用的開發憑證#

只在你信任上面每一個服務的 hostname 上使用這個功能。瀏覽器會把 cookie 送給該 hostname 上的所有 port。你在那個 hostname 上造訪的任何服務,都可能收到這個可重複使用的管理員憑證,包括和 T3 Code 無關的服務。如果你在那個 hostname 上有執行不受信任的服務,請維持一般的做法,每個 environment 各自配對。

要讓同一個瀏覽器 profile 在同一個 hostname 上的多個 web dev worktree 之間通用,先產生一個固定的值,只需要做一次:

openssl rand -hex 32

把這個值放進主要 checkout 裡那個被 gitignore 的 .env:

T3CODE_DEV_AUTH_TOKEN=<the value generated above>

t3.json 的 Setup Worktree 動作會把那個檔案連結到每個 worktree 的 .env。Dev runner 在啟動時讀取 repository 的 env 檔案。.env.local 和繼承而來的行程環境變數會蓋過 .env,所以設定好之後,不需要在每個 worktree 裡另外 export。

如果是手動建立的 worktree,或是沒有這個連結的 launcher,就改成 export 同一個固定值:

export T3CODE_DEV_AUTH_TOKEN="<the value generated above>"

不要在每次啟動時產生新的值。設定完成後,啟動或重新啟動 vp run dev --share,然後在那個 hostname 上,每個瀏覽器 profile 各開啟一次它在啟動時印出的 pairing URL。之後同一個 hostname 上的其他 web dev server,就會跨 port 接受這個共用的 cookie。Cookie 會在 30 天後過期。如果某個舊分頁的 URL 現在對應到的是替換過的 environment,請重新載入那個分頁。

這個 token 和啟動時的 pairing URL 都是可重複使用的管理員等級 secret。絕對不要把它們放進 commit、pull request 或任何公開的輸出。每個 server 仍然會在啟動時寫入自己的驗證資料庫紀錄,並保有自己的 SQLite 資料、簽章金鑰和撤銷狀態。桌面版和非開發用的 server 會忽略這個值。安全模型請看 environment 驗證。

檢查#

針對你改到的檔案和套件執行檢查:

vp test run <files>
vp lint <files>
vp run --filter <package> typecheck

改到原生 mobile 的部分時,使用 vp run lint:mobile。完整的測試由 CI 負責;目前有哪些 job 請看 ci.yml。在 Windows 測試還不是必要關卡的期間,可以用手動的 Windows lane 針對 Windows 做重點調查。

未使用的程式碼#

vp run knip:check 會先檢查整個 repo 裡未使用的檔案和相依套件,再檢查 apps/server、apps/desktop、apps/web,以及 packages/ 底下每一個內部套件裡未使用的 runtime export。CI 會強制執行這兩項檢查。匯出的型別和 Effect schema 即使沒有被使用也是允許的。Schema preprocessor 認得 schema 型別,包括 alias 和 schema class;用來建立或解碼 schema 的函式則仍然會被檢查。標準的 Effect service 建構 API 會維持匯出,並加上明確的 @public 註記,Knip 認得這個註記。完全沒被用到的檔案同樣仍然會被檢查。Web UI 元件模組裡的 named export 會被當成完整的元件組合保留下來。Knip 會忽略 apps/web/src/components/ui/*.tsx 裡未使用的 export,但整個檔案都沒被用到時仍然會回報。用 vp run knip --workspace apps/web 可以稽核單一個 workspace(包含 export),用 vp run knip:production --workspace apps/web 可以找出只靠測試才沒被判定為無用的程式碼。完整的 export 稽核目前仍然有待處理的項目,所以不是整個 repo 的 CI 關卡。隨著更多 workspace 清理乾淨,請擴充 export 檢查的 workspace 選擇器。刪除程式碼之前請先檢視呼叫端;production 模式也可能回報開發用的腳本和測試用的 fixture。在 runtime 才被發現的進入點,以及相依套件的例外,請寫在 knip.jsonc 裡。

桌面版 artifact#

本機 build 出來的 artifact 預設不簽章,並寫到 release/:

vp run dist:desktop:dmg
vp run dist:desktop:linux
vp run dist:desktop:win

DMG 預設使用 host 的架構。用 --arch 選擇其他目標,用 --keep-stage 保留打包過程的檔案以便檢查。其他選項請執行 vp run dist:desktop:artifact --help。

Linux AppImage 的前置需求#

請在 Linux 上 build,因為 browser-secret helper 會連結到 host 的 libsecret。安裝 Rust、C/C++ build 工具、libsecret 的開發用 header、pkg-config 和 ImageMagick。

Ubuntu 與 Debian:

sudo apt-get update
sudo apt-get install cargo rustc build-essential libsecret-1-dev pkg-config imagemagick

Fedora:

sudo dnf install rust cargo gcc gcc-c++ make libsecret-devel pkgconf-pkg-config ImageMagick

Arch Linux:

sudo pacman -S rust base-devel libsecret pkgconf imagemagick

在 Linux 上做桌面版開發,同樣需要 C toolchain、pkg-config 和 libsecret 的 header。

macOS DMG 的前置需求#

用 xcode-select --install 安裝 Xcode Command Line Tools,並安裝 Rust。要做跨架構或 universal build 時,加入需要的 Rust target:

rustup target add aarch64-apple-darwin x86_64-apple-darwin

Windows 安裝程式的前置需求#

安裝 Rust、Python 3,以及包含 Desktop development with C++ 的 Visual Studio Build Tools。要包含 Windows SDK,以及目標架構的 MSVC build 工具和 Spectre-mitigated 函式庫。加入對應的 Rust target:

rustup target add x86_64-pc-windows-msvc
# For an ARM64 installer:
rustup target add aarch64-pc-windows-msvc

NSIS 會由 electron-builder 下載。要支援 WSL,還需要用 --wsl-runtime 傳入 Linux CLI archive;見發版 runbook。

簽章與 passkey#

依照發版 runbook 設定好平台憑證之後,加上 --signed。macOS 的 passkey 需要一個已簽章、已 provision 的 app;本機簽章與 renderer HMR 的做法請照 Connect 設定進行。

本頁譯自 docs/operations/development.md(英文原文,版本 b7e1b25)。標示「本站補充」的區塊不在原文裡。

非官方翻譯,與 T3 Code 的維護者無關。內容由 AI 翻譯並補充,未經逐頁人工校對,可能有錯誤或已經過時,請以英文原文為準。

原文 © T3 Tools Inc.,以 MIT 授權釋出;本站為其官方 repository 中 docs/ 的翻譯。本站原始碼與問題回報