tsc 单独运行的一步。本页说明这一步需要哪些包,才能解析 chrome.* 和 browser.*。
Extension.js 会生成什么
当项目使用 TypeScript 时,extension dev 和 extension build 会在 package.json 旁边写下一个 extension-env.d.ts 文件。它在每次运行时都会被重新生成,所以不要编辑它。
这个文件会引入 extension 包发布的环境类型:
extension-env.d.ts
EXTENSION_* 环境变量键也在这里被赋予类型。这就是 process.env.EXTENSION_MODE 不需要额外配置就能解析的原因。
为 chrome 命名空间安装 @types/chrome
extension/types 自己声明了 browser 全局变量,但它是通过一条引用去够到 chrome 命名空间的:
@types/chrome,这条引用才解析得到。Extension.js 不会安装它,模板也不会声明它。
因此,一个调用了 chrome.storage 的脚手架 TypeScript 项目跑 tsc 会失败:
当你改用 browser.* 时
browser 全局变量由 extension/types 赋予类型,它把这个变量映射到 webextension-polyfill 上。想要完整的命名空间形状,请再装上配套的类型包:
让 extension-env.d.ts 留在 include 列表里
只有当 TypeScript 读到它时,这个生成的文件才有用。脚手架生成的tsconfig.json 会点名它:
tsconfig.json
tsconfig.json 的项目写下这份文件时,那份文件里不带 include 数组。TypeScript 于是会读取项目目录下的每一个文件,所以照样能找到 extension-env.d.ts。而一个你自己写的、漏掉了这个文件的 include 数组,会让资源导入和 browser 全局变量一起失效。
症状与修复
最佳实践
- 把
extension-env.d.ts当作构建产物看待。愿意的话可以提交它,但绝不要编辑它。 - 任何调用
chrome.*的 TypeScript 项目都该加上@types/chrome,包括你从模板生成的那些。 - 在持续集成中跑
tsc --noEmit。Extension.js 的构建不会因为类型错误而失败。
下一步
- 阅读 TypeScript 配置的其余部分。
- 了解这些类型所声明的环境变量。
- 回顾跨浏览器兼容性。

