Plasm 是什么?
Plasmo 是个浏览器插件开发框架,号称浏览器扩展界的 Next.js !
其框架提供的特性如下:
- 一流的 React + Typescript 支持
- 声明式开发(自动生成 manifest.json)
- 将 UI 组件渲染到网页
- 扩展内置页面
- 扩展热重载 + React 模块热更新
- .env* 文件
- 扩展储存 API
- 扩展通信 API
- 远程代码打包 (例如 Google Analytics)
- 支持多个浏览器和 manifest 版本
- 通过 BPP 进行自动部署
- 可选 Svelte 或 Vue 进行开发
安装
首先安装一个 React 的模板:
1 | pnpm create plasmo example-dir |
如果想使用其他模板,可以使用该命令,可以在此 https://github.com/PlasmoHQ/examples/ 查看所有可用的模板
1 | pnpm create plasmo --with-env |
安装错误:
- sharp 安装失败

解决方法:https://sharp.pixelplumbing.com/install#chinese-mirror
sharp 的安装包在外网,在国内有可能会下载失败,添加个 npm 代理,使用国内的镜像
1 | npm config set sharp_binary_host "https://npmmirror.com/mirrors/sharp" |
这两条命令只能在 npm v9 以下的版本生效,用 v9 版本会报错
启动及调试插件
- 启动很简单使用
pnpm run dev命令即可启动一个开发服务器,启动成功后会在build目录下生成开发产物:

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

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

- 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/ |
各种 Scripts
上面介绍了各种 pages 的作用,现在又出现个多个 scripts 同样让人摸不着头脑,这里我们再来总结下他们的作用:
| script | 说明 | 代码位置 |
|---|---|---|
| content script | content script 会运行在各个 tab 的上下文中,有多少个 tab 页,该脚本就会执行多少次,并且各个 script 不会互相干扰,并且和页面自身的 JavaScript 保持隔离 使用场景: 1. 从当前网页抓取数据 2. 从当前网页中选择、查找元素并设置样式 3. 将 UI 元素注入当前网页 4. 将代码注入“main work”上下文 |
content.ts 或者 contents/ |
| background service worker | 是一种后台服务,它可以处理一些长时间运行的任务,例如下载文件、缓存数据、推送通知等。这种方式可以节省内存,提高用户体验性,同时在离线状态下,依然能提供一些离线服务 每个 tab 下都会有一个独立的 background service worker。这是因为每个 tab 都是一个独立的浏览器窗口,而 service worker 只能在后台运行,不能直接与网页的内容直接进行交互 |
background.ts 或 background/ |
通信 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 建立长链接。
具体使用方法见官方文档该位置,这里不过多介绍






