浏览器插件入门

6 min

浏览器插件

开源之夏有点被导师 pua 到了 所以准备换了个项目 还是一个社区的项目

这个项目主要是对浏览器插件优化

浏览器插件基本项目结构

先看看基本结构吧 基本上都会有一个 mainfest.jsonpackage.json 基本上我感觉是一样的作用

{
  // 插件名称
  "name": "Hello Extensions",
  // 插件的描述
  "description": "Base Level Extension",
  // 插件的版本
  "version": "1.0",
  // 配置插件程序的版本号,主流版本是 2,最新是 3
  "manifest_version": 2
}

我们经常会点击右上角插件图标时弹出一个小窗口的页面,焦点离开时就关闭了,一般做一些临时性的交互操作;在配置文件中新增 browser_action 字段,配置 popup 弹框:

{
  "name": "Hello Extensions",
  "description": "Base Level Extension",
  "version": "1.0",
  "manifest_version": 2,
  // 新增 popup 弹框
  "browser_action": {
    "default_popup": "popup.html",
    "default_icon": "popup.png"
  }
}

然后创建我们的弹框页面 panel.html:

html 复制代码<html>
  <body>
    <h1>Hello Extensions</h1>
  </body>
</html>

点击图标后,插件显示 panel.html

后台 background

们也发现了,popup 页面只能做临时性的交互操作,用完就关了,不能存储信息或者和其他标签页进行交互等等;这时就需要用到 background(后台),它是一个常驻的页面,它的生命周期是插件中所有类型页面中最长的;它随着浏览器的打开而打开,随着浏览器的关闭而关闭,所以通常把需要一直运行的、启动就运行的、全局的代码放在 background 里面。

mainfest.json 添加路径

  "background": {
    "script": [
      "background.js"
    ],
    "persistent": true
  },

这样基本上结构就差不多了

实现查看组件属性和查看状态管理状态的功能

这个就是开源之夏的第一个任务喽

感觉就是 React 的那个插件的功能

我去看了看 react 的源码

感觉操作就是需要先获取到组件的状态 然后看状态管理器的状态

然后监听后台管理器的消息 然后在显示的 html 中加上显示的部分

在 content-Script 中新增⼀个 stateManager.ts ⽂件 以便捕获和发送组件状态和状态管理器信息

哦这里补充一下 一般会有一个 content-script 文件夹

官方定义是

content-scripts(内容脚本)是在网页上下文中运行的文件。通过使用标准的文档对象模型 (DOM),它能够读取浏览器访问的网页的详细信息,对其进行更改,并将信息传递给其父级插件。内容脚本相对于 background 还是有一些访问 API 上的限制,它可以直接访问以下 chrome 的 API:

  • i18n
  • storage
  • runtime:
    • connect
    • getManifest
    • getURL
    • id
    • onConnect
    • onMessage
    • sendMessage

我的理解就是监听监听监听 传信号信号信号 :speech_balloon:

基本上用的都是 chrome 的 api

let mockComponentState = { exampleComponent: { state: 'active' } }
let mockStateManagerInfo = { exampleStateManager: { state: 'initialized' } }
chrome.runtime.sendMessage({ type: 'updateComponentState', state:
mockComponentState })
chrome.runtime.sendMessage({ type: 'updateStateManagerInfo', stateManager:
mockStateManagerInfo });
// 钩子到框架特定的 API 获取真实的组件状态和状态管理器信息
(function () {
  const originalSetState = YourFramework.Component.prototype.setState
  YourFramework.Component.prototype.setState = function (newState, callback) {
    chrome.runtime.sendMessage({ type: 'updateComponentState', state:
this.state })
    return originalSetState.apply(this, arguments)
  }
})();
(function () {
  const originalDispatch = YourFramework.store.dispatch
  YourFramework.store.dispatch = function (action) {
    chrome.runtime.sendMessage({ type: 'updateStateManagerInfo', stateManager:
YourFramework.store.getState() })
    return originalDispatch.apply(this, arguments)
  }
})()

chrome.runtime.sendMessage 是 Chrome 扩展程序中的一种方法,用于从扩展程序中的一个部分向另一个部分发送消息,例如从内容脚本向后台脚本发送消息。

用法

chrome.runtime.sendMessage(extensionId, message, options, responseCallback)
  • extensionId(可选):字符串类型。指定接收消息的扩展程序的 ID。如果消息是发送到本扩展程序,可以省略此参数。
  • message:任意类型。发送的消息内容,可以是任何 JSON 序列化类型的数据。
  • options(可选):对象类型。包含额外的选项,比如 includeTlsChannelId(布尔值)。
  • responseCallback(可选):函数类型。一个函数,当收到响应消息时调用,传入一个参数 response,该参数是响应的消息。

然后在 content-Script 的 index.ts 中引入使用

 //监听来自 background 的消息
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
   //该方法可以监听页面 contentScript 和插件的消息
  // 没有 tab 信息说明消息来自插件
  if (!sender.tab  checkMessage(message, DevToolBackground)) {
    changeSource(message, DevToolContentScript);
    // 传递消息给页面
    window.postMessage(message, '*');
  }
  sendResponse({ status: 'ok' });
 });

他自己写的源码中有个什么 window 对象不能直接通过 contentScript 代码修改,只能通过添加 js 代码往页面 window 注入 hook 这玩意还没看懂 等要是选上慢慢来吧