dev,享有監看模式、瀏覽器啟動與情境感知的更新行為。
dev 會執行開發管線並監看你的專案檔案。它會依變更內容套用不同的更新策略:Hot Module Replacement (HMR)、硬重新載入,或必要時的完整重啟。
何時使用 dev
- 開發功能並即時驗證變更。
- 在一個或多個瀏覽器目標中除錯擴充功能行為。
build,需要正式版建置 + 啟動請用 start,只執行既有建置輸出請用 preview。
如果你的擴充功能放在 monorepo/submodule 中,請了解 extension.config.* 如何載入環境檔案(包含 workspace 根目錄的後備):環境變數。
Dev 指令功能
用法
https://github.com/user/repo/tree/main/path)。Extension.js 會下載儲存庫,並對本地副本執行開發模式。
最常用的旗標
這些涵蓋 80% 的情境。其餘可參見 完整參考。引數與旗標
有兩個已淘汰的別名雖然從
--help 中隱藏,但仍可運作:
--wait-format <pretty|json>會對應到--output,並在 stderr 警告一次。請把腳本遷移到--output。--author與--author-mode會對應到--debug。
Safari 旗標
這些旗標只適用於safari 與 webkit-based 目標。與其他目標一起傳入其中任何一個都會以 E_INVALID_OPTION 結束,所以打錯字不會靜默地失效。
對 Safari 目標,
dev 還會在第一次打包前執行工具鏈預檢。缺少 Xcode 會以 E_SAFARI_TOOLCHAIN 快速失敗。
父程序看門狗
--parent-pid 是給衍生 dev 的 harness 與代理使用的,宿主當掉不會外洩伺服器。它的值必須是正整數,其他任何值都會以 E_INVALID_OPTION 結束。看門狗每 2 秒輪詢一次父程序。父程序消失後,dev 伺服器會透過 SIGTERM 關閉;如果清理卡住,還有 5 秒的強制結束後備。
埠號如何決定
--port 是一個請求,不是保證。當請求的埠號被占用時,開發伺服器會往上找最近的空閒埠號。--port 0 會向作業系統要一個任意空閒埠號。請從 ready.json 讀取實際綁定的埠號,而不是你傳入的那個旗標。
自動化中介資料(建議用於腳本/代理)
當dev 執行時,Extension.js 會發出機器可讀的中介資料於:
dist/extension-js/<browser>/ready.jsondist/extension-js/<browser>/events.ndjson(以換行分隔的 JSON)
ready.json 視為就緒契約:
- 啟動中:
status: "starting" - 建置編譯完成:
status: "ready" - 啟動/編譯失敗:
status: "error" - 工作階段關閉後:
status: "stopped",因此已經死掉的工作階段不會再宣稱自己ready - service worker 連上之後為
runtime: "attached"(並附上executorAttachedAt)。act verb 應該等待它,而不是等待ready runId唯一識別一次執行階段工作階段startedAt標示執行階段開始時間command記錄產生它的指令(dev、start、preview或build)toolchainVersion、extensionName與extensionVersion記錄是哪個 Extension.js 版本、為哪個擴充功能產出了這棵目錄樹——終端機捲動紀錄消失後,這個檔案仍是一份建置回執port是實際綁定的開發伺服器埠號,host則是用戶端可以撥號的可連線主機(參見綁定主機與可連線主機)controlPort/instanceId定位extension logs與 act verb 使用的控制橋cdpPort(Chromium)與rdpPort(Gecko)公開瀏覽器的除錯埠號profilePath、browserPid與extensionId由瀏覽器啟動器在啟動後寫入
events.ndjson 只屬於目前這次執行:新一次執行開始時檔案會重設,且每筆記錄都蓋上本次執行的 runId(與 ready.json 一致),消費端不會看到上一個工作階段的事件與目前的交錯。
工作階段行為異常時,執行 extension doctor——它依序檢查契約、控制通道、權杖、執行器與瀏覽器,並指出第一個失敗的環節與修復方式。
--no-browser 與就緒同步
--no-browser 只會關閉瀏覽器啟動,但完整的開發迴圈仍然保留。開發伺服器依然監看你的檔案,並在每次重建後透過控制橋向擴充功能的 service worker 廣播一次重新載入,因此即使沒有被啟動的瀏覽器在驅動,你的變更也會生效:
- content script 的變更會就地重新注入到已開啟的相符分頁(service worker 會用最新建置執行
chrome.scripting.executeScript),所以存檔後頁面就會更新,不需手動重新整理。之後才開啟的分頁也會拿到新的建置,因為 service worker 會動態重新註冊 content script(chrome.scripting.registerContentScripts)。 - service worker / manifest 的變更會重啟擴充功能。
--no-browser 的表現就像一般的 dev 工作階段:把建置好的 dist/<browser> 載入任何你能控制的瀏覽器,它就會在你存檔時持續更新。(如果你想要永不重新載入的靜態開發包,請用 --no-reload,見下文。)
--no-browser 不會在編譯完成前阻擋外部 runner。
對 Playwright/CI/AI 工作流程:
- 以長駐程序執行
extension dev --no-browser。 - 用
extension dev --wait --browser=<browser>作為就緒閘道。 - 只在
status: "ready"後才啟動外部瀏覽器自動化。
--wait 是為第二個程序(或 CI 步驟)而設,並在 error/逾時時以非零碼結束。
當 --wait 看到死掉程序(pid 已不存在)留下的過期 ready.json 時,它會持續等待一個仍在運作的產生者。
--wait 需要本地專案路徑。傳入遠端 URL 會以 E_ARGS 結束。
如果你在同一次指令中同時傳入 --wait 與 --no-browser,--wait 優先,指令會以「僅等待」模式執行。
用 --output json 取得機器輸出
--output json 會在 stdout 印出 schema-1 信封,每行一個 JSON 物件:
- 一般的
dev執行會在啟動時印出一個status: "started"訊框。它帶有專案路徑、瀏覽器清單、請求的埠號,以及開發伺服器的pid。dev不會自行結束,所以後面不會再有結果訊框。即時狀態請讀ready.json。 dev --wait成功時會印出一個status: "ready"訊框。它的value.results陣列會逐一瀏覽器帶出完整的就緒契約。- 失敗時會在程序以
1結束前,印出一個帶有error.code(例如E_READY_TIMEOUT)的ok: false訊框。
用 --no-reload 取得乾淨的開發包
--no-reload 會略過 content script 的重新注入包裝,以及重建時的 reload dispatch。開發版的 dist 會更接近正式版打包,並且當檔案變更時不會擾動已開啟的分頁。請自行重新載入擴充功能或頁面以套用變更。
--no-reload 只在 extension dev 支援。把它傳給 start、preview 或 build 會以錯誤結束。它在內部會設定 EXTENSION_NO_RELOAD=true,讓 develop 程序能從 CLI argv 之外讀取它。
記錄旗標
這些旗標仍是實驗性的,可能在小版本之間變動。共用全域選項
也支援 全域旗標.Monorepo 與 workspace 根目錄
你可以將dev(以及 build)指向 monorepo 的根目錄,而不是擴充功能套件本身。Extension.js 會偵測 workspace 根目錄並自動解析其中的擴充功能套件:
範例
執行本地擴充功能
從 GitHub 執行遠端擴充功能
將 GitHub 樹狀 URL 當作引數,即可在本機開發遠端擴充功能:在 Firefox 中執行
依序在多個瀏覽器中執行
在 Docker 或 dev container 中執行
當你在 Docker、dev container 或 GitHub Codespaces 中執行時,將開發伺服器綁定到0.0.0.0,主機才連得到:
--port 0 讓作業系統自動挑選可用埠號:
綁定主機與可連線主機
--host 是開發伺服器綁定的位址。瀏覽器(HMR 用戶端與重新載入橋接)需要的是一個它真的能連線的位址,兩者未必是同一個值:
--host 0.0.0.0會綁定所有網路介面,但0.0.0.0並不是可連線的位址。Extension.js 會自動改為向瀏覽器公告127.0.0.1,這正是常見的埠號轉發式 Docker/dev container/Codespaces 設定所需要的目標:瀏覽器跑在主機上,埠號被轉發進容器。- 對於真正的遠端設定(瀏覽器與開發伺服器不在同一台機器上),請用
--public-host傳入瀏覽器連得到的位址(區網 IP 或主機名稱)。它會被傳播到 HMR 用戶端 URL、ready.json,以及烘焙進擴充功能裡的重新載入橋接。
--host 本身已經是具體位址時(例如 --host 192.168.1.50),那個值本來就可連線,會被直接使用。只有在綁定主機與瀏覽器面對的主機不同時,才需要 --public-host。
將 Brave 作為自訂執行檔執行
最佳實務
- 瀏覽器相容性: 在不同瀏覽器中測試,確認每個目標都能正常運作。
- 使用 polyfill:
dev中 polyfill 預設開啟,所以browser.*呼叫在 Chromium 系列瀏覽器中也能運作。想要未經處理的原始打包時,請傳入--no-polyfill。 - 自動化可靠性: 把
dev視為監看模式的搭配(--no-browser+dev --wait)。把start視為正式版的搭配(--no-browser+start --wait)。對腳本與 CI 自動化,使用--output=json。
後續步驟
- 用
build產生正式版產物。 - 用
start驗證正式版啟動流程。 - 透過 瀏覽器專屬 manifest 欄位 了解瀏覽器目標。
- 在
extension.config.js中集中設定共用預設值。 - 在 環境變數 中了解設定的環境檔載入行為。

