為什麼這很重要
瀏覽器在 manifest 的關鍵領域仍有差異,例如背景設定與廠商相關的中繼資料。透過帶前綴的欄位,你可以保留一份來源manifest.json,同時為 Chromium 家族與 Firefox 家族目標產出對應正確的輸出。
運作方式
Extension.js 會掃描 manifest 鍵值,並針對所選的瀏覽器解析帶前綴的條目。前綴要不是指定一個引擎家族,就是指定單一瀏覽器:chromium:套用到每一個 Chromium 家族目標(chromium、chrome、edge、chromium-based,分支brave、opera、vivaldi、yandex,以及 Safari 輸出)chrome:只套用到chrome,edge:只套用到edgefirefox:與gecko:套用到每一個 Gecko 家族目標(firefox、gecko-based,以及分支waterfox、librewolf)
brave 或 waterfox 這類分支為目標時,只帶有 chromium:/firefox: 鍵的 manifest 仍能正確解析。精確的瀏覽器名稱前綴也會符合它自己的目標(例如當你執行 --browser=brave 時的 brave:)。
適用 Chromium 系瀏覽器(Chrome、Edge…)
適用 Firefox
service_worker 只會出現在 Chromium 家族的輸出中,同時為 Firefox 輸出保留 background.scripts。
支援的前綴對應表:
精確的瀏覽器名稱前綴(例如
chrome:、edge:、brave: 或 waterfox:)只在你以同一個瀏覽器為目標時才會解析。它勝過所屬的家族前綴,因此為 chrome 建置時,chrome: 勝過 chromium:。
Safari 輸出繼承 Chromium 家族,因為轉換器接收的是 Chrome 形態的 manifest。chromium: 鍵適用於 Safari,但 chrome: 與 edge: 鍵不適用。若只想覆寫 Safari,請使用 safari:(或 webkit:),它們優先於 chromium: 鍵。
Safari 沒有實作的鍵與權限,會從 Safari 建置中自動移除,而且從 4.1.20 起,建置會為每個被移除的鍵印出一行,說明是哪個鍵、以及為什麼被移除。content_scripts[].world 會保留,因為 Safari 從 Safari 18 起就支援它。請見 建置 Safari 擴充功能。
這對任何層級的任何 manifest 欄位都有效,包含 permissions、content_scripts 與 background。
只針對一個 Chromium 廠商
chromium: 是家族前綴。chrome: 與 edge: 各自只指定一個瀏覽器,因此一個欄位可以只發佈到一個商店,而不進入另一個商店。例如,Chrome Web Store 的 key 不能進入 Edge Add-ons 的套件:
extension build --browser=chrome 會輸出 key。extension build --browser=edge 不會包含它。
不要寫 edge:key。Edge Add-ons 會拒絕任何在 manifest 中包含 key 的套件,因此該欄位在 Edge 建置裡沒有用處。擴充功能 id 由 Partner Center 指派。從 4.1.20 起,正式模式的 Edge 建置會丟棄 key 並印出一行說明原因,開發模式的建置則會保留它,因為此時穩定的 id 有用,而且不涉及任何商店。
前綴比對的是你用 --browser 要求的瀏覽器,而不是實際啟動的執行檔。當 Extension.js 退回到另一個瀏覽器執行檔時,前綴仍依要求的目標解析。
從 Extension.js 4.1.19 起,
chrome: 與 edge: 成為精確的瀏覽器前綴。在 4.1.18 及更早的版本中,它們適用於每一個 Chromium 家族目標。如果建置丟棄了 4.1.18 會套用的 chrome: 或 edge: 鍵,建置會印出一則點名該鍵的警告。把該鍵重新命名為 chromium: 即可保留原本的套用範圍。優先順序:三層結構
當多個鍵設定同一個欄位時,勝出者取決於層級,而不是它在檔案中的位置:- 不帶前綴的一般鍵是基礎。
- 家族前綴(Chromium 目標上的
chromium:,Gecko 目標上的firefox:與gecko:)會覆寫一般鍵。 - 精確前綴會覆寫前面兩者。精確指的是該前綴點名了確切的目標,例如為
chrome建置時的chrome:,或為brave建置時的brave:。在 Safari 與 webkit 系目標上,safari:與webkit:兩者都算精確前綴。
chrome 建置會輸出 "Chrome"。chrome: 點名了確切的目標,因此位於精確層,勝過 chromium:。為 edge、chromium 或 brave 建置則輸出 "Family",因為 chrome: 不適用於這些目標。
只有同一層級裡有兩個前綴時才會平手,例如 waterfox 這類 Gecko 分支上的 firefox: 與 gecko:,或 Safari 目標上的 safari: 與 webkit:。原始碼順序較後的鍵勝出。
只要帶前綴的鍵有比對到,它一定會覆寫同名的一般鍵,無論兩者在檔案中的先後位置。
前綴在每一層都會解析
解析器會走訪整棵 manifest 樹,包含陣列。位於content_scripts 條目內或任何巢狀物件內的帶前綴鍵,都依照與頂層鍵相同的三層規則解析。
同一個解析器也驅動進入點探索
前綴解析不只影響輸出的 JSON。同一個解析器會在 script 與 HTML 進入點探索之前執行,因此firefox:background 腳本或帶前綴的頁面,只有在相符的目標上才會成為被編譯的進入點。
分支與 *-based 別名
家族分類會先比對一份已知分支清單,再退回到子字串檢查。chrome、edge、brave、opera、vivaldi 與 yandex 依名稱歸類為 Chromium 家族,其他任何包含 chromium 的名稱也一樣。firefox、waterfox 與 librewolf 依名稱歸類為 Gecko 家族,其他任何包含 gecko 或 firefox 的名稱也一樣。這就是 chromium-based 與 gecko-based 別名,以及以它們為基礎的任意 *-based 名稱,都能繼承所屬家族帶前綴鍵的原因。
帶前綴的 manifest_version 需要一個不帶前綴的備援值
chrome: 與 edge: 是精確前綴,所以只作用於某一個廠商的 manifest_version 會讓其他所有建置都沒有這個欄位。下面這份 manifest 給了 Firefox 與 Chrome 一個版本號,卻沒有給 Edge:
manifest_version 的 manifest 任何瀏覽器都不會載入。從 4.1.21 開始,建置會用一則點名被丟棄鍵的錯誤拒絕這種情況,例如 chrome:manifest_version applies only to Chrome builds, so the edge build has no manifest_version.。到 4.1.20 為止,建置會照常寫出 manifest,瀏覽器之後才拒絕它。
請寫一個不帶前綴的 manifest_version 作為基礎值,只給例外情況加前綴:
chromium:manifest_version。
最佳實務
- 共用預設值不加前綴:把共用欄位放在一般的 manifest 鍵中,只對瀏覽器專屬的差異加上前綴。
- 僅在行為分歧時使用前綴:當執行階段需求不同時才使用瀏覽器前綴。
- 在持續整合(CI)中為每個目標分別建置:產生並驗證每個瀏覽器的輸出(
dist/<browser>),及早抓出相容性回歸。 - 以 MDN 驗證:在加入只支援某瀏覽器的設定前,先用 MDN Web Docs 確認支援度。

