记一次浏览器插件开发经历
最近做了一个浏览器插件的项目,私以为还是比较有意思的,在此记录一下经历。
这个浏览器插件的主要功能是,提供一个拨号盘界面,可以进行呼入、呼出的功能。再额外添加一些围绕着呼叫的辅助功能,比如:联络记录,通讯录,弹屏等等。
WXT 介绍
为了提高开发效率,我直接查找了可以用的插件开发框架,经过一番搜索最终选择了 WXT。
它可以使用流行的前端框架进行开发,它是建立在 Nuxt
之上的,而我对 Vue
还算比较熟悉,也就选择了 Vue
这条技术路线一路到底。
即使现在看来,整个开发过程的体验还是很轻松加愉快的。不足之处是,说明文档不是很全,有很多待补充内容,如果找不到想要的内容,只能到 issues 中寻找。
打开 WXT
的官方网站,找到 Get Stared
,初始化项目,
1 | pnpm dlx wxt@latest init <project-name> |
命令执行完成之后,会生成一些模板代码,具体有什么用可以到官网查看 Link 。
WXT
遵循的是 约定优于配置
,每个目录内的文件在最终编译时会转换为对应的文件。
例如:components
内的文件会转换为组件,background
内的文件会转为 ServiceWorker
,*.content.ts
会转为 content scripts
。
如果熟悉 Nuxt
的话,composables
, hooks
, utils
内的文件可以自动导入。像是在使用全局的函数,用起来很方便。
插件内的概念
在开始动手之前,需要先了解一下浏览器插件的概念,有助于开发。
popup
popup
是用户点击插件图标时,弹出的窗口。这个窗口有大小限制,为 800x600。
这个窗口内的内容,可以理解为就是html。框架内编写的vue组件是在这里渲染的。对应 WXT
的 entrypoints
目录中的 vue 文件。
每次打开 popup
时,vue代码都会重新加载。如果想实现一些状态共享的功能,在 popup
关闭时,状态都会清空,所以需要存到 storage
(后面讲)中在打开时再次读取。
background scripts
background scripts
是在浏览器后台运行的脚本。在 manifest v3 中,backgound scripts 就是 service worker.
对应 WXT
的 entrypoints/background
目录中的文件。
background scripts 不受跨域影响,可以监听来自 popup
和 content scripts
的消息。
content scripts
content scripts
是在浏览器页面中运行的脚本。在页面加载后会注入到页面中。可以操作 DOM 元素。
storage
storage
用来存储数据。类似 localStorage
,使用时必须加上前缀,local:
、session:
、sync:
和 managed:
。
与 localStorage
不同,storage
可以监听值的变化,也可以存储对象值。
storage
的数据可以在 popup
,background scripts
和 content scripts
之间共享。
我把它当作 Redis
来用,暂时没发现姿势有什么不对劲。
message
message
用来在 popup
,background scripts
和 content scripts
之间传递消息。
主要用法为
1 | // 接受消息 |
插件功能介绍
插件通话功能是由 jssip
实现的。页面上实现了登录注册,指定好后端地址,就可以使用通话功能了。
插件的页面组件使用了 vant
.
拨号盘和话务功能
这部分我使用 vue 画了一个拨号盘的界面用于用户交互。话务功能 jssip
中有现成的函数,可以拨号,挂断,静音等,直接调用相关函数就可以了。
拨号盘界面需要注意的是,要根据不同的话机状态,显示不同的样式。
因为 jssip
要获取用户媒体和创建 Audio 用于播放铃声,这部分代码只能放到 content scripts
脚本中。
个人暂时觉得还是不太完善,在网上查资料可以有 offscreen.html
和 background.html
的其他方法,暂未成功。
popup
中的状态,在用户关闭后就会丢失,而且这个窗口很容易被关闭。每次打开时都需要从 content scripts
中同步状态,这也就用到了 storage
和 message
。
来电通知使用了 notifications
,如下代码。这一部分倒是没遇到什么问题,jssip
收到来电后,使用 message
发到 background scripts
就可以了。
1 | browser.notifications.create({ |
为了加强插件状态的直观性,在通话和来电时改变图标,可以使用
1 | browser.action.setIcon({}); |
除了 jssip
的 websocket
外,插件还需要一个新的 websocket
获取后台系统的消息,以实现弹屏功能。这一部分也放到了 content scripts
脚本中,暂时没遇到什么坑,轻松加愉快。
通讯录
通讯录可以直接使用 vant
内的组件和 storage
来实现。
在使用 storage
存储的时候需要注意,数据是插件内全部可见的。也就是即使我这个插件需要不同的用户先登录后再使用,如果用户A保存了通讯录,用户B登录后也能访问到。
所以在保存这些数据时,需要给数据打上标记,让用户只能访问自己建立的数据。
弹屏功能
弹屏功能是收到来电后,可以打开指定的网页内容。网页可以由用户自行填写,支持内容替换。这样在和其他CRM系统集成的时候,可以方便的调用第三方系统内的功能。
这一部分也比较简单,使用 message
然后在 background scripts
脚本中处理。
1 | chrome.tabs.create({ url }); |
国际化
这一部分使用了 vueI18n
可以参照 WXT
的示例
没有遇到什么坑点,唯一要注意的是,在 background scripts
中,要这么用
1 | i18n.global.t('', {}, { locale: 'en' }); |
界面截图
总结
经过这个项目,我熟悉了浏览器插件的开发流程和概念。
幸好用了框架,没有让代码乱成一锅粥。
vue
生态中的资源也能很好的利用上。我想如果后续迭代的话,也很方便快捷。
——————
本文为个人原创,转载请署名且注明出处。