lmk123 / blog

个人技术博客,博文写在 Issues 里。
https://github.com/lmk123/blog/issues
623 stars 35 forks source link

将划词翻译的 Chrome 和 Firefox 安装包合二为一的尝试 #97

Open lmk123 opened 2 years ago

lmk123 commented 2 years ago

由于最近发生了一起“误将 Firefox 安装包发到了 Chrome 扩展商店“的 P0 事故(详细介绍见 #96),我开始考虑能不能将这俩安装包合二为一,这样就肯定不会再出现这个问题了。

我梳理了一下我以前分为两个安装包的原因,发现似乎确实可以合二为一。下面逐个分析一下 Firefox 与 Chrome 的不同之处,以及合二为一的解决方案。

browser vs chrome

Firefox 的扩展程序相关的 API 都放在全局变量 browser 下面,但是 Chrome 的放在全局变量 chrome 下面,且 browser 是基于 Promise 的,而 chrome 基于 Callback。

一来为了开发时的体验,二来为了兼容两个浏览器,我在开发时用了 Firefox 的 webextension-polyfill。这个 polyfill 在 Firefox 里是不需要的,所以为了减少 Firefox 安装包的大小,我仅在 Chrome 的安装包里才包含了 webextension-polyfill,这也是导致 Firefox 的安装包安装在 Chrome 里完全不能用的原因:Chrome 没有全局变量 browser

如果要将 Firefox 和 Chrome 合二为一,那么只需要把 webextension-polyfill 也包含进 Firefox 就可以了。

manifest.json 不同

首先,由于 Firefox 不支持全局快捷键,所以 manifest.json 中的 commands 不能设置 global: true,但 Chrome 里需要设置。

经过我的测试,即使加上 global: true,在 Firefox 91.0 里也只是会有一个警告信息,但仍然能成功安装。

其次,Chrome 对 options_ui 的支持程度不一样。大概在 2016 年,当时的 Chrome 还不支持 options_ui,只支持 options_page: "options.html" 这种形式;后来,Chrome 虽然支持了 options_ui,但 Firefox 中的 options_ui.browser_style 在 Chrome 中是 options_ui.chrome_style。为了尽可能兼容低版本的 Chrome,我给 Chrome 的安装包用的是 options_page,给 Firefox 用的是 options_ui

现在想想,已经过去 5 年了,用户的 Chrome 应该都支持 options_ui 了;chrome_style / browser_style 也只是一个可选的选项,所以这个也好改:Chrome 和 Firefox 都用 options_ui 并且去掉 chrome_style / browser_style 就可以了。

最后就是无痕(隐私)模式的设置项。这一项我在之前的版本中已经”合二为一“了,详情见 #90。

区分浏览器

有些代码只需要在 Firefox 里运行,而有些只需要在 Chrome 里运行。举个例子,由于 Chrome 支持全局快捷键而 Firefox 不支持,我会在 Chrome 里给用户加一个全局快捷键的提示,而 Firefox 里则改为告诉用户你的浏览器不支持全局快捷键。

同样是出于减少安装包大小的原因,我将浏览器类型的常量放在了 process.env.BROWSER_TARGET,这样代码里可以通过判断是不是 Chrome / Firefox 来再打包时删除没有运行到的代码。但为了合二为一,只能在运行时判断了。

总结

这么看下来,似乎确实可以将 Chrome 和 FIrefox 的安装包合二为一。我将在下个版本当中做个尝试,届时再更新一个后续。