在背景情境中執行擴充功能全域邏輯,並明確支援 Manifest V2(MV2)background script 與 Manifest V3(MV3)service worker。
Extension.js 從 manifest.json 讀取 background 進入點,並將其編譯為專屬的 background 輸出。在開發期間它會套用對應瀏覽器的重新載入行為。
範本範例
action
帶有 popup 並使用背景 service worker 處理瀏覽器事件的 action 擴充功能。
儲存庫:extension-js/examples/action
ai-chatgpt
帶有 popup 並用背景 service worker 串接外部 API(ChatGPT)。
儲存庫:extension-js/examples/ai-chatgpt
Background 能力
Background script 支援
在 manifest.json 中以下列欄位宣告 background script:
background.type 也會影響執行模式(module 與 classic service worker 行為的差異)。
Background script 宣告範例
在 manifest.json 中宣告 background script 的範例:
開發行為
Extension.js 追蹤 service worker/原始碼變更,並可觸發整個擴充功能的 hard reload。
影響 background 進入點的 manifest 變更會觸發「需要重新啟動」的診斷訊息。
啟動瀏覽器的 plugin 會套用對應平台(Chromium/Firefox)的 hard reload 策略。
Extension.js 對結構性進入點變更的處理比一般模組編輯更嚴格。
Firefox:service worker 轉譯為 event page
Firefox 不會執行 MV3 的 background.service_worker(載入此類擴充功能時會顯示 “background.service_worker is currently disabled. Add background.scripts.” )。你不需要特別處理:在 Firefox build 中,Extension.js 會自動把 background.service_worker 進入點翻譯成 background.scripts 的 event page,並指向同一個編譯後的 bundle。撰寫一個 background.service_worker,就能同時在 Chromium 與 Firefox 上載入。
Chromium:scripts 轉譯為 service worker
這個轉譯在另一個方向同樣成立。在 Chromium MV3 建置中,background.scripts 陣列會變成指向編譯產物的 background.service_worker。
只要出現 background.scripts,Chromium MV3 就會拒絕整個擴充功能,即使旁邊還有一個有效的 service_worker 也一樣。因此 Extension.js 一律會從輸出的 Chromium MV3 manifest 中移除 scripts 鍵。當來源同時宣告這兩個欄位時,既有的 service_worker 條目勝出。
Safari:使用 background 頁面,而不是 service worker
從 4.1.20 起,Safari 建置產出的是非持續性的 background 頁面。Extension.js 會把 background.service_worker 條目翻譯成 background: {scripts: [...]},和它為 Firefox 所做的翻譯一樣。
原因是在 Safari 26.5.2 上量測出來的:測試中 Manifest V3 的 service worker 從未啟動過,包括以 Apple 自己的轉換工具建置的擴充功能,而 background 頁面則會立刻執行。WebKit 有意偏好頁面形式(WebKit bug 270750 )。
在 background 腳本 最外層 有一個沒有保護、只有 Chromium
才有的呼叫,在 Safari 上就會丟出例外,Safari 接著會丟棄這個 background
情境。你拿不到記錄、拿不到重新載入,也看不到任何錯誤,擴充功能看起來就是死的。請保護這個呼叫,或在建置期分支。
從 4.1.20 起的 Safari 建置也會針對 Safari 缺少的擴充功能 API 發出警告,這是在你開始除錯之前找出問題最省事的方法。請見 建置 Safari 擴充功能 。
MV3 service worker 生命週期
background.service_worker 依瀏覽器的 service worker 生命週期執行,不是長期執行的常駐程序。
這意味著:
記憶體中的狀態可能會在事件之間消失。
設計長時間執行的工作時,要以事件為核心,而不是以程序常駐為前提。
啟動流程要保持輕量、可預測。
你的程式碼應該從 storage 還原重要狀態,或以安全方式重新計算。
只在 MV2 風格的相容性情境中使用 background.scripts。對於以 MV3 為主的擴充功能,請把 service worker 當成瀏覽器 API 呼叫與跨情境通訊的中央協調者。
輸出行為
常見的輸出包含:
background/service_worker.js
background/scripts.js
實際輸出取決於瀏覽器過濾後仍然生效的 manifest 欄位。
Module 與 classic 注意事項
background.type: "module" 採用 module worker 語義。
Classic service worker 模式採用基於 importScripts 的 chunk 載入行為。
避免在 background 程式碼中使用動態 import,尤其是必須在啟動時立即載入的部分。
執行階段載入的檔案
有些檔案從不以 import 陳述式出現,卻仍必須隨擴充功能一起發布。Extension.js 會把它們追蹤進輸出,讓建置後的擴充功能表現得和在瀏覽器中以未封裝方式載入原始碼一樣:
classic service worker 的 importScripts(...) 相依項目。 字串字面值參數會相對於輸出的 worker 位置遞迴解析(相依項目本身也可以呼叫 importScripts),因此即使 worker 移動到 background/service_worker.js,相對於 worker 的 URL 仍然可用。由 wasm-bindgen 膠水程式碼載入的 WebAssembly 同層檔案(*_bg.wasm)會與它的載入器一起發布。
chrome.scripting.executeScript({files: [...]}) 與 insertCSS({files: [...]}) 的內容。 只在 files: 陣列中被參照、而未在 manifest 的 content_scripts 中宣告的檔案,會依其擴充功能根目錄下的路徑原樣複製。
被參照的檔案若不存在於你的專案中,建置會產生一則指明缺少路徑的警告,而不是在執行階段靜默失敗。
建議的架構
讓 background 進入點保持精簡,把功能邏輯放到共用模組。
把 background 情境當成 messaging、storage 存取與瀏覽器 API 呼叫的中央協調者。
從 storage 還原持久狀態,不要假設 background script 會永久執行。
使用 alarms、明確的事件監聽器與小型功能模組,而不是一條龐大的啟動路徑。
常見錯誤
把 service worker 當成永久執行的伺服器程序。
把關鍵狀態只保存在記憶體裡。
在每次事件喚醒時都做沉重的啟動工作。
把太多功能邏輯放在 popup 或 content script,但實際上需要的是 background 等級的瀏覽器 API 存取。
最佳實務
以 MV3 為主的擴充功能優先採用 background.service_worker。
讓 background 進入檔案保持小巧,把邏輯委派給共用模組。
避免在 service worker 中做沉重的啟動工作;在安全的情況下採用延遲初始化。
在開發流程中,把 manifest 中 background 欄位的編輯視為結構性變更。
經由通過驗證的訊息處理器來路由特權動作。
把持久設定與快取放到瀏覽器 storage,而不是只放在模組層級變數中。
後續步驟