- HMR(hot module replacement):當模組更新是安全的時候
- 分類重載(full、service worker、content scripts,或僅通知的 page):當執行階段資產有變更時
- 需要重啟的錯誤/警告:當 entry 結構有變更時
重新載入前置條件(devtools 設定對話框)
在評估重新載入行為之前,先確認 Extension.js devtools 的 Confirm setup 對話框所列的相同設定檢查:
如果你跳過任一步驟,即使建置流水線健康,重新載入行為也可能看起來不一致。
重新載入層級
1) Hot module replacement(最快路徑)
當程式碼可以更新而不需重啟擴充功能的背景程序與事件監聽器時,Extension.js 會使用 HMR。 常見例子:- 附加在擴充功能 HTML 頁面上的腳本(透過注入的 HMR 包裝接受更新)
- 非 service worker 流程中的背景腳本模組
- 透過
userScriptsAPI 註冊的腳本 - 在支援的 content-script/runtime 包裝中的 CSS 更新
2) 分類重載
當一次變更需要的不只是 HMR 時,Extension.js 會把它歸入四種重載類型其中之一:
這個判定來自編譯器的 chunk 圖,而不是檔名,並遵循固定順序:
- 強制 full。 對
manifest.json或_locales/底下任何內容的變更,一律歸類為full,不論還改了什麼。 - Chunk 歸屬。 Extension.js 會查出每個變更來源檔屬於哪些 chunk。位於
background/chunk 的來源檔代表service-worker,位於content_scripts/chunk 的來源檔代表content-scripts。 - 變更的靜態資產。 有些變更檔案存在於輸出目錄,卻不屬於任何 chunk:圖示、web-accessible 資源、DNR 規則集。它們會強制
full,讓瀏覽器從磁碟重新讀取。 - 名稱啟發式。 僅用於 chunk 圖不認識的來源檔:路徑符合
background或service worker樣式的歸類為service-worker。 - Content 後備。 若 manifest 宣告了 content script,其餘未知的變更會重新注入每一個 content-script entry。
- 僅通知的 page。 其他一切都是
page指令:重新整理由 livereload 負責,重載通告仍會發出。
context (fileA, fileB +2 more),例如 service_worker + content_script (shared/api.ts)。同一個標籤會原封不動出現在 CLI 的 stdout、頁面 devtools 主控台與 devtools 標籤中,讓你不必猜測就能在三處對應同一次重載。
為什麼開發階段的 content script 檔名會包含雜湊? Chrome 會積極快取chrome-extension://資源。像content-0.js這種穩定檔名即使在完整擴充功能重載後仍可能提供舊的程式碼。Extension.js 會在開發時加上短雜湊(例如content-0.abcd1234.js),每次重建都會產生新的 URL 來繞過快取。正式建置則使用乾淨的名稱。在extension.config.*的commands.dev底下設定hashContentScripts: false可以停用它,保留穩定的開發階段檔名。同名的頂層鍵會被忽略。
3) 需要重啟(開發伺服器)
當擴充功能的 entrypoint 引用變更(不僅是模組內容)時,Extension.js 會回報需要重啟的診斷訊息。這能防止你繼續使用過期的依賴圖。 典型的需要重啟情境:- Manifest 腳本 entrypoint 清單變更
- HTML entrypoint 的腳本/樣式引用變更
- 監看模式下
pages//scripts/檔案集合變更(特別是刪除)
行為矩陣
開發階段的 runtime 如何注入
重載外掛會以五個注入步驟為你的建置加裝,然後進行清理:- 從無法承載開發伺服器 runtime 的 content-script chunk 中移除該 runtime。
- 在 background 與 content-script entry 上設定重載策略。
- 注入 service worker 的腳本重播 shim,讓
/scripts/*的注入在編輯後重新執行。 - 注入 bridge producer,讓 background 把主控台輸出轉送到控制通道。
- 注入 bridge relay,讓 content-script 的主控台輸出抵達同一個通道。
hot/。熱更新 chunk 是從擴充功能來源上的磁碟取得的,所以過期的世代會在最終產物中累積。Extension.js 會保留目前世代與前一個世代(供進行中的請求使用),並在每次編譯後刪除其餘的。
整條流程僅限開發階段。在正式建置中,以及當你傳入 --no-reload 時,它不會做任何事。
重新載入 manifest 外的腳本與 HTML
pages/ 與 scripts/ 採用與 manifest 宣告資產相同的重新載入策略。
- 既有的模組更新可以使用熱更新路徑。
- Entrypoint 集合變更(新增/刪除或引用圖變更)可能需要重啟。
Extension.js 會把
/pages 與 /scripts 資料夾辨識為可熱重載的位置,並把 每個
entry 視為可以獨立重載的頁面或腳本。從
/scripts/* 中以 chrome.scripting.executeScript
動態注入的腳本,在編輯時會被 重播。當你修改 /scripts/
下的檔案時,Extension.js 會在同一個分頁重新執行相同的注入,
並先卸載前一次的掛載——所以動態注入的腳本可以即時更新,效果就像宣告式的
content_scripts 一樣,而不會留下過期的 DOM
直到你手動重新觸發。這是一項僅限開發階段 的便利設計。最佳實務
- 在進行中的開發階段保持 entrypoint 引用穩定,以最大化 HMR。
- 把
manifest.json與語系編輯批次進行,避免反覆觸發整個擴充功能重載。 - 用
pages/與scripts/放置 manifest 之外的資產,當檔案集合或 entry 連線變更時再重啟。 - 把需要重啟的診斷視為刻意的安全檢查,而不是短暫的警告。

