一、Manifest V2 即将被弃用
在今年年初收到v2就要被弃用的通知后,还沉浸在过年喜悦中的心立马紧绷起来。在去年年初的时候就已经有计划
升级v3了,但是因为改动太大,而且谷歌后面延迟了v2弃用时间(谷歌原计划是2023年6月弃用),所以升级任务暂时被搁置了。如今已经确认弃用时间,那只能撸起袖子加油干了。
二、Manifest V3 改动点
我们项目用的技术栈是vue2+webpack,下面提到的改动点是我们项目有用到的,没提到的可自行查看官方迁移文档
1、 Manifest.json 文件
1.1 将 manifest_version 字段的值从 2 更改为 3。
{ "manifest_version": 3 }
1.2 更新主机权限
在Manifest V2 中,有两种方法为你的api或任何主机获得权限,要么在 permissions 数组或 optional_permissions 数组。
而 v3 的权限粒度划分会更细腻,不会像之前权限一把梭,所以像主机访问权限配置需要单独添加到 host_permissions 中:
// v2
{
"permissions": [
"tabs",
"bookmarks",
"https://www.blogger.com/", // 之前主机权限都在 permissions
],
"optional_permissions": [
"unlimitedStorage",
"*://*/*",
]
}
// v3
{
"permissions": [
"tabs",
"bookmarks"
],
"optional_permissions": [ // 单独配置主机权限
"unlimitedStorage"
],
"host_permissions": [
"https://www.blogger.com/",
],
"optional_host_permissions": [// 单独配置主机权限
"*://*/*",
]
}
1.3 替换background字段
在 Manifest V3 中,后台页面被 Service Worker 所取代。下面列出了清单更改。
- 将
manifest.json中的"background.scripts"替换为"background.service_worker"。请注意,"service_worker"字段接受字符串,而不是字符串数组。 - 从
manifest.json中移除"background.persistent"。
1.4 更新 web_accessible_resources 字段
web_accessible_resources 用于指定哪些资源文件可以被 web 页面访问和加载,但在 v2 时也是一把梭,基本一次配置哪哪的网页都能访问,同样在 v3 此字段改为资源与匹配的对象形式,看代码就懂了:
// v2
{
...
"web_accessible_resources": [
"images/*",
"style/extension.css",
"script/extension.js"
],
...
}
// v3
{
...
"web_accessible_resources": [
{
"resources": [
"images/*"
],
"matches": [
"*://*/*"
]
},
{
"resources": [ // 指定资源
"style/extension.css",
"script/extension.js"
],
"matches": [ // 谁可以访问
"https://example.com/*"
]
}
],
...
}
1.5 合并 browser_action 与 page_action 为 action
// v2
{
"browser_action": { … },
"page_action": { … }
}
// v3 直接合并成一个即可
{
"action": { … }
}
1.6 content_security_policy 需要从 string 改为对象配置
content_security_policy 用于定义加载和执行内容的安全策略,在 v3 版本你需要通过对象的形式来做配置:
// v2
"content_security_policy": "script-src 'self' 'unsafe-eval' https://cdn.lr-in-prod.com; object-src 'self'"
// v3
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'",
"sandbox": "sandbox allow-same-origin",
"web_accessible_resources": "https://cdn.lr-in-prod.com"
}
2、background 迁移 Service Worker
这个算是这次升级最大的改动了,已经的很多功能都需要大改甚至部分功能没有替代方案,如加载第三方脚本等。下面将一一列出我们项目需要改动到的地方。
1.1 全面禁止加载远程代码
- 之前用webpack打包出来的代码含有eval,需要去掉,处理方法:配置devtool: 'cheap'
- 打包出来的代码也含有jsonp,处理方法:将动态引入全部改成静态引入
1.2 禁止所有dom操作(window也无法访问)
- 之前Bakcground环境和popup环境中数据通信是直接在Bakcground的window上保存,然后popup通过chrome.extension.getBackgroundPage获取。在v3中需要使用chrome.runtime.onMessage和chrome.runtime.sendMessage进行数据通信,在popup处设置轮询,五秒一次获取一次Bakcground环境数据。
- 用chrome.storage代替localstorage,由于chrome.storage是异步的,所有同步获取的逻辑得重构。
- 去除第三方包影响,我们项目中引入的一些第三方包里面有用到dom操作,由于没有找到更好的替代包,所以我是直接用webpack插件将源码给修改了
- settimeout、setInterval替换成chrome.alarms
1.3 请求方式只能用fetch
我们项目用的是axios,如果替换成fetch的话,改动太大,所以放弃了直接用fetch替换。最后想到的是用为axios增加一个fetch Adapter,这样可以在代码不用更改的情况下,所有请求逻辑走到最新的fetch请求里。这里需要注意fetch的中断需要用AbortController
1.4 webpack热更新魔改
chrome.runtime.getPackageDirectoryEntry在serviceworker里已被弃用,之前的hot-reload文件已失效。现自己实现一个hot-reload,原理:用node启一个websocket服务器,监听dist目录文件变化,serviceworker监听ws通知实现重载。以上功能集成到webpack插件里,在开发环境时运行
1.5 谷歌api替换
最后一步,把所有api替换完,就搞定啦!
3、总结
由于国内关于谷歌插件v2迁移v3的文章稀少,而谷歌自身文档写的也一眼难尽,所以升级过程中踩了许多坑。但总算也是升级完拉。