Open lmk123 opened 1 year ago
2023 年 11 月 17 日更新:Chrome 发了新公告,准备从 2024 年 6 月开始下架并禁用 Manfiest V2 了 :joy:
2022 年 12 月 13 日更新:哈哈哈,Chrome 果然推迟了 Manifest V2 的下线时间:
以下是原文。
最近着手准备将划词翻译迁移到 Manifest V3,我以为最多只是没了 DOM 环境,等真的开始迁移了才发现这件事比我想的要复杂得多。
Chrome 官方虽然提供了迁移指南,但这份指南略微简陋,我将在下面补充一些细节。
先说说 DOM 环境吧,这一点划词翻译需要注意的地方有:
response.ok
responseType: 'document'
划词翻译使用了 Webpack 来构建,目前,划词翻译使用同一份 Webpack 配置来处理内容脚本和背景页的代码,因为它们都是输出成 web 的,但背景页变成 Service Worker 之后,背景页的代码就要单独输出成 webworker 了。
web
webworker
我一开始以为需要注意的点只是没了 DOM 环境,但后来我意识到,Service Worker 是一个事件驱动的背景页,这就很棘手了……
在解释这个问题之前需要先讲一下大致的背景。
在我 2012 年开发划词翻译的时候,背景页是持续存在的,也就是只要浏览器启动,那么背景页就会被加载并运行,直到浏览器关闭了背景页才会关闭。
后来在 2018 年,Chrome 推荐开发者迁移成事件驱动的背景页以减少资源占用,这种背景页简单概括就是,Chrome 会在扩展程序的背景页空闲时关闭背景页,只有产生了背景页监听的事件的时候才会重新打开背景页。
举个例子,假设我们的背景页只有下面的代码:
var tabs = [] chrome.tabs.onCreated.addListener(tab =>{ tabs.push(tab.id) }) setInterval(() => { console.log(tabs) })
在背景页是持续存在的时候,这段代码没有任何问题,但是当背景页是事件驱动的时候就有问题了,它的运行逻辑会变成这样:
tabs
可以使用 chrome.runtime.onSuspend 在背景页被关闭得到通知,但无法阻止 Chrome 关闭它。另外,Manifest V3 中不会触发此事件。
很明显,这么一对比,肯定是持续存在的背景页更省事,所以划词翻译一直没有迁移成事件驱动的背景页,但背景页变成 Service Worker 之后,浏览器会强制在 5 分钟后关闭 Service Worker,然后只在有事件被触发时才重新运行 Service Worker,所以从事实上将 Manifest V3 的扩展程序变成了事件驱动的背景页。
很多扩展程序就是因为这一点没法迁移到 Manifest V3,贴两个典型的:
于我而言,这才是最让我头皮发麻的一点,这意味着:
具体的细节可以查阅 Migrating from background pages to service workers
可是我的背景页非常的复杂,这一改动工作量巨大,且一定会出 bug,这才是迁移过程中最大的障碍。
距离 Chrome 决定全面禁用 Manifest V2 只有半年时间了,但 Service Worker 仍然有很多问题。
chrome.runtime.webRequest 不会唤醒 Service Worker 的 bug 直到 Chrome v108(两天前才刚发布)里才修复,而除此之外,我还看到很多 bug 反馈说还有很多事件都没有唤醒 Service Worker,比如 chrome.runtime.sendMessage(见 MV3 Serviceworker won't wake up when sent a message from the contentscript)
chrome.runtime.webRequest
chrome.runtime.sendMessage
换句话说,即使我今天就把划词翻译成功迁移到了 Manifest V3,那也需要用户全都立刻升级到最新版本的 Chrome 才能正常用,这根本不可能。
除此之外,Service Worker 还有很多不兼容 Manifest V2 的地方,有人列了一个清单:Use cases that are not well served by service workers
我怀疑今年 6 月份 Chrome 还是没法禁用 Manifest V2,也但愿如此 😂
迁移最大的障碍是要把一个持续存在的背景页迁移成事件驱动的,其次才是 DOM 环境的问题。我打算先做 DOM 环境的迁移,万一 Chrome 之后提供持久存在的 Service Worker 了呢 :joy:
下一个版本中,edge中deepl也一样受到影响吗?
@biiauchann Chrome、Edge、Firefox 都会受到同等的影响
2023 年 11 月 17 日更新:Chrome 发了新公告,准备从 2024 年 6 月开始下架并禁用 Manfiest V2 了 :joy:
2022 年 12 月 13 日更新:哈哈哈,Chrome 果然推迟了 Manifest V2 的下线时间:
以下是原文。
最近着手准备将划词翻译迁移到 Manifest V3,我以为最多只是没了 DOM 环境,等真的开始迁移了才发现这件事比我想的要复杂得多。
Chrome 官方虽然提供了迁移指南,但这份指南略微简陋,我将在下面补充一些细节。
没了 DOM 环境后需要改动的点
先说说 DOM 环境吧,这一点划词翻译需要注意的地方有:
response.ok
来判断调用是否成功。responseType: 'document'
要换成基于字符串的解析方式了。Service Worker 需要单独的 Webpack 输出配置
划词翻译使用了 Webpack 来构建,目前,划词翻译使用同一份 Webpack 配置来处理内容脚本和背景页的代码,因为它们都是输出成
web
的,但背景页变成 Service Worker 之后,背景页的代码就要单独输出成webworker
了。Service Worker 不仅仅是没了 DOM 环境,它还是一个事件驱动的背景页
我一开始以为需要注意的点只是没了 DOM 环境,但后来我意识到,Service Worker 是一个事件驱动的背景页,这就很棘手了……
在解释这个问题之前需要先讲一下大致的背景。
在我 2012 年开发划词翻译的时候,背景页是持续存在的,也就是只要浏览器启动,那么背景页就会被加载并运行,直到浏览器关闭了背景页才会关闭。
后来在 2018 年,Chrome 推荐开发者迁移成事件驱动的背景页以减少资源占用,这种背景页简单概括就是,Chrome 会在扩展程序的背景页空闲时关闭背景页,只有产生了背景页监听的事件的时候才会重新打开背景页。
举个例子,假设我们的背景页只有下面的代码:
在背景页是持续存在的时候,这段代码没有任何问题,但是当背景页是事件驱动的时候就有问题了,它的运行逻辑会变成这样:
tabs
是空数组tabs
就不是空的了很明显,这么一对比,肯定是持续存在的背景页更省事,所以划词翻译一直没有迁移成事件驱动的背景页,但背景页变成 Service Worker 之后,浏览器会强制在 5 分钟后关闭 Service Worker,然后只在有事件被触发时才重新运行 Service Worker,所以从事实上将 Manifest V3 的扩展程序变成了事件驱动的背景页。
很多扩展程序就是因为这一点没法迁移到 Manifest V3,贴两个典型的:
于我而言,这才是最让我头皮发麻的一点,这意味着:
可是我的背景页非常的复杂,这一改动工作量巨大,且一定会出 bug,这才是迁移过程中最大的障碍。
Service Worker 直到现在(2022 年 12 月 7 日)仍有很多未解决的问题
距离 Chrome 决定全面禁用 Manifest V2 只有半年时间了,但 Service Worker 仍然有很多问题。
chrome.runtime.webRequest
不会唤醒 Service Worker 的 bug 直到 Chrome v108(两天前才刚发布)里才修复,而除此之外,我还看到很多 bug 反馈说还有很多事件都没有唤醒 Service Worker,比如chrome.runtime.sendMessage
(见 MV3 Serviceworker won't wake up when sent a message from the contentscript)换句话说,即使我今天就把划词翻译成功迁移到了 Manifest V3,那也需要用户全都立刻升级到最新版本的 Chrome 才能正常用,这根本不可能。
除此之外,Service Worker 还有很多不兼容 Manifest V2 的地方,有人列了一个清单:Use cases that are not well served by service workers
我怀疑今年 6 月份 Chrome 还是没法禁用 Manifest V2,也但愿如此 😂
总结
迁移最大的障碍是要把一个持续存在的背景页迁移成事件驱动的,其次才是 DOM 环境的问题。我打算先做 DOM 环境的迁移,万一 Chrome 之后提供持久存在的 Service Worker 了呢 :joy: