extension.config.js(或 .mjs / .cjs),並套用到每個指令與 bundler。
運作方式
在專案根目錄(通常和package.json 同層)加上 extension.config.js。
支援的檔名:
extension.config.jsextension.config.mjsextension.config.cjs
型別安全的設定
Extension.js 從extension 套件匯出 FileConfig 型別,讓編輯器能對你的設定自動完成與型別檢查。用 JSDoc @type 標籤標註匯出——它可在 extension.config.js、.mjs 與 .cjs 中運作,且不需要建置步驟:
設定檔的環境載入
extension.config.* 在 Node 中執行,應該從 process.env.* 讀取值。
- Extension.js 在評估
extension.config.*之前,會依由弱到強的順序預先載入 env 檔:.env.defaults、.env、.env.local、.env.development。每個存在的檔案都會載入,而 shell 匯出的變數永遠優先。 - 它會先檢查專案資料夾。
- 在 monorepo 中,若 Extension.js 找不到專案本地的
.env*,會 fallback 到最近的 workspace 根目錄,也就是包含pnpm-workspace.yaml的資料夾。 - 比起在設定檔中匯入
dotenv,建議優先使用內建的 env 預載。
瀏覽器設定
需要為每個目標設定不同的瀏覽器預設值?使用browser:
chrome、edge、firefox、chromium、chromium-based、gecko-based、firefox-based。
常用的瀏覽器欄位:
profile、persistProfilepreferencesbrowserFlags、excludeBrowserFlagschromiumBinary、geckoBinaryextensions(僅載入的附屬擴充功能)
瀏覽器目標能力
指令設定
用commands 定義每個指令的預設值:
extensions、transpilePackages與perfBudgets在每個指令上都依由弱到強分層:頂層,接著是browser.<vendor>,接著是commands.<cmd>,最後是 CLI 旗標。define在同樣的層上逐鍵合併:頂層,接著是browser.<vendor>,接著是dev、start與build上的commands.<cmd>。folders從不逐鍵合併。browser.<vendor>.folders取代頂層物件,dev、start與build上的commands.<cmd>.folders則同時取代這兩者。commands.build.browser、commands.start.browser與commands.preview.browser決定這些指令的目標瀏覽器。--browser旗標仍然優先。start指令會在內部依序執行build與preview。Extension.js 會套用commands.start中的設定,包括profile、browserFlags與startingUrl等瀏覽器啟動選項。你也可以把建置專屬的設定放在commands.build。
指令共用能力
build 指令能力
dev 指令能力
記錄能力
編譯期常數
使用define 把常數內嵌進每個 bundle。Extension.js 會把每個值序列化為 JSON,所以字串、數字、布林值與一般物件都可以:
__APP_VERSION__ 當成一個裸識別字來讀取,建置會把它換成對應的值。在 TypeScript 專案裡,每個鍵還會在產生的 extension-env.d.ts 中得到一條環境宣告,所以 __APP_VERSION__ 會以 string 通過型別檢查。
特殊資料夾的位置
使用folders 移動某個特殊資料夾,或把它關掉。路徑從專案根目錄解析:
- 移動後的
scripts或pages資料夾必須保留原名。Extension.js 不會讀取src/injected這樣的路徑。 false會關掉這個資料夾。Extension.js 不再把其中的檔案編譯成進入點,也不再複製public資料夾。- 被關掉的
scripts資料夾裡、由你的程式碼點名的腳本(例如在chrome.scripting.executeScript({files})中)仍然會發佈。Extension.js 會像編譯其他資料夾裡的腳本一樣編譯它,不加內容腳本包裝。 - 被關掉的
public資料夾裡的任何內容都不會發佈,/icon.png這樣的根路徑也不再指向那裡。如果 manifest 仍然點名那裡的檔案,建置會失敗並逐一列出這些檔案。如果頁面或樣式表參照了那裡的檔案,建置會為每處參照印出一則警告。請重新開啟這個資料夾,或把檔案移出public/。
- 被關掉的
- 移動後的資料夾與預設資料夾的行為完全一致。移動後的
scripts資料夾裡的腳本會得到內容腳本包裝,並在dev中原地重新載入。移動後的pages資料夾裡的頁面會建置到同樣的pages/輸出。頁面、樣式表或 manifest 用同樣的根路徑(例如/logo.png)就能存取移動後的public資料夾裡的檔案。 - 當
public指定了路徑時,Extension.js 只從那個資料夾複製。 browser.<vendor>.folders會整個取代頂層物件,commands.<cmd>.folders則同時取代這兩者。兩者都不會逐鍵合併。
Rspack 設定
需要進階的 bundler 客製化?使用config 來修補產生出的 Rspack 設定。這個範例需要 4.1.31 之後的版本:在那之前,config 裡的 config.module.rules 是 undefined,而 configResolved 才是能看到規則的 hook:
config 也可以是物件,Extension.js 會把它合併到產生出的設定之上。
config 在 Extension.js 掛上它的 loader 規則之前執行。要讀取或修改最終的設定,請使用 configResolved。它在每次 dev、build 或 start 執行中只跑一次,就在第一次編譯之前,並收到已掛上所有 loader 規則的 Rspack 設定:
module、resolve、resolveLoader、node、optimization.minimize、optimization.minimizer,以及 Rspack 在建置開始時才讀取的 output 選項,例如檔案名稱與 environment。可以就地修改它們,也可以回傳一個新的設定物件。這個 hook 可以是非同步的,什麼都不回傳的 hook 會讓設定維持原樣。
到這時 Rspack 已經消耗了其餘所有鍵。這包括 entry、plugins、context、mode、target、devtool、externals、experiments 與 performance 這類鍵,minimize 與 minimizer 之外的所有 optimization 鍵,以及這些 output 鍵:path、module、library、enabledLibraryTypes、chunkFormat、chunkLoading、enabledChunkLoadingTypes、wasmLoading、enabledWasmLoadingTypes、workerChunkLoading、workerWasmLoading、workerPublicPath、pathinfo、sourceMapFilename、devtoolModuleFilenameTemplate、devtoolFallbackModuleFilenameTemplate、devtoolNamespace、bundlerInfo。對其中任何一個的修改,包括深入到值內部的修改,Extension.js 都會復原,並印出一則依路徑列出每個鍵的警告。請在 config 裡設定它們。
hook 上下文
兩個 hook 都會收到第二個引數,用來說明本次執行。它帶有browser(目標瀏覽器,與 --browser 的寫法一致)、mode(development、production 或 none)和 command(dev、build、start 或 preview)。用它為某一個瀏覽器修改 bundler,而不必讀取 process.argv。下面的範例讓 Firefox 的商店建置保持可讀,方便審核:
extension 套件為這個引數匯出了 ConfigHookContext 型別。只接收一個引數的 hook 仍然可以正常運作。
為某一個瀏覽器保留一組 locale
商店接受的語言可能少於你的_locales 資料夾所包含的語言。Extension.js 會為每個瀏覽器複製整個資料夾。要為某一個瀏覽器只發布其中一部分,請從 config 推入一個外掛,刪除其他 locale 的資源:
extension build --browser=edge 只會發布 _locales/en 與 _locales/de。其他所有瀏覽器仍保留整個資料夾。過濾器必須保留 default_locale 所指的資料夾。當它刪除了那個資料夾時,建置會失敗,並在錯誤中指出該 locale。
完整範例
最佳實務
- 瀏覽器專屬值放在
browser:讓指令定義專注於工作流程,而非瀏覽器內部細節。 - 有意識地使用頂層預設:把共用的
extensions/transpilePackages放在根層,只在需要的地方覆寫。 - 優先使用
chromiumBinary/geckoBinary名稱:它們與當前的指令與型別介面一致。 confighook 保持最小:只補上 Extension.js 一級選項尚未涵蓋的部分。

