Skip to main content
不必為每個瀏覽器各自維護一份 manifest 檔案。 Extension.js 讓你用前綴在同一份檔案內定義瀏覽器專屬的值,在編譯時只輸出符合當前目標的欄位。

為什麼這很重要

瀏覽器在 manifest 的關鍵領域仍有差異,例如背景設定與廠商相關的中繼資料。透過帶前綴的欄位,你可以保留一份來源 manifest.json,同時為 Chromium 家族與 Firefox 家族目標產出對應正確的輸出。

運作方式

Extension.js 會掃描 manifest 鍵值,並針對所選的瀏覽器解析帶前綴的條目。解析是以引擎家族為單位,而不是以廠商為單位:
  • Chromium 家族目標(chromiumchromeedgechromium-based,分支 braveoperavivaldiyandex,以及 Safari 輸出)會解析:chromium:chrome:edge:
  • Gecko 家族目標(firefoxgecko-based,以及分支 waterfoxlibrewolf)會解析:firefox:gecko:
當帶前綴的鍵符合當前目標時,Extension.js 會在輸出的 manifest 中將其改寫為不帶前綴的鍵。分支目標會繼承其引擎家族的前綴,因此當你以 bravewaterfox 這類分支為目標時,只帶有 chromium:/firefox: 鍵的 manifest 仍能正確解析。精確的瀏覽器名稱前綴也會符合它自己的目標(例如當你執行 --browser=brave 時的 brave:)。

適用 Chromium 系瀏覽器(Chrome、Edge…)

適用 Firefox

這讓 service_worker 只會出現在 Chromium 家族的輸出中,同時為 Firefox 輸出保留 background.scripts 支援的前綴對應表: 精確的瀏覽器名稱前綴(例如 brave:vivaldi:waterfox:)只在你以同一個瀏覽器為目標時才會額外解析,並且勝過它所屬的家族前綴(以 chrome 為目標時,chrome: 勝過 chromium:)。 Safari 輸出繼承 Chromium 家族(轉換器接收的是 Chrome 形態的 manifest),因此 chromium:/chrome:/edge: 鍵同樣適用於 Safari;若只想覆寫 Safari,請使用 safari:(或 webkit:),它們優先於家族鍵。 這對任何層級的任何 manifest 欄位都有效,包含 permissionscontent_scriptsbackground

家族層級的解析,而不是以廠商為單位

chromium:chrome:edge: 都是 Chromium 家族內的家族前綴:它們各自都適用於每一個 Chromium 家族目標。如果某個欄位只想給單一廠商使用,請改用它精確的瀏覽器名稱前綴(例如 brave:),它只會為該目標解析。

優先順序:三層結構

當多個鍵設定同一個欄位時,勝出者取決於層級,而不是它在檔案中的位置:
  1. 不帶前綴的一般鍵是基礎。
  2. 家族前綴(Chromium 目標上的 chromium:chrome:edge:,Gecko 目標上的 firefox:gecko:)會覆寫一般鍵。
  3. 精確前綴會覆寫前面兩者。精確指的是該前綴點名了確切的目標,例如為 chrome 建置時的 chrome:,或為 brave 建置時的 brave:。在 Safari 與 webkit 系目標上,safari:webkit: 兩者都算精確前綴。
原始碼順序只在同一層級內用來打破平手。看以下例子:
chrome 建置會輸出 "First"chrome: 點名了確切的目標,因此位於精確層,勝過在此處只是家族比對的 edge:。為 edge 建置則因為對稱的理由輸出 "Second"。為 chromiumbrave 建置會輸出 "Second",因為兩個前綴都只是家族比對,原始碼順序較後的那個贏得平手。 只要帶前綴的鍵有比對到,它一定會覆寫同名的一般鍵,無論兩者在檔案中的先後位置。

前綴在每一層都會解析

解析器會走訪整棵 manifest 樹,包含陣列。位於 content_scripts 條目內或任何巢狀物件內的帶前綴鍵,都依照與頂層鍵相同的三層規則解析。

同一個解析器也驅動進入點探索

前綴解析不只影響輸出的 JSON。同一個解析器會在 script 與 HTML 進入點探索之前執行,因此 firefox:background 腳本或帶前綴的頁面,只有在相符的目標上才會成為被編譯的進入點。

分支與 *-based 別名

家族分類會先比對一份已知分支清單,再退回到子字串檢查。chromeedgebraveoperavivaldiyandex 依名稱歸類為 Chromium 家族,其他任何包含 chromium 的名稱也一樣。firefoxwaterfoxlibrewolf 依名稱歸類為 Gecko 家族,其他任何包含 geckofirefox 的名稱也一樣。這就是 chromium-basedgecko-based 別名,以及以它們為基礎的任意 *-based 名稱,都能繼承所屬家族帶前綴鍵的原因。

最佳實務

  • 共用預設值不加前綴:把共用欄位放在一般的 manifest 鍵中,只對瀏覽器專屬的差異加上前綴。
  • 僅在行為分歧時使用前綴:當執行階段需求不同時才使用瀏覽器前綴。
  • 在持續整合(CI)中為每個目標分別建置:產生並驗證每個瀏覽器的輸出(dist/<browser>),及早抓出相容性回歸。
  • 以 MDN 驗證:在加入只支援某瀏覽器的設定前,先用 MDN Web Docs 確認支援度。

下一步