Skip to main content
Extension.js 用 SWC 編譯 TypeScript,它只抹除型別,從不檢查型別。型別檢查是你用 tsc 另外執行的一步。本頁說明這一步需要哪些套件,才能解析 chrome.*browser.*

Extension.js 會產生什麼

當專案使用 TypeScript 時,extension devextension build 會在 package.json 旁邊寫下一個 extension-env.d.ts 檔案。它在每次執行時都會重新產生,所以不要編輯它。 這個檔案會引入 extension 套件所發佈的環境型別:
extension-env.d.ts
這些引用會給你: EXTENSION_* 環境變數鍵也在這裡取得型別。這就是 process.env.EXTENSION_MODE 不需要額外設定就能解析的原因。

為 chrome namespace 安裝 @types/chrome

extension/types 自己宣告了 browser 全域變數,但它是透過一條引用去搆到 chrome namespace 的:
只有當你的專案裡裝了 @types/chrome,這條引用才解析得到。Extension.js 不會安裝它,範本也不會宣告它。 因此,一個呼叫 chrome.storage 的範本 TypeScript 專案跑 tsc 會失敗:
安裝套件就能清掉它:
再跑一次檢查,錯誤就不見了:
其他什麼都沒變。在安裝之前建置就已經成功了,因為 SWC 從來不讀型別。

當你改用 browser.* 時

browser 全域變數由 extension/types 賦予型別,它把這個變數對應到 webextension-polyfill 上。想要完整的 namespace 形狀,請再裝上對應的型別套件:
同一個選擇在執行階段那一側的樣子,請閱讀 跨瀏覽器相容

讓 extension-env.d.ts 留在 include 清單裡

只有當 TypeScript 讀得到它時,這個產生出來的檔案才有用。範本產生的 tsconfig.json 會點名它:
tsconfig.json
當 Extension.js 為一個還沒有 tsconfig.json 的專案寫出一份 tsconfig.json 時,那份檔案不帶 include 陣列。TypeScript 於是會讀取專案資料夾底下的每一個檔案,所以照樣找得到 extension-env.d.ts。而一個你自己寫、卻漏掉這個檔案的 include 陣列,會讓資源匯入與 browser 全域變數一起失效。

症狀與修正

最佳實務

  • extension-env.d.ts 當成建置產物看待。你想提交它也可以,但絕不要編輯它。
  • 任何會呼叫 chrome.* 的 TypeScript 專案都該加上 @types/chrome,包括你從範本建立的那些。
  • 在持續整合中執行 tsc --noEmit。Extension.js 的建置不會因為型別錯誤而失敗。

下一步