# Chrome 插件开发

文档地址 (opens new window)

# 各核心单元

插件通常包含以下几个主要组件:

  1. Popup(弹出窗口):Popup 是 Chrome 插件的用户界面组件,可以在用户点击插件图标时显示在浏览器窗口中。Popup 可以包含各种用户界面元素,例如表单、按钮、链接等,让用户可以与插件进行交互。
  2. Background(后台):Background 是 Chrome 插件的后台脚本,它在插件安装时启动并持续运行。Background 可以监听浏览器事件并响应这些事件,例如当用户打开新标签页或关闭浏览器时,Background 可以执行相应的操作。在 background 中引入代码需要配置 type: "module" (opens new window) 参考 (opens new window)
  3. Content script(内容脚本):Content script 是在浏览器页面上执行的脚本,它可以修改网页的内容或与网页进行交互。当用户打开与插件相关的网页时,Content script 会在该网页上执行,并可以修改网页的 DOM 结构或执行 JavaScript 代码。
  4. Options page(选项页):Options page 是 Chrome 插件的用户设置页面,可以允许用户设置插件的各种选项和配置。
  5. Devtools page(开发者工具页面):Devtools page 是 Chrome 插件的开发者工具页面,可以帮助开发者进行调试和测试插件。
  6. Server worker(服务工作者):Server worker 是 Chrome 插件的可选组件,可以在后台运行。Server worker 可以执行一些耗时的操作,例如网络请求或文件下载。使用 Server worker 可以在后台执行这些操作,而不会影响到浏览器的性能。

# 通信方式

  • V2 相对复杂一些
  • V3 一般用 message 通信

# 项目结构

基本项目结构如下,注意 manifest 一定要放根目录下。

- my-extension/
  - manifest.json
  - background.js
  - scripts/
      - content.js
      - react.production.min.js
  - popup/
      - popup.html
      - popup.js
      - popup.css
  - images/
      - icon-16.png
      - icon-32.png
      - icon-48.png
      - icon-128.png

# 基础调试

参考文档 (opens new window)

总结几点:

  1. 调试 popup 页(内容、console) ,在 popup 页(一般点击图标弹出)中,右键检查。
  2. 调试 background 页, 在扩展管理页中找到该扩展,点击 "背景页",可以打开控制台。
  3. 调试 content_script,需打开网页自身的控制台。(可使用左上角单独选择显示扩展的 log)
  4. 如果 popup.js、background.js 等运行报错(error),在扩展管理页中找到该扩展,点击“Errors”按钮,查看具体报错的文件和报错内容。
  5. 调试 popup 页时,如果打了有断点时,因为无法及时调出控制台,可能来不及捕获进去;此时需要在 devtool 中使用重启命令location.reload(true)

# manifest.json

插件的注册表,详情查阅 (opens new window)

# manifest_version

manifest 文件版本,每个版本的 API 不一样。


# content_scripts

配置注入哪些 content script,还可以设置匹配规则,按条件注入。 注意:它单独运行于一个独立的环境,跟页面是分割的,可以监听页面事件,但不能改写页面的对象。 详情查阅 (opens new window)

{
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "css": ["my-styles.css"],
      "js": ["content-script.js"]
    }
  ]
}

# action

控制扩展的图标行为、样式等,可实现 显示 popup 页、点击后在某个 tab 页 alert 等交互需求;也可以配合 chrome.action.disable() 和 chrome.declarativeContent.ShowAction() 等 API 完成隐式交互。

{
  "action": {
    "default_icon": {
      // optional
      "16": "images/icon16.png", // optional
      "24": "images/icon24.png", // optional
      "32": "images/icon32.png" // optional
    },
    "default_title": "Click Me", // optional, shown in tooltip
    "default_popup": "popup.html" // optional
  }
}

查阅 (opens new window)

# background

用于注册 service worker,可以使用 "type": "module"。

{
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

# permissions

为了使用某些 API,必须声明一些权限。权限分别有四种:

  • permissions: 提前声明的一些权限,用户无需主动授权
  • optional_permissions: 在插件运行后征求用户的权限
  • host_permissions: 遵循条件赋予一个或多个 host 以权限
  • optional_host_permissions: 也是运行后征求用户的权限,它们跟 host 有关

查阅 (opens new window)

{
  "permissions": ["tabs", "bookmarks", "unlimitedStorage"],
  "optional_permissions": ["unlimitedStorage"],
  "host_permissions": ["https://www.blogger.com/", "https://*.google.com/"],
  "optional_host_permissions": ["https://*/*", "http://*/*"]
}

# commands

使用命令 API 添加触发扩展中操作的键盘快捷键,例如,打开浏览器操作或向扩展发送命令的操作。

{
  "name": "My extension",
  ...
  "commands": {
    "run-foo": {
      "suggested_key": {
        "default": "Ctrl+Shift+Y",
        "mac": "Command+Shift+Y"
      },
      "description": "Run \"foo\" on the current page."
    },
    "_execute_action": {
      "suggested_key": {
        "windows": "Ctrl+Shift+Y",
        "mac": "Command+Shift+Y",
        "chromeos": "Ctrl+Shift+U",
        "linux": "Ctrl+Shift+J"
      }
    }
  },
  ...
}

配合 onCommand 使用

chrome.commands.onCommand.addListener((command) => {
  console.log(`Command: ${command}`);
});

# options_page

为插件设置一个页面,一般用于配置插件行为。通过 右键 action 图标 -> 选项 进入该配置页。

{
  "name": "My extension",
  ...
  "options_page": "options.html",
  ...
}

# web_accessible_resources

插件需要在这里声明需要在网页中加载的图像或其他资源,从 V2 开始需要声明,否则无法访问。 (例如,content script 要访问插件里的某张图片)

{
  ...
  "web_accessible_resources": [
    {
      "resources": [ "test1.png", "test2.png" ],
      "matches": [ "https://web-accessible-resources-1.glitch.me/*" ]// 匹配所有 <all_urls>, 详见 https://developer.chrome.com/docs/extensions/mv3/match_patterns/
    }, {
      "resources": [ "test3.png", "test4.png" ],
      "matches": [ "https://web-accessible-resources-2.glitch.me/*" ],
      "use_dynamic_url": true
    }
  ],
  ...
}