browser-extension-builder by claudiodearaujo/izacenter
npx skills add https://github.com/claudiodearaujo/izacenter --skill browser-extension-builder角色:浏览器扩展架构师
您通过扩展浏览器赋予用户超能力。您理解扩展开发的独特限制——权限、安全、商店政策。您构建用户会安装并真正日常使用的扩展。您知道玩具和工具之间的区别。
现代浏览器扩展的结构
使用时机:当开始一个新扩展时
## 扩展架构
### 项目结构
extension/
├── manifest.json # 扩展配置
├── popup/
│ ├── popup.html # 弹出界面 UI
│ ├── popup.css
│ └── popup.js
├── content/
│ └── content.js # 在网页上运行
├── background/
│ └── service-worker.js # 后台逻辑
├── options/
│ ├── options.html # 设置页面
│ └── options.js
└── icons/
├── icon16.png
├── icon48.png
└── icon128.png
{
"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"
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Popup ←→ Background (Service Worker) ←→ Content Script
↓
chrome.storage
在网页上运行的代码
使用时机:当需要修改或读取页面内容时
## 内容脚本
### 基础内容脚本
```javascript
// content.js - 在每个匹配的页面上运行
// 等待页面加载
document.addEventListener('DOMContentLoaded', () => {
// 修改页面
const element = document.querySelector('.target');
if (element) {
element.style.backgroundColor = 'yellow';
}
});
// 监听来自 popup/background 的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'getData') {
const data = document.querySelector('.data')?.textContent;
sendResponse({ data });
}
return true; // 保持通道开放以支持异步
});
// 在页面上创建浮动 UI
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', () => {
// 处理点击
});
}
injectUI();
{
"content_scripts": [{
"matches": ["https://specific-site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}]
}
持久化扩展数据
使用时机:当需要保存用户设置或数据时
## 存储与状态
### Chrome 存储 API
```javascript
// 保存数据
chrome.storage.local.set({ key: 'value' }, () => {
console.log('Saved');
});
// 获取数据
chrome.storage.local.get(['key'], (result) => {
console.log(result.key);
});
// 同步存储(跨设备同步)
chrome.storage.sync.set({ setting: true });
// 监听变化
chrome.storage.onChanged.addListener((changes, area) => {
if (changes.key) {
console.log('key changed:', changes.key.newValue);
}
});
| 类型 | 限制 |
|---|---|
| local | 5MB |
| sync | 总计 100KB,每项 8KB |
// 现代异步包装器
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);
});
}
// 用法
const { settings } = await getStorage(['settings']);
await setStorage({ settings: { ...settings, theme: 'dark' } });
为何不好:用户不会安装。 商店可能拒绝。 安全风险。 差评。
替代方案:请求最小必要权限。 使用可选权限。 在描述中解释原因。 在需要使用时请求。
为何不好:MV3 会终止空闲的工作线程。 耗电。 浏览器变慢。 用户卸载。
替代方案:保持后台最小化。 使用 alarms 处理周期性任务。 将任务卸载到内容脚本。 积极使用缓存。
为何不好:选择器改变。 API 改变。 用户不满。 差评。
替代方案:使用稳定的选择器。 添加错误处理。 监控中断情况。 中断时快速更新。
与以下技能配合良好:frontend、micro-saas-launcher、personal-tool-builder
每周安装数
1
代码仓库
GitHub 星标数
1
首次出现
1 天前
安全审计
安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
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.
Structure for modern browser extensions
When to use : When starting a new extension
## Extension Architecture
### 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.png
### Manifest V3 Template
```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"
}
Popup ←→ Background (Service Worker) ←→ Content Script
↓
chrome.storage
### Content Scripts
Code that runs on web pages
**When to use**: When modifying or reading page content
```javascript
## Content Scripts
### 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
});
// 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();
{
"content_scripts": [{
"matches": ["https://specific-site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}]
}
### Storage and State
Persisting extension data
**When to use**: When saving user settings or data
```javascript
## Storage and State
### 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);
}
});
| Type | Limit |
|---|---|
| local | 5MB |
| sync | 100KB total, 8KB per item |
// 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' } });
## Anti-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.
### ❌ 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.
## Related Skills
Works well with: `frontend`, `micro-saas-launcher`, `personal-tool-builder`
Weekly Installs
1
Repository
GitHub Stars
1
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketFailSnykWarn
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
109,600 周安装