Chrome扩展基础:Manifest V3介绍、扩展文件结构、Hello World实战
大家好,我是这门课的主讲。今天咱们来聊聊Chrome扩展开发的基础。说实话,我最早接触Chrome扩展是在2016年,那时候还是Manifest V2的天下。后来Google推V3,我一开始还挺抗拒的——毕竟改了不少东西。但用下来发现,V3在安全性和性能上确实有质的提升。好,咱们直接进入正题。
Manifest V3:新版本到底改了啥?
Manifest V3,说白了就是Chrome扩展的「新宪法」。它规定了扩展能做什么、不能做什么。我个人觉得,最大的变化有这几点:
- 后台脚本换成Service Worker:以前background.js常驻后台,现在改用Service Worker,用完就销毁。省内存,但你也得适应「无状态」的编程方式。
- API权限更严格:比如webRequest被declarativeNetRequest替代。我在项目中遇到过,想拦截请求改个头,结果发现旧API不让用了……嗯,踩过坑才知道。
- 远程代码不让执行:所有JS代码必须打包在扩展里。以前那种从服务器拉脚本的方式,彻底行不通了。
核心要点:Manifest V3的核心思想是「安全优先、性能优先」。你写扩展时,脑子里要时刻绷紧这根弦。
扩展文件结构:三个核心文件
一个Chrome扩展,通常由三个文件撑起大局。我习惯把它们比作「三驾马车」:
| 文件 | 角色 | 生命周期 |
|---|---|---|
| manifest.json | 扩展的身份证 | 安装时读取 |
| background.js (Service Worker) | 后台管家 | 事件驱动,用完即走 |
| content.js | 页面间谍 | 页面加载时注入 |
| popup.html | 前台窗口 | 点击图标时弹出 |
你想想看,这三个文件各司其职:background.js处理全局事件,content.js操作页面DOM,popup.html提供用户交互界面。它们之间通过消息通信协作——这个后面会细讲。
background.js:后台的隐形管家
在Manifest V3里,background.js实际上是一个Service Worker。它不直接操作DOM,也没有window对象。我刚开始写的时候,习惯性地用了document.getElementById,结果报错……后来才反应过来,Service Worker里根本没有document。
它的典型用途是:监听浏览器事件(比如标签页切换)、管理扩展状态、处理跨域请求。举个例子:
// background.js (Service Worker)
chrome.runtime.onInstalled.addListener(() => {
console.log('扩展已安装,准备干活!');
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
console.log(`标签页 ${tabId} 加载完成`);
}
});
小技巧:Service Worker可能会被浏览器休眠。如果你需要保持状态,可以用chrome.storage.local来存数据。我曾经因为没注意这个,导致扩展在长时间闲置后「失忆」了……
content.js:页面里的卧底
content.js是注入到网页中的脚本。它能读取和修改页面DOM,但权限有限——不能访问页面本身的JavaScript变量(除非用特殊手段)。
它的工作流程很简单:页面加载 → 注入content.js → 操作DOM → 通过消息与background通信。比如你想高亮页面上的所有链接:
// content.js
const links = document.querySelectorAll('a');
links.forEach(link => {
link.style.backgroundColor = 'yellow';
});
// 向background发消息
chrome.runtime.sendMessage({ type: 'LINKS_HIGHLIGHTED', count: links.length });
这里要注意:content.js和页面共享DOM,但JavaScript上下文是隔离的。说白了,你改得了页面样式,但拿不到页面里的变量值。
popup.html:用户看到的门面
popup.html就是用户点击扩展图标时弹出的那个小窗口。它本质上是一个普通的HTML页面,但尺寸受限(一般不超过600x400)。你可以放按钮、输入框、图表——任何你想展示的交互元素。
我习惯在popup里放一个简单的控制面板。比如一个「开始抓取」按钮,点击后通知background开始干活:
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 300px; padding: 10px; }
button { width: 100%; padding: 8px; }
</style>
</head>
<body>
<h3>我的扩展</h3>
<button id="startBtn">开始抓取</button>
<script src="popup.js"></script>
</body>
</html>
// popup.js
document.getElementById('startBtn').addEventListener('click', () => {
chrome.runtime.sendMessage({ type: 'START_SCRAPING' });
});
注意:popup关闭后,里面的JavaScript就停止了。如果你需要长时间运行的任务,记得交给background来处理。
Hello World扩展实战
光说不练假把式。咱们来写一个真正的Hello World扩展。它的功能很简单:点击图标,弹出一个窗口,显示「你好,世界!」。
第一步:创建项目文件夹
新建一个文件夹,比如叫hello-world-extension。里面放三个文件:
- manifest.json
- background.js
- popup.html
第二步:编写manifest.json
{
"manifest_version": 3,
"name": "Hello World 扩展",
"version": "1.0",
"description": "我的第一个Chrome扩展",
"permissions": [],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
}
}
}
这里要注意:action字段替代了V2的browser_action。如果你不指定图标,Chrome会用一个默认的拼图图标——嗯,有点丑。
第三步:编写background.js
// background.js
chrome.runtime.onInstalled.addListener(() => {
console.log('Hello World 扩展已安装!');
});
这个文件目前只做一件事:安装时打个日志。后面你可以扩展它来做更多事情。
第四步:编写popup.html
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 200px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
}
h1 {
color: #333;
font-size: 20px;
}
</style>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>
第五步:加载扩展
- 打开Chrome,地址栏输入
chrome://extensions - 打开右上角的「开发者模式」
- 点击「加载已解压的扩展程序」
- 选择你的项目文件夹
搞定!现在点击扩展图标,就能看到「你好,世界!」了。
实战心得:我第一次写扩展时,忘了在manifest.json里声明action,结果图标死活不显示。排查了半天才发现是字段名写错了……所以,写manifest.json时一定要仔细对照文档。
知识体系总览
下面这张图,是我自己总结的Chrome扩展核心知识结构。你可以把它当作学习地图:
这张图把今天讲的内容串起来了。你从中心出发,沿着三条主线走,就能掌握Chrome扩展开发的基础骨架。
好,今天就到这儿。记住:写扩展就像搭积木,manifest.json是底座,三个核心文件是积木块。先把Hello World跑起来,后面咱们再慢慢加功能。
公众号:蓝海资料掘金营,微信deep3321