當擴充功能需要無法乾淨放入 manifest.json 的 entrypoint 或資產時,使用特殊資料夾。
處理額外頁面、執行階段注入的腳本、需要精確路徑的靜態資產,以及本機開發用的附屬擴充功能,而不破壞專案結構。
特殊資料夾的位置
特殊資料夾只會從專案根目錄解析,別無其他位置。規則如下:
- 專案根目錄是包含
package.json(或 deno.json)的目錄。
- 把
pages/、scripts/、public/ 與 extensions/ 放在那個目錄,也就是 package.json 旁邊。
src/scripts/ 不是特殊資料夾。Extension.js 會忽略巢狀的特殊資料夾副本,因此那裡的檔案永遠不會成為 entrypoint 或被複製的資產。
- 把
manifest.json 移進 src/ 不會移動專案根目錄。骨架範本出貨時就是 src/manifest.json 加上高一層的 package.json,而特殊資料夾屬於 package.json 那一層。
唯一以 src 為根的例外:一個既沒有 package.json 也沒有 deno.json 的專案。此時包含 manifest.json 的目錄成為專案根目錄。當那份 manifest 位於 src/ 時,src/ 就是根目錄,特殊資料夾(與 dist/)都位於 src/ 之內。
我的 scripts/ 資料夾沒有出現在 dist/。 這幾乎都對應到上面的規則:
資料夾位在 src/ 底下,而不是 package.json 旁邊。把它移到專案根目錄。
如果它已經在那裡,確認你的專案中有地方引用了該檔案路徑。
範本範例
special-folders-pages
透過額外的 HTML entrypoint,實際看看 pages/ 特殊資料夾的運作。
儲存庫:extension-js/examples/special-folders-pages
special-folders-scripts
透過獨立的腳本 entrypoint,實際看看 scripts/ 特殊資料夾的運作。
儲存庫:extension-js/examples/special-folders-scripts
為什麼這很重要
manifest 並未直接宣告許多擴充功能檔案,包括 iframe 頁面、你以 chrome.scripting.executeScript 動態注入的腳本,以及靜態廠商資產。你在開發階段可能也需要附屬擴充功能。特殊資料夾讓這些都成為建置流水線中的一等公民。
運作方式
每個特殊資料夾都有特定角色:
pages/:額外的 HTML entrypoint
pages/ 用來放置額外的擴充功能頁面,例如 sandbox iframe、診斷頁面或內部工具。
Extension.js 會把 pages/ 中的每個 .html 視為 entrypoint,並像 manifest 宣告的頁面一樣編譯。
關於 sandbox iframe 範例,請參考 Chrome Sandbox Sample。
scripts/:獨立的腳本 entrypoint
scripts/ 用來放置動態載入、不綁定特定 HTML 頁面 entry 的可執行腳本。
Extension.js 會把 scripts/ 中的檔案編譯為 entrypoint,並使用與專案其他部分相同的副檔名解析流程。
要在某處引用該檔案路徑
只有當 scripts/ entry 相對於專案的路徑出現在你的原始碼某處時,它才會被保留:manifest、
某個 HTML 檔案,或是 JavaScript 或 TypeScript 字串,例如你傳給
chrome.scripting.executeScript 的引數。這正是讓僅在執行階段注入得以運作的原因,
因為該路徑從來不會進到 manifest。
沒有任何地方提到的檔案會被視為無用程式碼,並在不發出警告的情況下從建置中移除,
所以在為新的 entry 做第一次建置之後,請檢查 dist/<browser>/scripts/。
重要合約
當你用 scripts/ entry 作為類似 content script 的執行階段 entry 時,請遵循 content script 初始化模式。這是 Extension.js 預期的預設匯出合約,可確保注入腳本的熱重載安全:
- 匯出一個預設函式。
- 在函式內進行設定。
- 可選擇回傳一個同步的清理函式。
這在開發階段最重要,Extension.js 會安全地重新掛載類 content script 的 entry,而不是進行完整的頁面重載。
scripts/ 不允許 Node.js 腳本
Extension.js 會把 scripts/ 內的每個檔案以瀏覽器 content-script 掛載 runtime 包起來。如果你把 Node.js 專用檔案(例如 CLI 啟動器或建置輔助工具)放在這裡,包裝會破壞檔案。
shebang 不再位於第 1 行,且瀏覽器情境中無法使用僅限 Node 的 API。
Extension.js 會偵測兩種 Node.js 指標,並在建置時拋出錯誤:
- 第 1 行的 shebang(
#!/usr/bin/env node)。
- 來自
node: 協定的 import(例如 import fs from 'node:fs')。
如果你看到 scripts/ is a reserved folder in Extension.js,請把檔案移到專案
根目錄下的其他資料夾,例如 bin/、tools/、ops/、tasks/ 或
ci-scripts/。
關於動態注入範例,請參考 Chrome Scripting Sample。
public/:僅複製的靜態資產
當你需要穩定的檔案路徑且不需打包/轉換時,使用 public/。
Extension.js 會把 public/ 下的所有內容 1:1 複製到輸出根目錄。
重要的 public/ 防護
不要把 manifest.json 放在 public/manifest.json。Extension.js 會阻擋這種情況,避免在編譯時覆蓋產生的 manifest。
extensions/:附屬擴充功能(僅載入)
當你使用附屬擴充功能(例如 DevTools 輔助工具)時,Extension.js 在 dev/preview/start 流程中支援 extensions/ 資料夾作為僅載入來源。
整體而言:
- 掃描
extensions/ 下含有 manifest.json 的子資料夾作為解壓後的擴充功能根目錄。
- Extension.js 會將附屬擴充功能與主要擴充功能一起載入。
- 此資料夾用於載入附屬擴充功能,而非把它們建置進主產物。
你也可以透過 --extensions CLI 旗標或 extension.config.js 中的 extensions 鍵載入附屬擴充功能:
Extension.js 會自動下載、解壓並把商店 URL 與你的擴充功能一起載入。
開發行為(監看模式)
在開發監看模式下,Extension.js 會監控 pages/ 與 scripts/ 的檔案集合變更:
- 新增支援的檔案會觸發警告(你可以繼續工作)。
- 移除支援的檔案會觸發編譯錯誤,需要重新啟動開發伺服器才能恢復。
這能保護執行中的編譯圖,避免出現過期或損壞的 entrypoint。
最佳實務
- 共用執行階段資產放在
public/:用在必須保持名稱與路徑精確的檔案。
pages/ 與 scripts/ 用於真正的 entrypoint:讓 manifest 之外的執行路徑保持明確。
- entrypoint 變更後重啟開發伺服器:特別是刪除
pages/ 或 scripts/ 下的檔案後。
- 附屬擴充功能保持獨立:把
extensions/ 視為本地工作流程的僅載入相依。
public/ 中不要放 manifest.json:Extension.js 會阻擋 public/manifest.json 以保護產生的擴充功能輸出。
下一步
模板示範