跳转到主要内容
Extension.js 在开发与构建期间处理浏览器特定的设置。你可以从同一个项目为 Chromium 与 Gecko(Firefox 引擎) 目标生成运行时正确的产物。

跨浏览器扩展开发

跨浏览器扩展开发意味着写一个扩展同时发布到 Chrome、Edge 和 Firefox,而无需 fork 代码。Extension.js 会把同一个项目编译成各浏览器对应的产物(dist/chromedist/edgedist/firefox),并按当前目标过滤 manifest。重载循环、运行时 API 和打包流程都与你当前调试的浏览器保持一致。 使用一份 manifest.json 即可针对特定浏览器或自定义二进制文件。如果你需要在 Chromium 系目标里使用 browser.* API 兼容性,可以启用 polyfill。

Chrome 与 Firefox 扩展兼容性

Chrome 与 Firefox 扩展在大部分 WebExtensions 接口上是一致的,但有三处日常都会遇到的差异:
  • 后台脚本: Chrome (Manifest V3) 要求 background.service_worker。Firefox 使用 background.scripts,并采用非持久事件页。Extension.js 通过同一份带前缀的 manifest 同时分发到两者。
  • 运行时 API 命名空间: Firefox 原生支持 browser.*。Chromium 使用 chrome.*。在 Chromium 目标中传入 --polyfill 可以填平这个差异。
  • 权限与内容安全策略 (CSP): 浏览器对部分 permissionshost_permissions 条目的处理不同。把浏览器差异放进带前缀的 manifest 键里,而不是在运行时做特性检测。

浏览器特定的 manifest 字段

浏览器特定的 manifest 字段是 Extension.js 让一份 manifest.json 在多浏览器中工作的方式。编译时 Extension.js 会按当前目标过滤带前缀的键(chromium:chrome:edge:firefox:gecko:)。不带前缀的键在所有目标中都生效。完整前缀列表请参见浏览器特定的 manifest 字段

模板示例

action

action template screenshot 通过一个能在 Chrome、Firefox 和 Edge 中运行的 action 弹窗,体验跨浏览器兼容性。
npx extension@latest create my-extension --template=action
代码仓库:extension-js/examples/action

工作原理

1) 选择浏览器目标

选择你想运行扩展的位置。 --browser 选择常见目标,或传入自定义的浏览器二进制路径。
extension dev --browser firefox
extension dev --chromium-binary /Applications/Brave\\ Browser.app/Contents/MacOS/Brave\\ Browser
使用与你的操作系统匹配的二进制路径:
  • macOS/Applications/Brave Browser.app/Contents/MacOS/Brave Browser
  • Linux/usr/bin/brave-browser(或其他基于 Chromium 的浏览器二进制)
  • Windows"C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
当你传入二进制路径时,Extension.js 会把它映射到对应的浏览器引擎目标:
  • --chromium-binary 对应 chromium-based
  • --gecko-binary 对应 gecko-based

2) 按浏览器过滤 manifest 字段并编译

编译期间,Extension.js 只包含当前所选浏览器对应的 manifest 字段。 例如:
{
  "chromium:background": {
    "service_worker": "sw.js"
  },
  "firefox:background": {
    "scripts": ["sw.js"]
  }
}
对于 Chromium 系目标,Extension.js 使用 chromium:chrome:edge: 等前缀。
对于 Firefox 系目标,则使用 firefox:gecko:
完整的带前缀 manifest 字段说明,请参见浏览器特定的 manifest 字段

3) 按浏览器目标输出

Extension.js 会把每个目标写入各自的构建目录:
  • dist/chrome
  • dist/edge
  • dist/firefox
  • dist/chromium-based(自定义 Chromium 引擎)
  • dist/gecko-based(自定义 Gecko 引擎)
这样你的构建产物井井有条,也更便于在 CI 中发布。

4) 可选:为 Chromium 目标启用 browser.* polyfill

如果你的代码使用 browser.*,可以在 Chromium 系目标中启用 --polyfill
extension build --browser chrome --polyfill
启用后,Extension.js 会为非 Firefox 目标使用 webextension-polyfill(Mozilla 的 browser.* 兼容库)。
对于 Firefox,Extension.js 会跳过这一步,因为 Firefox 已原生支持 browser.*

最佳实践

  • 保持一份代码:尽量用带前缀的 manifest 字段表达浏览器差异。
  • 每次只构建一个目标:在持续集成 (CI) 中为每个浏览器单独生成产物(dist/<browser>)。
  • 必要时再用 --polyfill:仅当 Chromium 系目标依赖 browser.* 时启用。
  • 及早检查 API 支持情况:依赖浏览器特定 API 前先查阅 MDN WebExtensions 文档

下一步