PAYATHON 2026

Rslib 构建时为何找不到 browser 命名空间?

数据小许

结论

先在 tsconfig.json 的 compilerOptions.types 中显式加入 "firefox-webext-browser"。这个错误说明类型检查阶段无法解析 browser 命名空间,现有配置还不足以说明是 SWC 覆盖了 types。

Rslib 使用 SWC 转译 TypeScript。启用 dts: true 后,Rslib 会生成类型声明,并默认进行类型检查。日志中的 [tsc] 与声明生成阶段相符,应先检查该阶段是否加载了目标类型包。Rslib TypeScript 文档

显式加载类型包

在现有配置中增加 types,其他选项可以保留:

{
  "compilerOptions": {
    "lib": ["DOM", "ES2022"],
    "jsx": "react-jsx",
    "module": "es2022",
    "skipLibCheck": true,
    "isolatedModules": true,
    "resolveJsonModule": true,
    "moduleResolution": "bundler",
    "useDefineForClassFields": true,
    "rootDir": "./src",
    "types": ["firefox-webext-browser"]
  },
  "include": ["src/**/*"]
}

这里填写 firefox-webext-browser,不带 @types/ 前缀。如果项目已有 types 列表,将它追加到列表中,并保留其他需要的类型条目。显式设置 types 后,未列出的类型包不会自动加入全局作用域。TypeScript types 文档

加载声明后,原代码可以继续使用:

export type MessageSender = browser.runtime.MessageSender;

@types/firefox-webext-browser 通过全局 declare namespace browser... 提供声明,需要让这个声明文件进入 TypeScript 编译程序。DefinitelyTyped 声明源码

为什么没有配置 types 也可能报错?

这与实际使用的 TypeScript 版本有关。官方文档说明,TypeScript 6.0 起 types 的默认值为 [];6.0 之前,默认会包含可见的 @types 包。原问题没有提供版本,因此不能仅凭缺少 types 就确定根因。TypeScript types 文档

如果使用较早版本,类型包已安装且可见,也没有其他配置限制类型加载,就需要继续检查实际构建环境,不能直接将问题归因于 SWC。

仍然失败时如何排查?

在执行 Rslib 构建的同一项目目录中,先确认依赖版本和安装情况:

npm ls @rslib/core typescript @types/firefox-webext-browser

如果目标项目尚未安装类型包,再安装:

npm install --save-dev @types/firefox-webext-browser

然后使用项目本地的 TypeScript 检查同一份配置:

npx tsc -p ./tsconfig.json --noEmit
npx tsc -p ./tsconfig.json --showConfig
npx tsc -p ./tsconfig.json --listFilesOnly

检查以下结果:

  • 如果独立运行 tsc 也出现 TS2503,先处理 TypeScript 的类型加载问题。
  • 确认有效配置中的 types 包含 firefox-webext-browser。如果配置了自定义 typeRoots,检查它是否限制了类型包的查找目录。
  • 在文件列表中查找 @types/firefox-webext-browser/index.d.ts,确认声明是否实际进入编译程序。
  • 如果独立运行 tsc 通过,Rslib 仍然失败,再核对构建工作目录、实际读取的 tsconfig.json 和两者使用的 TypeScript 版本。--showConfig 展示的是这次独立调用 tsc 的配置,不能单独证明 Rslib 内部使用了完全相同的配置。

自定义 typeRoots 会限制自动包含的类型目录,不建议在确认原因之前随意添加。TypeScript typeRoots 文档

哪些配置不能替代类型加载?

lib: ["DOM", "ES2022"] 提供相应的标准库声明,不能替代 Firefox WebExtensions 的类型包。skipLibCheck: true 也不会补上源码中缺失的 browser 命名空间。

加载 @types/firefox-webext-browser 只解决编译期类型问题,不会在运行时创建 browser 对象。运行代码仍需处于提供该 API 的环境中。

备注:内容仅供参考。