Skip to main content
有些 manifest 形態會讓 Chromium 拒絕載入整個擴充功能。這個拒絕要嘛以原生對話框出現,要嘛完全沒有任何提示,但絕不會是一則主控台錯誤。沒有外力協助時,開發 session 就這樣卡住:瀏覽器在跑,擴充功能卻不在,除錯通道也永遠連不上。 Extension.js 在兩個位置補上了這個落差:
  • 啟動之前,它會讀取每一個即將載入的擴充功能的建置後 manifest.json,並針對每一個能夠證實的拒絕原因發出警告,指名欄位與原因。
  • 建置時,它會修復一小組毫無歧義的致命形態,並為每一次修復印出一行修復說明。

啟動前診斷

這些檢查針對建置後的擴充功能執行,就在瀏覽器啟動之前。

manifest 版本相關的拒絕

無效的 match 樣式

只要有一個樣式無效,Chrome 就會拒絕整個擴充功能。Extension.js 會檢查 host_permissionsoptional_host_permissionscontent_scriptsmatchesexclude_matches),以及 web_accessible_resources 中的 matches。 host 文法允許 **.domain.tld 或字面的 host。host 中任何其他位置的萬用字元都是無效的,例如 https://foo.*.com/*。連接埠、查詢字串與片段不會觸發拒絕,而且連接埠本身也可以是萬用字元。

載入阻斷項清單

以下每一項都已在實際的 Chrome 版本上驗證過會拒絕整個擴充功能:
  • name:缺少、為空,或不是字串。Chrome 要求一個非空的字串名稱。
  • version:缺少,或不是 1 到 4 段以點分隔的整數,且每段的值介於 0 到 65535 之間。
  • MV3 的 web_accessible_resources:項目必須是字典,包含 resources,再加上 matchesextension_idsuse_dynamic_url 其中之一。MV2 的字串陣列寫法在 MV3 上會遭拒絕。MV2 下它仍然合法。
  • content_scripts 文法matches 為必填且不得為空,jscss 的項目必須是字串,run_at 只接受 document_startdocument_enddocument_idle,而且每個項目至少需要一個 jscss 檔案。
  • minimum_chrome_version:無效的值會直接遭拒絕。值合法但高於解析出的瀏覽器版本同樣會遭拒絕,因此這項檢查比對的是該 session 實際啟動的那個執行檔。
  • commands:Chrome 最多允許 4 個帶 suggested_key 的快速鍵。Firefox 沒有上限,所以從 Firefox 移植過來的擴充功能經常在這裡踩雷。
  • key:必須是合法的 base64 公開金鑰。padding 有問題就會導致擴充功能遭拒絕。
  • 圖示:只要有一個 manifest 圖示(icons.* 或任一 *_action.default_icon)對應的檔案缺少或大小為 0 位元組,整個擴充功能就會遭拒絕。
  • 語系:宣告了 default_locale,但對應的 _locales/<locale>/messages.json 缺少或不是合法 JSON,會遭拒絕。整串 __MSG_key__ 參照在目錄中沒有定義時也一樣(查找不分大小寫,@@predefined 名稱除外)。_locales 目錄樹有內容、manifest 中卻沒有 default_locale,同樣會遭拒絕。
  • storage.managed_schema:schema 路徑在擴充功能目錄內不存在時,整個擴充功能會遭拒絕。
每一項發現都會在啟動之前印成一則警告,指名擴充功能路徑與每一個阻斷項,所以卡住的原因會事先講清楚。

建置時的自動修復

其中一部分致命形態夠明確,可以直接修掉。在建置過程中,Extension.js 會在產出的 manifest.json 裡修復這些: 每一次修復都會在發生的當下於 CLI 輸出中報告一行修復說明,並記錄一則 manifest.json 建置警告,所以不會有任何東西被悄悄改寫。
修復只作用於產出的 dist manifest。你的原始碼 manifest.json 永遠不會被修改。看到修復說明時請去修原始碼,讓這次修復不再被需要。

後續步驟