# Chrome 插件开发
# 各核心单元
插件通常包含以下几个主要组件:
- Popup(弹出窗口):Popup 是 Chrome 插件的用户界面组件,可以在用户点击插件图标时显示在浏览器窗口中。Popup 可以包含各种用户界面元素,例如表单、按钮、链接等,让用户可以与插件进行交互。
- Background(后台):Background 是 Chrome 插件的后台脚本,它在插件安装时启动并持续运行。Background 可以监听浏览器事件并响应这些事件,例如当用户打开新标签页或关闭浏览器时,Background 可以执行相应的操作。在 background 中引入代码需要配置 type: "module" (opens new window) 参考 (opens new window)
- Content script(内容脚本):Content script 是在浏览器页面上执行的脚本,它可以修改网页的内容或与网页进行交互。当用户打开与插件相关的网页时,Content script 会在该网页上执行,并可以修改网页的 DOM 结构或执行 JavaScript 代码。
- Options page(选项页):Options page 是 Chrome 插件的用户设置页面,可以允许用户设置插件的各种选项和配置。
- Devtools page(开发者工具页面):Devtools page 是 Chrome 插件的开发者工具页面,可以帮助开发者进行调试和测试插件。
- 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
# 基础调试
总结几点:
- 调试 popup 页(内容、console) ,在 popup 页(一般点击图标弹出)中,右键检查。
- 调试 background 页, 在扩展管理页中找到该扩展,点击 "背景页",可以打开控制台。
- 调试 content_script,需打开网页自身的控制台。(可使用左上角单独选择显示扩展的 log)
- 如果 popup.js、background.js 等运行报错(error),在扩展管理页中找到该扩展,点击“Errors”按钮,查看具体报错的文件和报错内容。
- 调试 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
}
}
# background
用于注册 service worker,可以使用 "type": "module"。
{
"background": {
"service_worker": "background.js",
"type": "module"
}
}
# permissions
为了使用某些 API,必须声明一些权限。权限分别有四种:
- permissions: 提前声明的一些权限,用户无需主动授权
- optional_permissions: 在插件运行后征求用户的权限
- host_permissions: 遵循条件赋予一个或多个 host 以权限
- optional_host_permissions: 也是运行后征求用户的权限,它们跟 host 有关
{
"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
}
],
...
}