Skip to main content
Extension.js 用 SWC 编译 TypeScript,它只擦除类型,从不检查类型。类型检查是你用 tsc 单独运行的一步。本页说明这一步如何解析 chrome.*、browser.* 和 process.env。

Extension.js 会生成什么

当项目使用 TypeScript 时,extension dev 和 extension build 会在 package.json 旁边写下一个 extension-env.d.ts 文件。它在每次运行时都会被重新生成,所以不要编辑它。 这个文件会引入 extension 包发布的环境类型:
extension-env.d.ts
这些引用会给你: EXTENSION_* 环境变量键也在这里被赋予类型。这就是 process.env.EXTENSION_MODE 不需要额外配置就能解析的原因。

随 Extension.js 一起安装的类型

从 Extension.js 4.1.19 起,extension 包把这些引用需要的三个类型包列为依赖: 它们会随 extension 一起安装,所以在一个新项目里,tsc 不需要额外安装就能解析 chrome.* 和 browser.*:
构建并不需要这些包。SWC 从来不读类型,所以不管有没有它们,构建都会成功。

固定你自己的版本

extension 包接受这三个类型包的任意版本。当你的项目自己声明了其中一个时,npm、pnpm 和 Bun 会复用你的项目安装的那一份。 当你的 tsconfig.json 没有 types 数组时,TypeScript 也会加载你的项目声明的那一份。以你自己 package.json 里的版本为准:
package.json

使用 Extension.js 4.1.18 或更早版本的项目

在 4.1.19 之前,extension/types 引用了 chrome,但不会安装 @types/chrome。一个调用了 chrome.*、却没有自己那一份类型的项目跑 tsc 会失败:
把 extension 升级到 4.1.19 或更高版本。如果你留在更早的版本上,请手动安装这个包:
在这些版本上,装上 @types/webextension-polyfill 之前,browser 的类型是 any。想为 browser.* 提供类型,请把这个包也装上:

升级后 browser.* 出现类型错误

从 4.1.19 起,browser 拥有完整的 webextension-polyfill 类型,而不再是 any。以前能通过 tsc 的代码可能会出现新的类型错误,例如调用了 polyfill 没有声明的 API。 修正这个调用,或者对只有 Chromium 提供的 API 改用 chrome.*。同一个选择在运行时那一侧的样子,请阅读 跨浏览器兼容性。

让 extension-env.d.ts 留在 include 列表里

只有当 TypeScript 读到它时,这个生成的文件才有用。脚手架生成的 tsconfig.json 会点名它:
tsconfig.json
当 Extension.js 为一个还没有 tsconfig.json 的项目写下这份文件时,那份文件里不带 include 数组。TypeScript 于是会读取项目目录下的每一个文件,所以照样能找到 extension-env.d.ts。而一个你自己写的、漏掉了这个文件的 include 数组,会让资源导入和 browser 全局变量一起失效。

症状与修复

最佳实践

  • 把 extension-env.d.ts 当作构建产物看待。愿意的话可以提交它,但绝不要编辑它。
  • 只有当你需要某个类型包的特定版本时,才在你自己的 devDependencies 里声明它。
  • 在持续集成中跑 tsc --noEmit。Extension.js 的构建不会因为类型错误而失败。

下一步