这是最简的目录结构
my-extension/
├── manifest.json
├── background/
│ └── service-worker.js
├── content/
│ └── content.js
├── popup/
│ ├── popup.html
│ └── popup.js
├── icons/
│ └── icon48.png
└── _locales/
└── en/
└── messages.json
文件内容详解
1. manifest.json
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "A minimal extension with all core components",
"icons": {
"48": "icons/icon48.png"
},
"action": {
"default_popup": "popup/popup.html",
"default_icon": "icons/icon48.png"
},
"background": {
"service_worker": "background/service-worker.js",
"type": "module"
},
"content_scripts": [
{
"matches": ["<all_urls>"],//<all_urls> 表示所有页面都适用,一般就写这个就好了,如果需要特定网站使用,就需要你写域名了,对了这个如果没有生效,还需要编写host_permissons.
"js": ["content/content.js"],
"run_at": "document_idle"
}
],
"permissions": ["storage", "activeTab"],//这个参数可以查看谷歌开发官方文档。
}
2. background/service-worker.js
console.log('Service Worker 已启动');
// 安装事件
chrome.runtime.onInstalled.addListener(() => {
console.log('扩展已安装');
});
// 监听来自 popup 或 content script 的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'PING') {
sendResponse({ status: 'pong' });
}
return true;
});
3. content/content.js
console.log('Content script 已注入');
// 修改页面背景色
document.body.style.backgroundColor = '#f0f8ff';
// 监听来自扩展其他部分的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'GET_PAGE_TITLE') {
sendResponse({ title: document.title });
}
return true;
});
4. popup/popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { width: 250px; padding: 15px; font-family: Arial, sans-serif; }
button { margin-top: 10px; padding: 8px 16px; cursor: pointer; }
</style>
</head>
<body>
<h2>我的扩展</h2>
<p id="status">就绪</p>
<button id="pingBtn">发送 Ping</button>
<button id="getTitleBtn">获取页面标题</button>
<script src="popup.js"></script>
</body>
</html>
5. popup/popup.js
document.getElementById('pingBtn').addEventListener('click', async () => {
const response = await chrome.runtime.sendMessage({ type: 'PING' });
document.getElementById('status').textContent = response.status;
});
document.getElementById('getTitleBtn').addEventListener('click', async () => {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const response = await chrome.tabs.sendMessage(tab.id, { type: 'GET_PAGE_TITLE' });
document.getElementById('status').textContent = '标题: ' + response.title;
});
6. icons/icon48.png
任意 48×48 像素 PNG 图片。
7. _locales/en/messages.json(国际化示例)
{
"appName": {
"message": "My Extension"
},
"appDesc": {
"message": "A minimal Chrome extension demo"
}
}
各组件通信流程
用户点击图标
│
▼
popup/popup.html ──→ popup/popup.js
│ │
│ chrome.runtime.sendMessage()
│ │
▼ ▼
background/service-worker.js
│
│ chrome.tabs.sendMessage()
│
▼
content/content.js ──→ 操作网页 DOM
额外可选文件夹(按需添加)
my-extension/
├── options/ ← 选项页面
│ ├── options.html
│ └── options.js
├── lib/ ← 公共工具库
│ └── utils.js
├── css/ ← 样式文件
│ └── styles.css
├── images/ ← 更多图片资源
│ └── logo.svg
├── fonts/ ← 自定义字体
├── data/ ← 静态数据
│ └── config.json
└── test/ ← 测试文件
└── test.html
这个结构覆盖了 Chrome 扩展的三个核心组件:
| 组件 | 作用 | 生命周期 |
|---|---|---|
| background | 后台事件处理、全局状态管理 | 按需激活,空闲回收 |
| content | 操作网页 DOM、读取页面数据 | 随页面加载 |
| popup | 用户交互界面 | 点击图标时显示 |
直接把这个目录拖进 chrome://extensions 就能运行。
content.js 是操作你当前网页的方法,console.log 会打印到你当前操作网页上。
popup.html 是右上角插件点开的页面,可以定义。