您现在的位置是:首页 > 编程 > 

插件构建之plasma

2025-07-18 05:12:24
插件构建之plasma 过去一年,开发了两款插件并上架谷歌商店,在最初技术调研时原本想使用plasma,考虑插件包的体积与其他未知原因,最终我还是选择了webpack5搭建了一个基础的chrome插件,具体可参考之前写的一篇文章#放弃plasmo,webpack5搭建了一个chrome基础插件,因为原生的插件配置也非常简单。通常的插件api使用也踩了不少坑,但从新回顾,发现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文件夹

代码语言:javascript代码运行次数:0运行复制
 
// popup/
import { useState } from "react"

function IndexPopup() {
  ct [data, setData] = useState("")

  return (
    <div>
      <h1>:Web技术学苑</h1>
    </div>
  )
}

export default IndexPopup

在初始化后的文件夹,我们可以使用src来组织我们的插件,具体可以参考src,从扩展页面中可以发现,在插件中的一些页面可以组织成以下

代码语言:javascript代码运行次数:0运行复制
 
# contents/
# popup/
# opti/
# newtab/
# sidepanel/
# devtools/

我们发现popup页面的样式如何控制

css module

我们看下popup页面,我们引入的scss对应的scss

代码语言:javascript代码运行次数:0运行复制
 
.app {
  width: 60px;
  height: 600px;
}

popup

代码语言:javascript代码运行次数:0运行复制
 
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-csuiwebComponent,而且插入到html的根节点上,且样式不生效,那如何使得样式生效呢

导出默认getStyle

代码语言:javascript代码运行次数:0运行复制
 
// 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指定域名,然后重新运行项目即可

代码语言:javascript代码运行次数:0运行复制
 
// contents/
export ct config: PlasmoCSConfig = {
  matches: ["/*"],
  all_frames: true
}
...

如何插入对应页面节点上

我们发现以上的webComponent是插入在html上的,在通常情况下,有可能实际业务中会遇到插入到页面的某个节点上,所以如何将content的内容插入到节点上

  • 主要是要导出getOverlayAnchor,然后绑定页面具体的节点
代码语言:javascript代码运行次数:0运行复制
 
// 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弹出窗口中打开

代码语言:javascript代码运行次数:0运行复制
 
...
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/即可

代码语言:javascript代码运行次数:0运行复制
 
// 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目录,然后新建一个页面

代码语言:javascript代码运行次数:0运行复制
 
// 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弹框页面打开一个页面

代码语言:javascript代码运行次数:0运行复制
 
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

代码语言:javascript代码运行次数:0运行复制
 
// background.js
chrome.addListener(() => 
{ 
   chrome.sidePanel.setOpti(
   {   path: "sidepanel.html",
       enabled: true,
       openPanel: true
    }).catch((error) => ("Failed to open side panel:", error)); 
 });

总结

  • 主要介绍了plasma构建插件的几个核心文件,比如background.jscontentsoptitabs等插件页面
  • 如何在content.js中使用cssModule并插入相对指定节点
本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2024-12-0,如有侵权请联系 cloudcommunity@tencent 删除import插件开发者浏览器

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1119353.html

相关标签:无
上传时间: 2025-07-17 23:21:15
留言与评论(共有 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分钟前 发表
你可以理解成加载当前网页后