开发环境搭建
Chrome Extension开发的本质其实还是HTML、CSS和JavaScript,所以习惯用什么写JS就可以用什么来写Extension,我比较习惯用VScode,也不需要做什么额外的配置了
调试
Chrome Extension项目中只要有manifest.json文件就可以开始调试了
-
地址栏输入chrome://extensions/
-
Chrome浏览器右上角菜单→扩展程序
勾选右上角开发者模式,打开之后就可以以加载本地插件了,不然只能加载crx文件,插件文件修改之后,需要在插件页面对应的插件上点击刷新,或者Ctrl+R刷新
Chrome Extension 核心介绍
manifest.json文件
这个核心是一个文件,这个文件是Chrome Extension项目中最重要的一个文件,相当于Extension的身份证,他的作用主要有三个:
- 扩展基本信息:定义名称、版本、图标等元信息
- 权限控制中心:声明所需的 API 权限和域名权限
- 组件入口注册:定义 Service Worker、弹出页、内容脚本等入口
基础配置模板
{
"manifest_version": 3,
"name": "AI Assistant",
"version": "1.0.0",
"description": "AI-powered browser assistant",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
权限声明
{
// 基础权限(安装时申请)
"permissions": [
"storage", // 数据存储
"scripting", // 动态脚本执行
"contextMenus", // 右键菜单
"activeTab" // 访问当前活动标签页
],
// 可选权限(运行时动态请求)
"optional_permissions": [
"downloads",
"geolocation"
]
}
组件入口配置
{
// 定义Extension的图标
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/icon16.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
}
},
"background": {
"service_worker": "background.js",
"type": "module" // 支持 ES Modules
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
官方网站配置文档:developer.chrome.com/docs/extens…
Service Worker
Service Worker本质是一个后台脚本文件,主要负责:
- 处理一些离线任务(比如定时提醒)
- 保存数据(比如记住用户的设置)
- 监听浏览器事件(比如插件安装/更新)
更像一个管家,平时你看不见他,但他会帮你做一些事情:
- 每天7点准时提醒你喝水(定时任务)
- 记住你所有朋友的生日(数据存储)
- 新家具到了自动签收(处理事件)
Service Worker的配置也是写在了manifest.json文件中,在上面的配置中,service_worker字段配置的background.js文件如下
// 监听扩展安装事件
chrome.runtime.onInstalled.addListener(() => {
console.log('Quick Notes 扩展已安装');
});
// 监听来自内容脚本的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'getNotes') {
chrome.storage.local.get(['notes'], (result) => {
sendResponse({ notes: result.notes || [] });
});
return true; // 保持消息通道开放
}
});
Content Scripts
Content Scripts更像是装修工人,主要是一些js和css文件,用来修改页面内容,监听网页事件等等,就像装修,你雇了一队工人(Content Scripts),他们按照你给的图纸(manifest.json)里的配置,专门给指定的房子(Extension)刷墙(改样式)、装新家具(加功能)
除此之外,Content Scripts还有一个很重要的桥梁的作用,他是连接页面和Service Worker的通信桥梁
PS:Content Scripts和Service Worker都能监听事件,有什么区别
- 运行环境:Content Script主要运行在网页上下文中,可以访问DOM,而Service Worker作为后台脚本,处理后台任务,是运行在独立的后台环境中的
- 生命周期:Content Scripts的生命周期与网页相关,随页面关闭而终止,而Service Worker是独立的后台进程,独立存活,可被浏览器唤醒
- 监听对象:Content Scripts主要监听网页内的具体操作,Service Worker监听的是浏览器级别的全局事件
如果要打个比方的话,
-
Content Scripts ≈ 网页内的间谍
- 专注:当前网页内的具体操作
- 优势:直接操作 DOM、快速响应页面事件
-
Service Worker ≈ 后台指挥官
- 专注:浏览器全局状态、跨页面协调
- 优势:持久化运行、处理复杂后台任务
表现就是二者对于一些API调用存在一些权限上的差异
实际开发中,通常需要两者配合:Content Scripts 负责【感知页面】,Service Worker 负责【统筹全局】。
Content Scripts的配置写在了manifest.json文件中,下面举一个具体一些的例子,在上面的配置中content_scripts配置的content.js文件如下
// 监听来自弹出窗口的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'getPageInfo') {
const pageInfo = {
title: document.title,
url: window.location.href,
timestamp: Date.now()
};
sendResponse(pageInfo);
}
});
// 添加右键菜单功能
document.addEventListener('contextmenu', (event) => {
const selectedText = window.getSelection().toString().trim();
if (selectedText) {
chrome.runtime.sendMessage({
action: 'saveSelection',
text: selectedText,
url: window.location.href
});
}
});
Popup:用户交互门户
首先我实现了一个很简单的插件页面,这个插件的页面是下面这样的
这个插件的popup.html文件是下面这样的
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Quick Notes</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Quick Notes</h1>
<div class="notes-container">
<textarea id="noteInput" placeholder="在这里输入您的笔记..."></textarea>
<button id="saveNote">保存笔记</button>
</div>
<div class="notes-list" id="notesList">
<!-- 笔记列表将通过 JavaScript 动态生成 -->
</div>
</div>
<script src="popup.js"></script>
</body>
</html>
如果这个页面变成下面这样
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Quick Notes</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Hello World</h1>
</div>
</body>
</html>
就是经典的“Hello World”啦!!
可以看到,其实插件的HTML文件和正常网页的HTML文件没有什么太大的区别,也可以导入css和js文件,结构也一致,但是这个HTML是自适应大小的,不会像正常网页那样固定浏览器宽高,当然,配置同样是写在manifest.json文件中,action.default_popup字段,名称不一定是popup.html,你喜欢就好,就像前端框架文件中主文件index.html一个道理
最后给大家放一个简单但是相对完整的插件的项目结构
quick-notes-extension/
├── manifest.json # 扩展配置文件
├── popup.html # 弹出窗口界面
├── popup.js # 弹出窗口逻辑
├── background.js # 后台服务
├── content.js # 内容脚本
├── styles.css # 样式文件
└── images/ # 图标资源
了解到这里,其实你已经可以开发一个非常简单的插件啦,至于具体的API调用和一些复杂的功能实现,我后面会陆陆续续给大家介绍的。