插件构建之plasma
插件构建之plasma
过去一年,开发了两款插件并上架谷歌商店,在最初技术调研时原本想使用plasma
,考虑插件包的体积与其他未知原因,最终我还是选择了webpack5
搭建了一个基础的chrome插件
,具体可参考之前写的一篇文章#放弃plasmo,webpack5搭建了一个chrome基础插件,因为原生的插件配置也非常简单。通常的插件api使用也踩了不少坑,但从新回顾,发现plasma
解决了我当初插件业务开发中的很多问题,也真正做到了让开发者只关注业务本身就行。
初始化一个插件项目
按照官方教程,初始化一个插件非常简单,使用一下命令就行,按照指定命令提示,快速初始化了一个插件项目
代码语言:javascript代码运行次数:0运行复制
pnpm create plasmo
我们看到初始化后的项目是下面这样的
我们发现这是一个原始的构建插件工程项目,当我们执行pnpm run dev
时,会生成一个build
文件夹,我们只需要打开chrome插件的开发者模式,添加这个build
此时我们加载完插件后,popup.html
插件就是这样的
我们修改的任何一行代码时,此时会热更新到插件,无需重新加载插件,这是我之前使用
webpack5
构建插件未解决的问题,因为我们次修改后,需要build,重新加载,才能生效,这种体验有点糟糕。但是plasmo
就完美解决插件热更新问题
调整项目文件夹名
我们看到初始化项目根目录的就是我们插件打开的
popup
页面,但是可以在根目录下新建一个popup
文件夹
// popup/
import { useState } from "react"
function IndexPopup() {
ct [data, setData] = useState("")
return (
<div>
<h1>:Web技术学苑</h1>
</div>
)
}
export default IndexPopup
在初始化后的文件夹,我们可以使用src
来组织我们的插件,具体可以参考src,从扩展页面中可以发现,在插件中的一些页面可以组织成以下
# contents/
# popup/
# opti/
# newtab/
# sidepanel/
# devtools/
我们发现popup
页面的样式如何控制
css module
我们看下popup
页面,我们引入的scss
对应的scss
.app {
width: 60px;
height: 600px;
}
popup
import { useState } from "react"
import style from "./scss"
function IndexPopup() {
ct [data, setData] = useState("")
return (
<div classame={style["app"]}>
<h1>:Web技术学苑</h1>
</div>
)
}
export default IndexPopup
看下页面结果
我们会发现plasma
天然支持css module
,真正加载插件的时候,会把scss
编译成css
contents
插件中,popup是插件的一个气泡页面,90%
的插件都会有这个气泡,但是我们也会发现一些安装的插件会改变我们浏览器网页的内容,为什么会改变我们浏览网页的内容呢,真正影响的当前页面布局的是contents
如何在网站插入内容?我们知道插件的content.js
是可以获取到当前网页的浏览器内容的,也就是说可以操作当前网页的dom,你可以理解成加载当前网页后,chrome插件给开发者开了一个黑盒,开发者只要用户安装了这个插件,我就可以改变当前页面的dom
scss
代码语言:javascript代码运行次数:0运行复制
.app {
width: 100%;
text-align: center;
padding: 10px 0;
color:red;
}
代码语言:javascript代码运行次数:0运行复制
// contents/
import React, { memo } from "react"
import style from "./scss"
interface Props {}
ct Index: React.FC<Props> = (props) => {
ct {} = props
return <div classame={style["app"]}>hello,欢迎关注Web技术学苑</div>
}
export default memo(Index)
我们发现css没有作用,但是页面内容已经插入的当前网页的html中
我们首页会发现plasma
会创建一个plasmo-csui
的webComponent
,而且插入到html
的根节点上,且样式不生效,那如何使得样式生效呢
导出默认getStyle
// contents/
import type { PlasmoGetStyle } from "plasmo"
import React, { memo } from "react"
// 引入默认scss文件
import styleText from "data-text:./scss"
import style from "./scss"
// 引入默认样式
export ct getStyle: PlasmoGetStyle = () => {
ct style = ("style")
= styleText
return style
}
interface Props {}
ct Index: React.FC<Props> = (props) => {
ct {} = props
return <div classame={style["app"]}>hello,欢迎关注Web技术学苑</div>
}
export default memo(Index)
所以样式就生效了,我们发现在contents
引入的cssmodule
并不会像在popup
一样,而是需要getStyle
这样的接口,动态插入的style
如何在指定域名中生效,现在默认是所有网站都会生效,因此我想指定网址才生效呢,我们需要导出config
即可,并配置matches
指定域名,然后重新运行项目即可
// contents/
export ct config: PlasmoCSConfig = {
matches: ["/*"],
all_frames: true
}
...
如何插入对应页面节点上
我们发现以上的webComponent
是插入在html上的,在通常情况下,有可能实际业务中会遇到插入到页面的某个节点上,所以如何将content
的内容插入到节点上
- 主要是要导出
getOverlayAnchor
,然后绑定页面具体的节点
// contents/
import type {
PlasmoCSConfig,
PlasmoCSUIProps,
PlasmoGetOverlayAnchor
} from "plasmo"
import React from "react"
export ct config: PlasmoCSConfig = {
matches: ["/*"],
all_frames: true
}
export ct getOverlayAnchor: PlasmoGetOverlayAnchor = () =>
document.querySelector(".quickdelete-wrap")
ct ContentForQuick = () => (
<span
style={{
borderRadius: 4,
background: "red",
height: "44px",
display: "flex",
alignItems: "center"
}}>
:Web技术学苑
</span>
)
export default ContentForQuick
以上就是达到我想要的目标了,不过插入的内容依旧是webCompoent
opti
通常来讲这可能是插件内部的设置页面,我们看下如何在popup中或者content中如何打开插件中内部的页面
代码语言:javascript代码运行次数:0运行复制
// opti/
import React, { memo } from "react"
interface Props {}
ct Set: React.FC<Props> = (props) => {
ct {} = props
return <div>我是设置页面</div>
}
export default memo(Set)
我们在popup
弹出窗口中打开
...
function IndexPopup() {
ct [data, setData] = useState("")
ct handleToOptiPage = () => {
chrome.()
}
return (
<div classame={style["app"]}>
<h1>:Web技术学苑</h1>
<div onClick={handleToOptiPage}>go to option page</div>
</div>
)
}
因此opti
页面就在弹框页面中打开了一个新的页面
newtab页面
这个页面会默认覆盖你当前默认打开的tab页面,你只需要在根目录新建newtab/
即可
// newtab/
import React, { memo } from "react"
interface Props {}
ct TabsPge: React.FC<Props> = (props) => {
ct {} = props
return <div>new tabs page</div>
}
export default memo(TabsPge)
当我们每新开一个tab时,默认就会插件的tab
页
tabs
我们插件内部也可以有很多内部的页面,因此,你可以在根目录新建一个tabs
目录,然后新建一个页面
// tabs/
import React, { memo } from "react"
interface Props {}
ct About: React.FC<Props> = (props) => {
ct {} = props
return <div>about page</div>
}
export default memo(About)
我们可以在popup
弹框页面打开一个页面
import { useState } from "react"
import style from "./scss"
function IndexPopup() {
ct [data, setData] = useState("")
ct handleToOptiPage = () => {
chrome.()
}
ct handleToewTabPage = () => {
({
url: `chrome-extension://${chrome.runtime.id}/newtab.html`
})
}
ct handleToAboutPage = () => {
({
url: `chrome-extension://${chrome.runtime.id}/tabs/about.html`
})
}
return (
<div classame={style["app"]}>
<h1>:Web技术学苑</h1>
<div onClick={handleToOptiPage}>go to option page</div>
<div onClick={handleToewTabPage}>go to tab page</div>
<div onClick={handleToAboutPage}>go to about page</div>
</div>
)
}
export default IndexPopup
sidepanel
这是chrome插件的一个新方式,可以在当前窗口打开侧边栏方式打开插件内容
代码语言:javascript代码运行次数:0运行复制
import React, { memo } from "react"
interface Props {}
ct Index: React.FC<Props> = (props) => {
ct {} = props
return <div>this is sidepanel</div>
}
export default memo(Index)
打开sidepanel
,主要在background.js
中打开sidepanel
// background.js
chrome.addListener(() =>
{
chrome.sidePanel.setOpti(
{ path: "sidepanel.html",
enabled: true,
openPanel: true
}).catch((error) => ("Failed to open side panel:", error));
});
总结
- 主要介绍了
plasma
构建插件的几个核心文件,比如background.js
、contents
、opti
、tabs
等插件页面 - 如何在
content.js
中使用cssModule
并插入相对指定节点
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 18 条评论) |
本站网友 珍珠粉的功效与作用 | 19分钟前 发表 |
此时会热更新到插件 | |
本站网友 福州白癜风医院 | 24分钟前 发表 |
PlasmoGetOverlayAnchor = () => document.querySelector(".quickdelete-wrap") ct ContentForQuick = () => ( <span style={{ borderRadius | |
本站网友 吉林省高速公路 | 4分钟前 发表 |
`chrome-extension | |
本站网友 ido婚纱摄影 | 1分钟前 发表 |
默认就会插件的tab页tabs我们插件内部也可以有很多内部的页面 | |
本站网友 王伟车队 | 5分钟前 发表 |
["/*"] | |
本站网友 城阳二手房网 | 1分钟前 发表 |
PlasmoCSConfig = { matches | |
本站网友 宁德霞浦 | 9分钟前 发表 |
contents | |
本站网友 南昌县租房 | 6分钟前 发表 |
tabs等插件页面如何在content.js中使用cssModule并插入相对指定节点本文参与 腾讯云自媒体同步曝光计划 | |
本站网友 西乡租房信息 | 4分钟前 发表 |
`chrome-extension | |
本站网友 高唐教育信息网 | 12分钟前 发表 |
`chrome-extension | |
本站网友 正豪大大鸡排 | 14分钟前 发表 |
setData] = useState("") ct handleToOptiPage = () => { chrome.() } return ( <div classame={style["app"]}> <h1>:Web技术学苑</h1> <div onClick={handleToOptiPage}>go to option page</div> </div> ) } 因此opti页面就在弹框页面中打开了一个新的页面newtab页面这个页面会默认覆盖你当前默认打开的tab页面 | |
本站网友 性爱知识 | 10分钟前 发表 |
4 | |
本站网友 dll之家 | 18分钟前 发表 |
{ memo } from "react" interface Props {} ct About | |
本站网友 李迪 | 10分钟前 发表 |
height | |
本站网友 新生儿腹泻的原因 | 15分钟前 发表 |
{ memo } from "react" interface Props {} ct About | |
本站网友 百大易 | 30分钟前 发表 |
因为原生的插件配置也非常简单 | |
本站网友 长沙友谊商店 | 24分钟前 发表 |
你可以理解成加载当前网页后 |