当前位置: 首页 > news >正文

记一次基于manifest v3开发谷歌插件

背景

头疼在国际化功能普遍的前端项目中,如果你在处理或者在某一块功能上新增一些需求的时候,在没有国际化功能的页面中,我们随便复制一些文本,然后在vs code中全局搜索,很快就可以找到所要更改的代码文件在哪里;但是
众所周知,国际化功能中的项目(如果你的国际化文件,写死在项目中,那就可以退场啦),所有的文本都是唯一key的映射产物,而我们的代码中也只是引用这个唯一的key,怎么快速找到这个key,成为了让我们头疼的事情!

目的

为了节省自己日常开发的时间成本,为工作增效(哈哈哈哈,顺带哈)

分析

遇到问题,解决问题!

灵感来源于,谷歌浏览器的翻译插件

可不可以有类似的插件,当我选中某一段文本,他就会检索出来包含这段文本的一些key或者一个key呢,所以解决问题的版本就出来了

  • 好,接下来,我们有了新的问题,怎么开发一个谷歌浏览器的插件?
  • 多得博主之前有相关经验,也不难,大家要接受新的事物进入自己的世界,直接上一个manifestV3开发文档
  • 都准备好,那就开始

技术栈

  • Manifest v3

具备技能,前端三座大山。

配置文件

对于谷歌浏览器的插件开发来说,manifest.json的配置是至关重要的,它是一切的源头,相当于我们日常开发项目中的 index.js 入口文件

manifest.json

{"name": "插件的名称","description": "插件的描述","version": "0.1","permissions": ["contextMenus"],"background": {"service_worker": "service_worker.js"},"content_scripts": [{"js": ["lucky.js"],"matches": ["https://*.bxingupdate.com/*", "https://*.bitvenus.live/*", "https://www.bvox.com/*"],"run_at": "document_end","world": "MAIN"},{"js": ["func.js"],"matches": ["https://*.bxingupdate.com/*", "https://*.bitvenus.live/*", "https://www.bvox.com/*"],"all_frames": true,"run_at": "document_end"}],"manifest_version": 3, // 制定manifest开发版本,最新是3 "host_permissions": ["https://*.bxingupdate.com/*", "https://*.bitvenus.live/*", "https://www.bvox.com/*"],"web_accessible_resources": [],"action": {"default_popup": "popup.html","default_icon": {"16": "icons/icon16.png","48": "icons/icon16.png","128": "icons/icon16.png"}},"icons": { // 配置的插件图标"16": "icons/icon16.png","48": "icons/icon16.png","128": "icons/icon16.png"}
}

这里,以谷歌浏览器插件 redux devtools为例:
在这里插入图片描述
上图,绿色区域就是manifest中的名称,红色部分就是描述;左侧图标,就是icons配置的

那 action 中的 default_popup 就是我们在使用浏览器扩展的时候,
在这里插入图片描述
在这里插入图片描述
类似这里弹出来的这个弹窗,就是popup.html所书写的内容。

以上,其他的一些key的含义,可自行前往官网去查看,且官网上面会有你需要的各种案例。

目录结构

在这里插入图片描述

  1. service_worker.js, 也常被称为background.js,它的作用是 如此

  2. func.js, 它是content-scripts的一种,是当前页面与扩展程序沟通的媒介

  3. lucky.js, 与func.js一样都是content-scripts,不过它的特征在于 它是以script脚本直接运行在当前页面的,

    这样看更清晰一些,以下两张图,看得出他们所处在不同的加载位置
    在这里插入图片描述
    在这里插入图片描述

  4. popup.js, 这个是用于popup.html中的一些脚本书写,

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>插件</title></head><style>....</style><body>....<script src="./popup.js"></script></body>
</html>

接下来,介绍下,以上这个插件中,我们需要用到的通信方法

通信

1. conent-script与background之间的通信

  • content-script怎么给background发送消息呢?

    使用chrome.runtime.sendMessage api,给background发送消息。

  • background又怎么接收消息?
    使用chrome.runtime.onMessage.addListener api,来接收其他人给他发送的消息,包括下面的popup!而且这个api的第一个参数是个函数,该函数中的第三个参数可以用作消息通信,可以发送一些消息给传递给他消息的人,

content-script background { data: '123' } sendResponse({ data: '456' }) background经过自己的处理, 最终 把相应结果给出. content-script background
  • 那么,background又怎么主动发送消息给content-script呢? conent-script又怎么接收的消息?
    使用 chrome.tabs.sendMessage api,主动发消息给content-script,而content-script也是通过chrome.runtime.onMessage.addListenerapi来接收消息
带有两个参数 标签页的id, data
background
content-script

2. popup和background之间的通信

与content-script类似,只不过不能直接与 content script 通信,必须通过 background script 作为中介

总结一下通信关系

(1) popup.html

  • 由 popup.js 负责逻辑处理。
  • 只能在用户点击扩展图标时显示,生命周期短。
  • 不能直接与 content script 通信,必须通过 background script 作为中介。

(2) content script

  • 运行在网页环境,能操作网页 DOM。
  • 不能直接访问 background,但可以通过 chrome.runtime.sendMessage() 与 background 通信。

(3) background script

  • 持续运行,负责处理长期任务、监听事件、管理扩展的状态等。
  • 能与 popup 和 content script 进行通信。
主要通信方式

(1) popup ↔ background

  1. 单次消息传递
// popup.js
chrome.runtime.sendMessage({ action: "getData" }, (response) => {console.log("收到后台返回的数据:", response);
});// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {if (request.action === "getData") {sendResponse({ data: "这是来自后台的数据" });}
});
  1. 长连接(持久连接)
// popup.js
let port = chrome.runtime.connect({ name: "popup" });
port.postMessage({ action: "ping" });port.onMessage.addListener((msg) => {console.log("从后台收到:", msg);
});// background.js
chrome.runtime.onConnect.addListener((port) => {console.log("popup 连接上了:", port.name);port.onMessage.addListener((msg) => {if (msg.action === "ping") {port.postMessage({ reply: "pong" });}});
});

(2) content script ↔ background

  1. 单次消息传递
// content.js
chrome.runtime.sendMessage({ action: "fetchData" }, (response) => {console.log("收到后台返回的数据:", response);
});// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {if (request.action === "fetchData") {sendResponse({ data: "这是后台发送给 content script 的数据" });}
});
  1. 长连接
// content.js
let port = chrome.runtime.connect({ name: "content_script" });
port.postMessage({ action: "hello" });port.onMessage.addListener((msg) => {console.log("收到后台的回复:", msg);
});// background.js
chrome.runtime.onConnect.addListener((port) => {console.log("content script 连接上了:", port.name);port.onMessage.addListener((msg) => {if (msg.action === "hello") {port.postMessage({ reply: "world" });}});
});

(3) popup ↔ background ↔ content script(间接通信)
因为 popup 不能直接访问 content script,所以它们必须通过 background script 作为中介。

// popup.js
chrome.runtime.sendMessage({ action: "sendToContent", message: "你好,content script!" });// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {if (request.action === "sendToContent") {chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {chrome.tabs.sendMessage(tabs[0].id, { message: request.message });});}
});// content.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {console.log("收到 popup 传来的消息:", request.message);
});

写在最后

  1. 如果大家对开发扩展程序感兴趣,博主也贡上自己的扩展程序完整代码给大家 国际化助手
  2. 如果大家看到这里了,就给人美心善的博主点个赞赞支持一下吧,后续大家有任何相关的问题,可以评论区,也可以私信,博主有应必回,在此先感谢大家支持!!!

相关文章:

记一次基于manifest v3开发谷歌插件

背景 头疼在国际化功能普遍的前端项目中&#xff0c;如果你在处理或者在某一块功能上新增一些需求的时候&#xff0c;在没有国际化功能的页面中&#xff0c;我们随便复制一些文本&#xff0c;然后在vs code中全局搜索&#xff0c;很快就可以找到所要更改的代码文件在哪里&…...

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录 说明 效果 项目 代码 下载 参考 C# OpenCvSharp 部署MOWA&#xff1a;多合一图像扭曲模型 说明 算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》 ariv链接 https://arxiv.org/pdf/2404.10716 效果 Stitched Image 翻译成中文意思是&…...

本地部署DeepSeek-R1模型(新手保姆教程)

背景 最近deepseek太火了&#xff0c;无数的媒体都在报道&#xff0c;很多人争相着想本地部署试验一下。本文就简单教学一下&#xff0c;怎么本地部署。 首先大家要知道&#xff0c;使用deepseek有三种方式&#xff1a; 1.网页端或者是手机app直接使用 2.使用代码调用API …...

神经网络常见激活函数 5-PReLU函数

文章目录 PReLU函数导函数函数和导函数图像优缺点pytorch中的PReLU函数tensorflow 中的PReLU函数 PReLU 参数化修正线性单元:Parametric ReLU 函数导函数 PReLU函数 P R e L U { x x > 0 α x x < 0 ( α 是可训练参数 ) \rm PReLU \left\{ \begin{array}{} x \qua…...

2025我的第二次社招,写在春招之季

先说一个好消息&#xff0c;C那些事 4w star了&#xff01; 前面断更了一个月&#xff0c;本篇文章就可以看到原因&#xff0c;哈哈。 大家好&#xff0c;我叫光城&#xff0c;腾讯实习转正做后端开发&#xff0c;后去小公司做数据库内核&#xff0c;经过这几年的成长与积累&am…...

Visual Studio Code中文出现黄色框子的解决办法

Visual Studio Code中文出现黄色框子的解决办法 一、vsCode中文出现黄色框子-如图二、解决办法 一、vsCode中文出现黄色框子-如图 二、解决办法 点击 “文件”点击 “首选项”点击 “设置” 搜索框直接搜索unicode选择“文本编辑器”&#xff0c;往下滑动&#xff0c;找到“Un…...

threejs开源代码之-旋转的彩色立方体

效果&#xff1a;旋转的彩色立方体 效果描述&#xff1a; 一个立方体在场景中旋转。立方体的每个面有不同的颜色。使用自定义着色器为立方体添加动态的光影效果。 代码实现 import * as THREE from three; import { OrbitControls } from three/examples/jsm/controls/OrbitC…...

visual studio 2008的试用版评估期已结束的解决办法

visual studio 2008试用期过了后&#xff0c;再次启动时提示&#xff1a;visual studio的试用版评估期已结束。 需要的工具&#xff1a;补丁文件PatchVS2008.exe 解决办法&#xff1a; 1.在“控制面板”-“添加删除程序”中选择visual studio 2008&#xff0c;点击“更改/卸载”…...

解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Http和Socks的区别?

HTTP 和 SOCKS 的区别 HTTP 和 SOCKS 都是用于网络通信的协议&#xff0c;但它们在工作原理、应用场景和实现方式上有显著的区别。以下是详细的对比和说明。 一、HTTP 协议 1. 定义 HTTP&#xff08;HyperText Transfer Protocol&#xff09;是用于传输超文本数据的应用层协…...

VC播放mp3的方法

1、使用msi库 #include <mmsystem.h> #pragma comment(lib,"winmm.lib") .......//打开文件MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType _T("mpegvideo"); mciOpen.lpstrElementName _T("c://1.mp3"); MCIERROR mciError mci…...

Docker 部署 verdaccio 搭建 npm 私服

一、镜像获取 # 获取 verdaccio 镜像 docker pull verdaccio/verdaccio 二、修改配置文件 cd /wwwroot/opt/docker/verdaccio/conf vim config.yaml config.yaml 配置文件如下&#xff0c;可以根据自己的需要进行修改 # # This is the default configuration file. It all…...

49-拓展(1)

49-拓展&#xff08;1&#xff09; 扩展概述 扩展可以为在当前 package 可见的类型&#xff08;除函数、元组、接口&#xff09;添加新功能。 当不能破坏被扩展类型的封装性&#xff0c;但希望添加额外的功能时&#xff0c;可以使用扩展。 可以添加的功能包括&#xff1a; …...

国产编辑器EverEdit - 在文件中查找和替换

1 在文件中查找和替换 1.1 应用场景 某些场景&#xff0c;用户需要在所有工程文件中进行查找和替换关键词&#xff0c;比如&#xff1a;查找工程中哪些文件使用了某个常量。 1.2 使用方法 选择主菜单查找 -> 在文件中查找和替换&#xff0c;或使用快捷键Ctrl Shift F&a…...

安全行业大模型SecLLM技术白皮书

在ChatGPT 呈现全球现象级热度时&#xff0c;通用大语言模型&#xff08;Large Language Model, LLM&#xff09;技术成为了推动创新和变革的关键驱动力。但由于安全行业的特殊性和复杂性&#xff0c;LLM 并不能满足其应用需求。安全行业大模型(Security Large Language Model,…...

基础入门-HTTP数据包红蓝队研判自定义构造请求方法请求头修改状态码判断

知识点&#xff1a; 1、请求头&返回包-方法&头修改&状态码等 2、数据包分析-红队攻击工具&蓝队流量研判 3、数据包构造-Reqable自定义添加修改请求 一、演示案例-请求头&返回包-方法&头修改&状态码等 数据包 客户端请求Request 请求方法 …...

2025年日祭

本文将同步发表于洛谷&#xff08;暂无法访问&#xff09;、CSDN 与 Github 个人博客&#xff08;暂未发布&#xff09; 本蒟自2025.2.8开始半停课。 任务计划&#xff08;站外题与专题&#xff09; 数了一下&#xff0c;通过人数比较高的题&#xff0c;也就是我准备补的题&a…...

git命令行删除远程分支、删除远程提交日志

目录 1、从本地通过命令行删除远程git分支2、删除已 commit 并 push 的记录 1、从本地通过命令行删除远程git分支 git push origin --delete feature/feature_xxx 删除远程分支 feature/feature_xxx 2、删除已 commit 并 push 的记录 git reset --hard 7b5d01xxxxxxxxxx 恢复到…...

centOS8安装MySQL8设置开机自动启动失败

提供一个终极解决方案虽然systemctl 更符合管理预期但是不能用 使用一下命令 修改配置文件、修改mysql.service全是问题 systemctl start mysqld systemctl enable mysqld systemctl daemon-reload完全不生效各种报错 提示配置文件内容有问题 Main process exited, codeexite…...

对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xff0…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...