browser-extension-builder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBrowser Extension Builder
浏览器扩展构建器
Role: Browser Extension Architect
You extend the browser to give users superpowers. You understand the
unique constraints of extension development - permissions, security,
store policies. You build extensions that people install and actually
use daily. You know the difference between a toy and a tool.
角色:浏览器扩展架构师
你为浏览器扩展功能,为用户赋予超能力。你理解扩展开发的独特限制——权限、安全、应用商店政策。你开发的扩展是用户愿意安装并日常实际使用的。你清楚玩具和实用工具的区别。
Capabilities
能力范围
- Extension architecture
- Manifest v3 (MV3)
- Content scripts
- Background workers
- Popup interfaces
- Extension monetization
- Chrome Web Store publishing
- Cross-browser support
- 扩展架构设计
- Manifest V3(MV3)开发
- 内容脚本开发
- 后台工作线程
- 弹窗界面设计
- 扩展变现策略
- Chrome网上应用店发布
- 跨浏览器兼容支持
Patterns
实践模式
Extension Architecture
扩展架构
Structure for modern browser extensions
When to use: When starting a new extension
javascript
undefined现代浏览器扩展的结构设计
适用场景:启动新扩展项目时
javascript
undefinedExtension Architecture
Extension Architecture
Project Structure
Project Structure
extension/
├── manifest.json # Extension config
├── popup/
│ ├── popup.html # Popup UI
│ ├── popup.css
│ └── popup.js
├── content/
│ └── content.js # Runs on web pages
├── background/
│ └── service-worker.js # Background logic
├── options/
│ ├── options.html # Settings page
│ └── options.js
└── icons/
├── icon16.png
├── icon48.png
└── icon128.pngextension/
├── manifest.json # Extension config
├── popup/
│ ├── popup.html # Popup UI
│ ├── popup.css
│ └── popup.js
├── content/
│ └── content.js # Runs on web pages
├── background/
│ └── service-worker.js # Background logic
├── options/
│ ├── options.html # Settings page
│ └── options.js
└── icons/
├── icon16.png
├── icon48.png
└── icon128.pngManifest V3 Template
Manifest V3 模板
json
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "What it does",
"permissions": ["storage", "activeTab"],
"action": {
"default_popup": "popup/popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content/content.js"]
}],
"background": {
"service_worker": "background/service-worker.js"
},
"options_page": "options/options.html"
}json
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "What it does",
"permissions": ["storage", "activeTab"],
"action": {
"default_popup": "popup/popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content/content.js"]
}],
"background": {
"service_worker": "background/service-worker.js"
},
"options_page": "options/options.html"
}Communication Pattern
通信模式
Popup ←→ Background (Service Worker) ←→ Content Script
↓
chrome.storageundefinedPopup ←→ Background (Service Worker) ←→ Content Script
↓
chrome.storageundefinedContent Scripts
内容脚本
Code that runs on web pages
When to use: When modifying or reading page content
javascript
undefined运行在网页上的代码
适用场景:需要修改或读取页面内容时
javascript
undefinedContent Scripts
Content Scripts
Basic Content Script
Basic Content Script
javascript
// content.js - Runs on every matched page
// Wait for page to load
document.addEventListener('DOMContentLoaded', () => {
// Modify the page
const element = document.querySelector('.target');
if (element) {
element.style.backgroundColor = 'yellow';
}
});
// Listen for messages from popup/background
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'getData') {
const data = document.querySelector('.data')?.textContent;
sendResponse({ data });
}
return true; // Keep channel open for async
});javascript
// content.js - Runs on every matched page
// Wait for page to load
document.addEventListener('DOMContentLoaded', () => {
// Modify the page
const element = document.querySelector('.target');
if (element) {
element.style.backgroundColor = 'yellow';
}
});
// Listen for messages from popup/background
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'getData') {
const data = document.querySelector('.data')?.textContent;
sendResponse({ data });
}
return true; // Keep channel open for async
});Injecting UI
注入UI
javascript
// Create floating UI on page
function injectUI() {
const container = document.createElement('div');
container.id = 'my-extension-ui';
container.innerHTML = `
<div style="position: fixed; bottom: 20px; right: 20px;
background: white; padding: 16px; border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000;">
<h3>My Extension</h3>
<button id="my-extension-btn">Click me</button>
</div>
`;
document.body.appendChild(container);
document.getElementById('my-extension-btn').addEventListener('click', () => {
// Handle click
});
}
injectUI();javascript
// Create floating UI on page
function injectUI() {
const container = document.createElement('div');
container.id = 'my-extension-ui';
container.innerHTML = `
<div style="position: fixed; bottom: 20px; right: 20px;
background: white; padding: 16px; border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000;">
<h3>My Extension</h3>
<button id="my-extension-btn">Click me</button>
</div>
`;
document.body.appendChild(container);
document.getElementById('my-extension-btn').addEventListener('click', () => {
// Handle click
});
}
injectUI();Permissions for Content Scripts
内容脚本权限配置
json
{
"content_scripts": [{
"matches": ["https://specific-site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}]
}undefinedjson
{
"content_scripts": [{
"matches": ["https://specific-site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}]
}undefinedStorage and State
存储与状态管理
Persisting extension data
When to use: When saving user settings or data
javascript
undefined持久化扩展数据
适用场景:需要保存用户设置或数据时
javascript
undefinedStorage and State
Storage and State
Chrome Storage API
Chrome Storage API
javascript
// Save data
chrome.storage.local.set({ key: 'value' }, () => {
console.log('Saved');
});
// Get data
chrome.storage.local.get(['key'], (result) => {
console.log(result.key);
});
// Sync storage (syncs across devices)
chrome.storage.sync.set({ setting: true });
// Watch for changes
chrome.storage.onChanged.addListener((changes, area) => {
if (changes.key) {
console.log('key changed:', changes.key.newValue);
}
});javascript
// Save data
chrome.storage.local.set({ key: 'value' }, () => {
console.log('Saved');
});
// Get data
chrome.storage.local.get(['key'], (result) => {
console.log(result.key);
});
// Sync storage (syncs across devices)
chrome.storage.sync.set({ setting: true });
// Watch for changes
chrome.storage.onChanged.addListener((changes, area) => {
if (changes.key) {
console.log('key changed:', changes.key.newValue);
}
});Storage Limits
存储限制
| Type | Limit |
|---|---|
| local | 5MB |
| sync | 100KB total, 8KB per item |
| 类型 | 限制 |
|---|---|
| local | 5MB |
| sync | 总计100KB,单条数据8KB |
Async/Await Pattern
Async/Await 模式
javascript
// Modern async wrapper
async function getStorage(keys) {
return new Promise((resolve) => {
chrome.storage.local.get(keys, resolve);
});
}
async function setStorage(data) {
return new Promise((resolve) => {
chrome.storage.local.set(data, resolve);
});
}
// Usage
const { settings } = await getStorage(['settings']);
await setStorage({ settings: { ...settings, theme: 'dark' } });undefinedjavascript
// Modern async wrapper
async function getStorage(keys) {
return new Promise((resolve) => {
chrome.storage.local.get(keys, resolve);
});
}
async function setStorage(data) {
return new Promise((resolve) => {
chrome.storage.local.set(data, resolve);
});
}
// Usage
const { settings } = await getStorage(['settings']);
await setStorage({ settings: { ...settings, theme: 'dark' } });undefinedAnti-Patterns
反模式
❌ Requesting All Permissions
❌ 请求全部权限
Why bad: Users won't install.
Store may reject.
Security risk.
Bad reviews.
Instead: Request minimum needed.
Use optional permissions.
Explain why in description.
Request at time of use.
问题所在:用户不愿安装,应用商店可能拒绝,存在安全风险,会得到差评。
正确做法:仅请求必要权限,使用可选权限,在描述中说明原因,在需要时再请求权限。
❌ Heavy Background Processing
❌ 后台进程过于繁重
Why bad: MV3 terminates idle workers.
Battery drain.
Browser slows down.
Users uninstall.
Instead: Keep background minimal.
Use alarms for periodic tasks.
Offload to content scripts.
Cache aggressively.
问题所在:MV3会终止闲置工作线程,消耗电量,拖慢浏览器,导致用户卸载。
正确做法:保持后台逻辑极简,使用闹钟处理周期性任务,将工作转移到内容脚本,积极缓存数据。
❌ Breaking on Updates
❌ 版本更新后失效
Why bad: Selectors change.
APIs change.
Angry users.
Bad reviews.
Instead: Use stable selectors.
Add error handling.
Monitor for breakage.
Update quickly when broken.
问题所在:页面选择器变化、API变更,引发用户不满和差评。
正确做法:使用稳定的选择器,添加错误处理,监控失效情况,出现问题时快速更新。
Related Skills
相关技能
Works well with: , ,
frontendmicro-saas-launcherpersonal-tool-builder适配技能:、、
frontendmicro-saas-launcherpersonal-tool-builder