Chrome Extension 开发指南
在本教程中,我们将深入了解并掌握基于最新Manifest V3(MV3)标准的Chrome插件开发。通过逐步探索和丰富的代码示例,全面理解插件开发的每个环节。
基本概念
通常,一个 Chrome 插件是一个完整的应用项目,它包含了一系列主要文件。其本身的开发语言为 javascript 。因此对于前端开发工程师来说,只要熟悉了整个结构以及 API,开发一个 Chrome 插件就没有那么困难了。
先来认识一下插件中的几个主要文件
manifest.json (必须)
manifest.json 文件定义了插件的基本信息和行为。目前 manifest 的版本已经升级为 v3,并且将在 2024年6月禁止再使用 v2版本。
以下是一些关键字段的介绍和示例用法 (read more):
字段名
示例
说明
"name": "My New Extension", "version": "1.0.0",
name
字段定义了插件的名称,
version
字段定义了插件的版本号。
"action": {
"default_popup": "popup.html", "default_title": "My New Extension"
},
action
字段定义了插件的用户界面,通常是浏览器工具栏上的一个按钮。
"background": {"service_worker": "service-worker.js"}
background
字段定义了一个后台脚本,它会在插件安装后一直运行。
(在 v2 版本中,这个字段为 background.js,v3已经变更为 service_worker)
Extension Service Worker:service-worker.js (backgournd.js)
Service Worker 是扩展程序的核心事件处理脚本。Service Worker 在需要时加载,并在其进入休眠状态时取消加载。只要 Service Worker 在加载后还会主动接收事件,它就会运行。
因此在 service-worker.js 中,我们通常会定义一些监听事件。service-worker 作为一个chrome 后台脚本,它可以使用 Chrome 的一些 API, 但无法无法访问 DOM
Service worker 有几个生命周期 (read more):
生命周期
触发事件
说明
安装
ServiceWorkerRegistration.install
addEventListener("install", (event) => {});
当用户从 Chrome 应用商店安装或更新 Service Worker,或者用户使用 chrome://extensions
页面加载或更新已解压的扩展程序时。
安装完成
chrome.runtime.onInstalled
当该扩展程序(而不是 Service Worker)首次安装时、该扩展程序更新到新版本以及 Chrome 更新到新版本时,都会触发该事件。使用此事件来设置状态或一次性初始化。
激活
ServiceWorkerRegistration.active
addEventListener("activate", (event) => {});
在上一步安装完毕之后,会触发此项
启动
chrome.runtime.onStartup
当用户个人资料启动时,会触发 chrome.runtime.onStartup
事件,但不会调用任何 Service Worker 事件。
Service Worker 中可能用到的一些事件 (read more):
Content Scripts: content-script.js
Content Scripts 可以读取和更改网页内容,但其本身被限制在沙盒中,无法更改和注入页面的 js。
我们可以通过 content script 来插入一些和页面元素融合的功能。也可以用于调整页面的样式布局,比如移除侧边栏的广告。
另外如果想让 content script 和其他脚本通信,可以使用 chrome.runtime.sendMessage 和 chrome.runtime.onMessage:
Popup Page 和 Option Page
当用户与Chrome插件进行交互时,Popup Page是他们点击插件图标后首先看到的页面。Popup Page应该简洁直观,同时提供用户所需的核心功能或信息。
Option Page是插件的设置中心,允许用户根据个人偏好调整插件的行为。在这里,用户可以修改插件的配置,如通知设置、外观偏好或功能开关。
为了增强用户体验,插件可以在Popup 和 Option 中利用chrome.storage
API来存储和读取用户的个性化设置。无需使用复杂的服务器端存储解决方案。
注意,Popup 和 Option 本身并不是必须的。这取决于插件本身是否需要。
开发实践
在本节中,我们将通过一个具体的开发案例来深入Chrome插件的开发实践。目标是创建一个插件,该插件能够读取页面上发起的fetch请求,并允许用户修改请求URL中的subEnv
查询参数。
功能实现
插件的核心功能将围绕以下两个关键点展开:
读取fetch请求:监测页面上的fetch请求,寻找包含
subEnv
参数的URL。用户交互:提供用户界面,使用户能够修改
subEnv
的值。
技术对比
在实现上述功能时,我们有两种主要的技术途径:
劫持 fetch 在插件开发中可以有两种形式,
使用
declarativeNetRequest
API 优势:作为Chrome内核提供的API,declarativeNetRequest
能够确保拦截所有fetch请求。 局限:相比于直接注入JS,这种方法在灵活性上有所欠缺,并且存在一定的使用限制。注入JS以Hook fetch方法 优势:提供了更高的灵活性,允许开发者自由地修改请求(Request)和响应(Response)。
局限:注入脚本的时机可能会影响其对所有fetch请求的覆盖能力。
权衡与选择
开发者在选择实现方式时,需要根据项目的具体需求进行权衡。如果需要确保捕获所有请求,且对修改的灵活性要求不高,那么使用declarativeNetRequest
可能是更好的选择。反之,如果项目需要高度定制化的请求处理逻辑,那么注入JS可能是更合适的方案。
manifest.json
假设我们以第一种方式来实现。首先需要修改 manifest 中的 permisssions
declarativeNetRequest 用于获取页面上的请求,并且需要声明对应的 rule 规则。(read more)
在 manifest 中,我们可以指定 rule_resources 为空,之后在插件让用户手动的选择需要被修改的 fetch URL,这样可以更灵活劫持需要处理的路径。
同时也需要 storage 权限来保存用户选择的 URL。
service-worker.js
在 service-worker.js 中,可以通过监听 storage 变化来更新 rules
declarativeNetRequest API 接受的规则可以通过正则表达式来命中需要的 URL。(read more) 但由于限制,所支持的正则表达式并非完全态,贪婪方法并不适用。(RE2 Syntax)
declarativeNetRequest API 通过 updateDynamicRules 方法来动态修改 rules。(read more)
Popup Page
为了提供一个便捷的用户交互方式,我们将创建一个Popup Page,允许用户输入特定的URL和调整所需的subEnv
参数。此外,我们将利用Chrome的存储机制来保存用户的输入,以便在用户下次访问Popup Page时能够恢复之前的设置。
存储机制
数据保存:当用户输入URL和
subEnv
参数后,我们将使用chrome.storage
API来保存这些数据。这确保了用户设置的持久化,即使在浏览器关闭后也能保持。数据提取:在Popup Page加载时,我们将从
chrome.storage
中提取之前保存的URL和subEnv
值,并将其自动填充到相应的输入框中,提升用户体验。
关键代码实现
以下是实现上述存储和提取功能的JavaScript代码示例:
这里设计了2个方法用于保存和读取 chrome.storage。同时每当点击确认按钮 saveSubEvnItemList 之后,就会触发 service-worker.js 中的 chrome.storage.onChanged
至此,一个用于修改页面请求中,subEvn query 的Chrome插件现已开发完成。
推荐开发工具:NextExtension-Starter
为了简化开发流程并提高开发效率,这里推荐使用 NextExtension-Starter。一个基于Next.js框架的Chrome插件开发模板。
使用NextExtension-Starter的好处 :
快速开发:利用React的组件化特性,构建可复用的UI组件,实现的Popup和Option页面。
集成打包:该模板集成了打包工具,可以一步生成插件所需的Zip文件,简化部署流程。
自定义图标:轻松生成和集成插件icon,增强插件的视觉效果和用户识别度。
发布插件
Last updated