前言
对于没有接触过chrome插件开发的同学来说,chrome插件也不是一个陌生的东西,它在我们的日常浏览器使用过程中作为常用且便捷的小工具往往能带来四两拨千斤的效果,不论是复杂的研发流程提效还是简单的网页数据存取、英文划词翻译等功能,它都能带给我们不少网上冲浪的助力。
对于有chrome插件V2版本开发经验的同学来说,从2022年6月开始,chrome插件商店就不再接受非V3版本的新插件上架了,明年1月现有老插件的更新版本也被限制为必须为V3版本,2023年中将不再支持所有老版本插件;所以要维护现有插件的同学也需要及时迁移项目为V3版本。
目前学习的 chrome 插件开发的最大难点在于各类论坛里几乎没有几篇V3版本的教程,并且由于V2版本和V3差别非常大,甚至在开发过程中遇到问题也没有办法参考 stackoverflow.com 上的V2相关问答内容,所以本文会用最好理解的角度介绍V3版本插件开发的基础内容,带新司机迅速上路,陪老司机快速转换赛道 🚀
一个常见插件的组成
最前方指路👉 官方文档
身份证——manifest.json
对于你的chrome浏览器来说,一个目录只要存在一个符合规范的manifest.json,这个目录就可以被认为是一个chrome插件,哪怕它并没有其它的功能。
manifest.json里含有一个插件最重要的一些信息,下面我们就来简单介绍一下:
{
"name": "英文文本纠错插件", //插件名称
"version": "0.1", //当前版本
"background": {
"service_worker": "background.js" //background文件
},
"manifest_version": 3, //插件manifest版本
"content_scripts": [{ //content.js文件和它依赖的第三方库
"matches":["*://*/*"],
"js": ["./thirdParty/lodash.js","./thirdParty/jquery-3.6.0.min.js","content.js"]
}],
"permissions": [ //需要权限的能力
"tabs"
],
"host_permissions": [ //域名权限
"*://*/*"
],
"action": { //控制插件在浏览器在toolbar的显示
"default_icon": "img/icon.png", //插件logo
"default_title": "Data-TnS 英文文本纠错插件", //插件logo hover时的tooltip提示
"default_popup": "popup.html"//插件本体页面
}
}
通过阅读上面的manifest.json,我们可以很清晰的获得这个插件的名字、版本、需要的chrome权限、content 文件依赖的第三方库等信息。
插件本体——popup page
插件的本体就是我们点击浏览器左上方icon后弹出的页面,在这个页面里我们可以做各种想做的事情,比如说展示信息、接收用户输入和进行跨域请求。
popup的功能很好理解,同时它的生命周期也非常短,每次点击后被激活,非插件任意页面区域任意点击就会关闭popup page,它的生命周期也就结束了;所以能在popup page中实际可以做的事是非常有限的。
对dom超能力——content
如果我们只想做一个类似网页版计算器的 chrome 辅助计数插件 / 闹钟提醒插件,其实是完全用不到content 这个“超能力”的,因为普通的计算器只需要关注用户输入,并不需要处理现有浏览器页面上的数据。
但是如果我们想要做一个网页内容笔记插件/划词记录, 只是简单的在自己的 popup 单页面这一亩三分地整活就不能满足我们的需求了,我们需要可以真正获取当前浏览器 tab 页面 dom 的能力,并且希望可以在 dom 中做一些修改。
有了这个能力,我们就有了很大的想象空间,我们完全可以给没有夜间模式的网站注入自己的 css,让它拥有新的黑暗风格样式,比如这款 dark reader。
每个插件的 content 都工作在一个沙箱中,它不会影响其他插件的 content,也不能访问到页面在window 上挂载的全局变量,保证了在使用插件时浏览器页面的稳定性。
同时为了保证安全性,我们也不能在 content 中使用evil
函数,否则可能会带来XSS攻击。
上帝视角——background
为什么说 background 是上帝视角呢,因为它可以监听用户在浏览器各个 tab 中的操作!它需要时加载,在空闲时卸载,所以可以理解它是在一个对用户不可见的隐藏 tab 中执行。
同时,这里也可以访问所有的 chrome api , 而能影响页面 dom 的 content 只能使用一部分 chrome api。
什么情况下我们可以用到 background 呢?试想我们要开发一个可以下载b站视频的插件,这个插件就会在浏览器未关闭的时间里持续监听用户是否浏览到了b站域名。如果用户打开了一个b站的页面,那么就在页面边缘一个固定位置渲染一个 button,用户点击即可下载当前页面的视频资源。
我们可以在 chrome 的任务管理器中看到浏览器中使用 background 正在监听的插件。
Overall——模块消息传递
还有和其它插件/和浏览器页面/Native app的通讯方式,详细了解请看 👉 官方模块通信文档
V2 to V3
简单来说,V3版本为了更高的安全性和更好的保护用户隐私,对开发人员做出了更多的限制。
从开发者角度来说,新的 manifest.json 和 api 修改让我们的开发在某些地方变得没有之前容易了;但从用户角度来说,大家都不希望使用第三方插件而泄露了自己的个人数据,所以这次版本更新的break change也是大势所趋。
重点限制
禁止使用远程托管的第三方依赖库
chrome 要求 V3 版本插件所依赖的所有脚本逻辑必须包含在插件源文件内部。
所以不能以cdn的形式在插件页面中使用第三方依赖库,你需要把依赖内容下载到本地目录。
background 能力限制
- service worker 无权访问 dom
- service worker 会不使用时终止,并在需要时重新启动(V2 版本是可以设置为持续运行的)
- 重启可能会导致状态丢失,应该使用存储 api 进行存储
- 不能使用 XMLHttpRequest 进行请求,需要转换为 fetch
详细了解请看 👉 官方迁移文档
开发与调试
调试入口
popup page
直接在插件页面上左键点击检查进入控制台即可。
content
由于 content 可以直接为当前浏览器页面注入脚本逻辑,所以它的调试入口和普通页面是一致的。
我们可以点击F12进入控制台,为了避免干扰我们还可以只筛选出目标插件的console结果。
background
在浏览器导航栏输入chrome://extensions/
进入扩展管理页。
先打开右上角开发者模式,再点击目标插件的查看视图 Service Worker,即可打开控制台。
注意点
在插件开发阶段,我们只需要点击加载已解压的扩展程序,就可以将我们本地开发的插件以文件夹的形式加载到chrome中。
- 当我们需要修改 content 中的内容时,我们需要点击目标插件卡片右下角的重新加载按钮,然后刷新我们的浏览器页面; 如果只重新加载插件,会导致一些意想不到的 error。
- 每次更新内容 popup page 中的内容时,只需要重新打开一下 popup page 就可以了,不需要刷新页面,也不需要重新加载插件。
- 当我们插件的 manifast.json 有任何错误时,会直接阻塞插件的重新加载;当运行时有任何错误时,也会在卡片页面展示错误。
Mini 开发 sop
如果你要开发一个 chrome 插件,可以按这个步骤简单规划一下:
- 明确功能,要做的东西需要满足什么需求 ?
- 遛一遍官方文档,看看这个功能可以通过现有chrome api 实现吗 ?
- 明确这个插件需要编写哪些内容(popup? content? background?)
- 下载需要依赖的第三方库在本地开发目录中
- 开搞!
- 上架 chrome 扩展商店
参考
“我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!”