当前位置: 首页 > 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…...

springboot+vue基于web的在线学习资源推荐的设计与实现

目录功能模块分析推荐系统功能交互功能设计后台管理功能技术实现要点项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作功能模块分析 用户管理模块 用户注册与登录&#xff1a;支持邮箱/手机号注册&#xff0c;提供密码找回功能…...

拯救你的Flash回忆:CefFlashBrowser让经典内容重获新生

拯救你的Flash回忆&#xff1a;CefFlashBrowser让经典内容重获新生 【免费下载链接】CefFlashBrowser Flash浏览器 / Flash Browser 项目地址: https://gitcode.com/gh_mirrors/ce/CefFlashBrowser 你是否曾经因为现代浏览器不再支持Flash而无法重温那些经典的教学课件&…...

太原烘焙培训排名

在太原选择烘焙培训机构时&#xff0c;许多朋友会关注不同机构的教学质量与特色。以下整理了一些选择时可以考虑的方面&#xff0c;供您参考。教学方式与内容部分机构采用以实操为主的教学模式&#xff0c;例如山西旭梦圆食品有限公司的课程安排中&#xff0c;实践操作占较大比…...

Pylint魔法方法验证:10个技巧确保特殊方法符合Python规范的终极指南

Pylint魔法方法验证&#xff1a;10个技巧确保特殊方法符合Python规范的终极指南 【免费下载链接】pylint Its not just a linter that annoys you! 项目地址: https://gitcode.com/gh_mirrors/pyl/pylint Python开发者们&#xff0c;你是否曾为魔法方法&#xff08;dund…...

第二章 从ROM到app_main:深入剖析ESP32 FreeRTOS双核启动的代码级实现

1. ESP32双核启动全景图&#xff1a;从硬件复位到RTOS就绪 第一次拿到ESP32开发板时&#xff0c;你可能和我一样好奇&#xff1a;按下复位键后&#xff0c;这个小小的芯片内部究竟发生了什么&#xff1f;为什么我们的app_main函数能自动运行&#xff1f;今天我们就用"显微…...

单片机抢答器项目避坑指南:从按键抖动处理到中断优先级设置

单片机抢答器项目避坑指南&#xff1a;从按键抖动处理到中断优先级设置 在嵌入式系统开发中&#xff0c;抢答器是一个经典的教学项目&#xff0c;但看似简单的功能背后却隐藏着许多技术细节。很多开发者在实现基本功能后&#xff0c;往往会忽略一些关键优化点&#xff0c;导致系…...

【Java边缘运行时部署终极指南】:20年专家亲授5大避坑法则与3步极速上线实战

第一章&#xff1a;Java边缘运行时部署全景认知与演进脉络Java在边缘计算场景中的运行时部署正经历从传统云中心化架构向轻量、自治、低延迟方向的深刻演进。早期Java应用依赖完整JDK和重量级容器&#xff08;如Tomcat&#xff09;部署于虚拟机或Kubernetes集群&#xff0c;难以…...

IIC驱动进阶:实现非连续寄存器批量配置的模块化设计

1. IIC总线驱动开发的痛点与挑战 第一次接触摄像头模块配置时&#xff0c;我被密密麻麻的寄存器列表吓到了。OV5640摄像头需要配置上百个寄存器&#xff0c;地址从0x3100到0x5FFF不等&#xff0c;每个寄存器都有特定功能。更麻烦的是&#xff0c;这些寄存器地址完全不连续&…...

如何快速掌握单细胞分析:CELLxGENE新手必看的3个实用技巧

如何快速掌握单细胞分析&#xff1a;CELLxGENE新手必看的3个实用技巧 【免费下载链接】cellxgene An interactive explorer for single-cell transcriptomics data 项目地址: https://gitcode.com/gh_mirrors/ce/cellxgene 你是否曾经面对海量的单细胞转录组数据感到无从…...

Treap(树堆)实战:从原理到代码实现与性能对比

1. 什么是Treap&#xff1a;当二叉搜索树遇上堆 第一次听说Treap这个数据结构时&#xff0c;我正被红黑树的旋转操作折磨得焦头烂额。直到某天在算法竞赛讨论区看到有人用20行代码实现了一个"魔法平衡树"&#xff0c;才真正打开了新世界的大门。Treap这个名字本身就揭…...