当前位置: 首页 > 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. 如果大家看到这里了,就给人美心善的博主点个赞赞支持一下吧,后续大家有任何相关的问题,可以评论区,也可以私信,博主有应必回,在此先感谢大家支持!!!
http://www.lryc.cn/news/534014.html

相关文章:

  • C# OpenCvSharp 部署MOWA:多合一图像扭曲模型
  • 本地部署DeepSeek-R1模型(新手保姆教程)
  • 神经网络常见激活函数 5-PReLU函数
  • 2025我的第二次社招,写在春招之季
  • Visual Studio Code中文出现黄色框子的解决办法
  • threejs开源代码之-旋转的彩色立方体
  • visual studio 2008的试用版评估期已结束的解决办法
  • 解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用
  • Http和Socks的区别?
  • VC播放mp3的方法
  • Docker 部署 verdaccio 搭建 npm 私服
  • 49-拓展(1)
  • 国产编辑器EverEdit - 在文件中查找和替换
  • 安全行业大模型SecLLM技术白皮书
  • 基础入门-HTTP数据包红蓝队研判自定义构造请求方法请求头修改状态码判断
  • 2025年日祭
  • git命令行删除远程分支、删除远程提交日志
  • centOS8安装MySQL8设置开机自动启动失败
  • 对接DeepSeek
  • SpringSecurity高级用法
  • NLP_[2]-认识文本预处理
  • 字符设备驱动开发
  • c语言:取绝对值
  • DeepSeek从入门到精通教程PDF清华大学出版
  • HTML之CSS定位、浮动、盒子模型
  • LQB(1)-python-各种基础排序
  • 解锁国内主流前端与后端框架
  • 使用OBS推流,srs服务器播放
  • 【鸿蒙HarmonyOS Next实战开发】多媒体视频播放-ijkplayer
  • GRU 和 LSTM 公式推导与矩阵变换过程图解