dev、start、preview 與 build 執行,都會在每次編譯時原子性地寫入 dist/extension-js/<browser>/ready.json。目前的契約是 schemaVersion: 2。
狀態
兩階段就緒
status: "ready" 只代表編譯完成,不代表更多。瀏覽器可能還在啟動,service worker 也可能還沒連上。
act 類工具(eval、storage、reload、open、inspect)需要第二個階段。要等到契約帶上 runtime: "attached" 與一個 executorAttachedAt 時間戳之後,再去驅動擴充功能。
attach 這個標記是冪等的,而且能撐過重新編譯。一次 attach 也會清掉先前的 extension_load_refused 狀態,因為執行器就跑在被控的瀏覽器裡面。
欄位參考(schema v2)
一定存在的欄位:
已知時才會出現的欄位:
錯誤狀態
code 欄位為失敗類別命名。對自動化來說有三個代碼要緊:
一次載入被拒會活過下一次成功編譯。只有一次新的執行(
starting)或一次真正的執行器 attach 才能把它清掉。
用 —wait 等待
extension dev --wait 與 extension start --wait 每 250 毫秒輪詢一次契約,並在它回報 ready 時結束。搭配 --output json 可以拿到機器可讀的結果。
等待迴圈拒絕相信過期的檔案。每次讀取都會跑三項檢查:
command欄位必須與正在等待的指令相符。pid必須還活著。對dev而言,產生者已死一定代表檔案過期,所以會繼續輪詢。- 對
start而言,只有契約夠新鮮時才接受一個已死的 pid。新鮮的意思是ts、compiledAt或startedAt落在最近 60 秒內。
E_READY_TIMEOUT 結束。處於 error 狀態的契約會帶著它的 message 讓等待失敗。
把工作階段檔案串起來
同一個資料夾裡還有events.ndjson(編譯時間軸)與 logs.ndjson(擴充功能的主控台輸出)。兩者的每一列都帶著來自 ready.json 的 runId。
events.ndjson 在每次執行開始時被清空,所以它永遠只描述目前這次執行。事件型別有 compile_start、compile_success、compile_error 與 shutdown。
範例
後續步驟
- 用結果信封讀取指令結果。
- 用生命週期串流把同一個工作階段當成影格來串流。
- 用 Playwright E2E 把整套流程接進測試。

