Plasm 是什么?

Plasmo 是个浏览器插件开发框架,号称浏览器扩展界的 Next.js

其框架提供的特性如下:

安装

首先安装一个 React 的模板:

1
2
3
pnpm create plasmo example-dir
cd example-dir
pnpm dev

如果想使用其他模板,可以使用该命令,可以在此 https://github.com/PlasmoHQ/examples/ 查看所有可用的模板

1
pnpm create plasmo --with-env

安装错误:

  • sharp 安装失败

解决方法:https://sharp.pixelplumbing.com/install#chinese-mirror

sharp 的安装包在外网,在国内有可能会下载失败,添加个 npm 代理,使用国内的镜像

1
2
npm config set sharp_binary_host "https://npmmirror.com/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npmmirror.com/mirrors/sharp-libvips"

这两条命令只能在 npm v9 以下的版本生效,用 v9 版本会报错

启动及调试插件

  1. 启动很简单使用 pnpm run dev命令即可启动一个开发服务器,启动成功后会在 build目录下生成开发产物:

  1. 打开 chrome 的插件管理页面(chrome://extensions/),打开【开发者模式】开关,点击【加载已解压的扩展程序】,选择项目中的 build/chrome-mv3-dev目录:


  1. 加载成功后可以将其固定到状态栏中,便于后续开发:

  1. Plasm 有热重载功能,修改代码后,Plasm 会自动刷新当前激活的 tab,其它 tab 可以点击右下角的按钮手动刷新

各种 Pages

Plasm 的文档中有好几种 page,不熟悉浏览器插件的估计会一脸懵逼,这里来总结下各种 page 的作用,以及出现的地点:

Page 页面出现地点 说明 代码位置
extension pages
(这些页面是浏览器插件机制内的页面,和 Plasm 框架无关,并且在浏览器中也有实体按钮)
popup page 点击状态栏的插件图标后弹出,点击空白地方消失 popup.tsx

popup/index.tsx
options page 右键点击插件图标,选择【选项】栏后,会打开个新页面,这个页面一般用作插件的配置页面 options.tsx

options/index.tsx
new tab page 在点击主页按钮或者新建 tab 页时会打开该页面,同时浏览器的启动页配置会变成插件
这个 page 在开发导航类的插件时会非常有用
newtab.tsx

newtab/index.tsx
dev tools page 在开发者工具中会出现个新的 tab,这个的内容就是该页面 devtools.tsx

devtools/index.tsx
框架页面
(这些页面都是框架提供的,通常以编程方式重定向到或打开这些页面
tab pages 使用场景:
1. 首次安装插件时的欢迎页面
2. 登录鉴权页面
3. 需要更精细的路由控制时
可以在以下 URL 的方式访问这些页面:
chrome-extension://<extension-id>/tabs/delta-flyer.html
tabs 目录下
sandbox pages 这个页面主要用在 iframe 里面,因为和主页面的上下文隔离,安全性更高,可以用来执行一些动态生成的代码 sandbox.ts file

sandboxes/.ts

各种 Scripts

上面介绍了各种 pages 的作用,现在又出现个多个 scripts 同样让人摸不着头脑,这里我们再来总结下他们的作用:

script 说明 代码位置
content script content script 会运行在各个 tab 的上下文中,有多少个 tab 页,该脚本就会执行多少次,并且各个 script 不会互相干扰,并且和页面自身的 JavaScript 保持隔离
使用场景:
1. 从当前网页抓取数据
2. 从当前网页中选择、查找元素并设置样式
3. 将 UI 元素注入当前网页
4. 将代码注入“main work”上下文
content.ts
或者
contents/.ts
background service worker 是一种后台服务,它可以处理一些长时间运行的任务,例如下载文件、缓存数据、推送通知等。这种方式可以节省内存,提高用户体验性,同时在离线状态下,依然能提供一些离线服务
每个 tab 下都会有一个独立的 background service worker。这是因为每个 tab 都是一个独立的浏览器窗口,而 service worker 只能在后台运行,不能直接与网页的内容直接进行交互
background.ts

background/.ts

通信 Message

Plasm 提供的 Message API 便于在各个组件之间的消息的发送,中继以及接收。官方文档介绍其 API 是声明式,类型安全,函数式以及基于 Promise,相比于我们自己封装,Plasm 提供的 API 更加的完善。

Plasm 将 Message API 封装到一个单独的 package 中,使用之前需要安装:

1
pnpm install @plasmohq/messaging

Message API 的分类如下:

下表中的单词缩写如下:

Extension Pages -> Ext-Pages

Content Scripts -> CS

Background Service Worker -> BGSW

Messaging API From To One-time Long-lived
Message Flow Ext-Pages/CS BGSW Yes No
Relay Flow Website CS/BGSW Yes No
Ports Ext-Pages/CS BGSW No Yes
Ports BGSW Ext-Pages/CS No Yes
Ports + Relay BGSW WebPage Yes Yes

Message Flow

Message Flow 非常适合 extension pages,tab pages 或者 content scripts 等前台和 background service worker 后台服务的一次性通信。在将一些繁重的工作扔给后台处理和绕过 CORS 时用此通信方式就非常合适。

具体使用方法见官方文档该位置,这里不过多介绍

Relay Flow

该 API 还不太稳定,谨慎使用

看文档介绍该 API 用于 target webpage background service worker 之间的通信,听着和上面的 Message Flow 很像。

但是研究下官方的示例,发现 Relay Flow 和 Message Flow 的作用截然不同。简单来说,如果 target webpage 也是你开发的,并且需要将 message 传递到配套的插件 background service worker 里,那么就可以将 content scripts 作为中转,完成消息的发送。

该 API 的使用场景还是比较局限的,但是在某些场景下可能会有奇效。

具体使用方法见官方文档该位置,这里不过多介绍

Ports

该 API 还不太稳定,谨慎使用

Messaging Ports API 是对插件原生的 port API 的抽象,主要用于和 background service worker 建立长链接。

具体使用方法见官方文档该位置,这里不过多介绍

存储 Storage

环境变量 Environment Variables