使用 Plasmo,只需编写 React 组件,即可创建浏览器扩展程序。
创建项目
通过以下命令,创建基础的 Plasmo 浏览器扩展项目结构:
npm create plasmo
创建文件:
- 创建了一个 package.json 文件,与普通项目比起来,多了一个 “manifest” 属性,可自定义插件相关信息。
- 创建了一个 popup.tsx 文件,用于编写插件代码。
开发与加载扩展
执行命令
npm run dev
在 Chrome 中加载扩展程序:到扩展管理中加载解压缩的拓展,加载 build/chrome-mv3-dev
目录。
扩展页面创建
https://docs.plasmo.com/framework/ext-pages
创建这些文件,正常编写 React 代码即可。
- 弹出页面 popup.tsx
- 选项设置页 options.tsx
- 开发工具页 devtools.tsx
- 新标签页 newtab.tsx
注入内容脚本
插件往往需要注入到网页中,通过内容脚本来实现。
- 仅注入脚本: https://docs.plasmo.com/framework/content-scripts
- 注入 UI 界面: https://docs.plasmo.com/framework/content-scripts-ui
我们创建 content.tsx
,注入 UI 界面。
设置匹配域名时启用,如仅在本站博客文章页面使用:
import type { PlasmoCSConfig } from "plasmo"
export const config: PlasmoCSConfig = {
matches: ["https://heibaimeng.com/post/*"]
}
导出组件,里面编写需要注入的 UI 内容:
export default () => (
<div>
<button onClick={() => alert("hello")}>hello</button>
</div>
)
默认注入到 body,使用 Overlay
(绝对定位)的方式。可通过钩子改为 Inline
模式,直接插到某个节点旁:
export const getInlineAnchor: PlasmoGetInlineAnchor = async () =>
document.querySelector(/* ... */)
打开控制台,可以发现组件挂载在 plasmo-csui 这个 web components 的 shadow-root 内了。所以直接加载 css 只会影响原页面,不会影响注入的 UI 内容,需要通过钩子 加载 CSS:
import cssText from "data-text:./content.css"
export const getStyle = () => {
const style = document.createElement("style")
style.textContent = cssText
return style
}
可以自行指定 shadow host id,方便 dom 操作:
const HOST_ID = "heibaimeng-shadow-host"
export const getShadowHostId = () => HOST_ID
// dom 操作
document.getElementById(HOST_ID).shadowRoot
官方示例
https://github.com/PlasmoHQ/examples/tree/main
- 引入 antd 示例:https://github.com/PlasmoHQ/examples/tree/main/with-antd
- content-scripts-ui 示例: https://github.com/PlasmoHQ/examples/tree/main/with-content-scripts-ui
- vue 示例: https://github.com/PlasmoHQ/examples/tree/main/with-vue
- ...