← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

浏览器插件-开发

Cross-browser extension development skill supporting Chrome, Firefox, Edge, and Safari with Manifest V3, build automation, and quality assurance

personAuthor: kissstronghubModelScope

Browser Extension Development Skill

跨浏览器插件开发技能,支持Chrome、Firefox、Edge、Safari,包含Manifest V3规范、自动化构建、质量保证和发布流程。

功能特性

  • ✅ 跨浏览器兼容 (Chrome/Firefox/Edge/Safari)
  • ✅ Manifest V3 标准支持
  • ✅ 自动化构建和打包
  • ✅ 多浏览器同时测试
  • ✅ 代码质量检查和优化
  • ✅ 自动发布到商店
  • ✅ 插件模板和脚手架
  • ✅ 调试和性能分析工具
  • ✅ 国际化支持
  • ✅ 安全审计和合规检查

支持的浏览器

| 浏览器 | 版本要求 | 格式 | 商店 | |--------|----------|------|------| | Chrome | 88+ | Manifest V3 | Chrome Web Store | | Firefox | 109+ | Manifest V3 | Firefox Add-ons | | Edge | 88+ | Manifest V3 | Microsoft Edge Add-ons | | Safari | 14+ | Safari Web Extension | Mac App Store |

工作流程

Step 1: 选择插件类型

第1步:选择插件类型
  [1] 📌 侧边栏插件 - 侧边栏界面
  [2] 🎯 弹出窗口插件 - Popup界面
  [3] 📄 内容脚本插件 - 注入网页
  [4] 🔧 工具栏插件 - Browser Action
  [5] 🎨 主题插件 - 浏览器主题
  [6] 📋 背景脚本插件 - 后台服务
  [7] 🚀 全功能插件 - 组合类型

Step 2: 配置插件信息

第2步:配置插件信息
  插件名称: [输入名称]
  版本号: [1.0.0]
  描述: [输入描述]
  作者: [输入作者]
  权限: [选择权限列表]

Step 3: 选择功能模块

第3步:选择功能模块
  [1] 🔔 通知系统
  [2] 💾 本地存储
  [3] 🌐 网络请求拦截
  [4] 📸 截图功能
  [5] 📋 剪贴板操作
  [6] 🔍 页面分析
  [7] 📊 数据统计
  [8] ⚙️ 选项页面

Step 4: 选择UI框架

第4步:选择UI框架
  [1] 🎨 原生HTML/CSS/JS
  [2] ⚛️ React
  [3] 💚 Vue.js
  [4] 🔷 Svelte
  [5] 🎯 Solid.js
  [6] 📦 Web Components

Step 5: 生成项目结构

根据选择生成完整的项目结构,包含所有必要的配置文件和模板代码。

Step 6: 开发和调试

使用提供的开发工具进行实时调试和测试。

Step 7: 构建和打包

自动构建所有浏览器版本的插件包。

Step 8: 质量检查

运行代码质量检查、安全审计和性能测试。

Step 9: 发布部署

一键发布到各个浏览器商店。

项目结构模板

基础模板

my-extension/
├── src/
│   ├── manifest.json          # Chrome/Edge manifest
│   ├── manifest.firefox.json  # Firefox manifest
│   ├── manifest.safari.json   # Safari manifest
│   ├── background/
│   │   └── service-worker.js  # Background script
│   ├── content/
│   │   ├── content.js         # Content script
│   │   └── content.css        # Content styles
│   ├── popup/
│   │   ├── popup.html         # Popup UI
│   │   ├── popup.js           # Popup logic
│   │   └── popup.css          # Popup styles
│   ├── options/
│   │   ├── options.html       # Options page
│   │   ├── options.js         # Options logic
│   │   └── options.css        # Options styles
│   ├── sidebar/
│   │   ├── sidebar.html       # Sidebar UI
│   │   ├── sidebar.js         # Sidebar logic
│   │   └── sidebar.css        # Sidebar styles
│   ├── icons/
│   │   ├── icon16.png
│   │   ├── icon48.png
│   │   └── icon128.png
│   └── _locales/
│       ├── en/
│       │   └── messages.json
│       └── zh_CN/
│           └── messages.json
├── scripts/
│   ├── build.js               # Build script
│   ├── watch.js               # Watch script
│   └── publish.js             # Publish script
├── tests/
│   ├── unit/
│   └── integration/
├── docs/
├── package.json
├── webpack.config.js
└── README.md

权限系统

常用权限

{
  "permissions": [
    "activeTab",           // 当前标签页
    "tabs",                // 标签页管理
    "storage",             // 本地存储
    "notifications",       // 通知
    "clipboardRead",       // 读取剪贴板
    "clipboardWrite",      // 写入剪贴板
    "downloads",           // 下载管理
    "webRequest",          // 网络请求
    "cookies",             // Cookie管理
    "history",             // 浏览历史
    "bookmarks",           // 书签管理
    "contextMenus",        // 右键菜单
    "management",          // 插件管理
    "scripting",           // 脚本注入
    "sidePanel"            // 侧边栏
  ],
  "host_permissions": [
    "https://*/*",         // 所有HTTPS网站
    "http://*/*",          // 所有HTTP网站
    "*://*.example.com/*"  // 特定网站
  ]
}

API使用指南

存储API

// 保存数据
chrome.storage.local.set({ key: value });

// 读取数据
chrome.storage.local.get(['key'], (result) => {
  console.log(result.key);
});

// 监听变化
chrome.storage.onChanged.addListener((changes, namespace) => {
  for (let key in changes) {
    let storageChange = changes[key];
    console.log(key, storageChange.oldValue, storageChange.newValue);
  }
});

标签页API

// 获取当前标签页
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
  let currentTab = tabs[0];
});

// 创建新标签页
chrome.tabs.create({url: 'https://example.com'});

// 更新标签页
chrome.tabs.update(tabId, {url: 'https://example.com'});

// 注入内容脚本
chrome.scripting.executeScript({
  target: {tabId: tabId},
  files: ['content.js']
});

通知API

// 创建通知
chrome.notifications.create('notification-id', {
  type: 'basic',
  iconUrl: 'icon.png',
  title: '标题',
  message: '内容'
});

// 监听点击
chrome.notifications.onClicked.addListener((notificationId) => {
  console.log('通知被点击:', notificationId);
});

网络请求API

// 监听请求
chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    console.log('请求:', details.url);
    return {cancel: false};
  },
  {urls: ["<all_urls>"]},
  ["blocking"]
);

// 修改请求头
chrome.webRequest.onBeforeSendHeaders.addListener(
  (details) => {
    details.requestHeaders.push({
      name: 'X-Custom-Header',
      value: 'value'
    });
    return {requestHeaders: details.requestHeaders};
  },
  {urls: ["<all_urls>"]},
  ["blocking", "requestHeaders"]
);

跨浏览器兼容性处理

条件代码

// 检测浏览器
const isChrome = typeof chrome !== 'undefined' && chrome.runtime;
const isFirefox = typeof browser !== 'undefined';
const isSafari = typeof safari !== 'undefined';

// 使用适配器模式
if (isChrome) {
  // Chrome/Edge代码
  chrome.runtime.sendMessage({action: 'getData'});
} else if (isFirefox) {
  // Firefox代码
  browser.runtime.sendMessage({action: 'getData'});
} else if (isSafari) {
  // Safari代码
  safari.extension.dispatchMessage('getData');
}

统一API封装

// utils/browser-api.js
export const browserAPI = (() => {
  if (typeof chrome !== 'undefined' && chrome.runtime) {
    return chrome;
  } else if (typeof browser !== 'undefined') {
    return browser;
  }
  throw new Error('Unsupported browser');
})();

// 使用
browserAPI.storage.local.set({key: value});
browserAPI.tabs.query({active: true, currentWindow: true});

构建配置

Webpack配置

// webpack.config.js
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: {
    background: './src/background/service-worker.js',
    content: './src/content/content.js',
    popup: './src/popup/popup.js',
    options: './src/options/options.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]/[name].js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        {from: 'src/manifest.json', to: 'manifest.json'},
        {from: 'src/icons', to: 'icons'},
        {from: 'src/_locales', to: '_locales'},
        {from: 'src/popup/popup.html', to: 'popup/popup.html'},
        {from: 'src/options/options.html', to: 'options/options.html'},
        {from: 'src/sidebar/sidebar.html', to: 'sidebar/sidebar.html'}
      ]
    }),
    new MiniCssExtractPlugin({
      filename: '[name]/[name].css'
    })
  ]
};

质量保证

代码检查规则

{
  "extends": [
    "eslint:recommended",
    "plugin:chrome-extension/recommended",
    "plugin:mozilla/recommended"
  ],
  "rules": {
    "no-unused-vars": "error",
    "no-undef": "error",
    "camelcase": "warn",
    "consistent-return": "error",
    "no-eval": "error",
    "no-implied-eval": "error"
  }
}

测试框架

// Jest配置
module.exports = {
  testEnvironment: 'jsdom',
  setupFiles: ['./tests/setup.js'],
  testMatch: ['**/tests/**/*.test.js'],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80
    }
  }
};

发布流程

Chrome Web Store

  1. 打包为.zip文件
  2. 登录Chrome Web Store开发者控制台
  3. 上传并填写插件信息
  4. 提交审核

Firefox Add-ons

  1. 使用web-ext工具打包
  2. 登录Firefox Developer Hub
  3. 上传并填写插件信息
  4. 提交审核

Microsoft Edge Add-ons

  1. 打包为.zip文件
  2. 登录Microsoft Partner Center
  3. 上传并填写插件信息
  4. 提交审核

Safari App Store

  1. 使用Xcode打包
  2. 提交到App Store Connect
  3. 填写插件信息
  4. 提交审核

调试技巧

Chrome调试

  • chrome://extensions/ 开启开发者模式
  • 检查后台页面控制台
  • 使用DevTools检查内容脚本
  • 查看Network面板的请求

Firefox调试

  • about:debugging#/runtime/this-firefox
  • 检查后台脚本
  • 使用浏览器控制台
  • 查看存储数据

Edge调试

  • edge://extensions/ 开启开发者模式
  • 类似Chrome的调试方式

性能优化建议

  1. 减少权限: 只请求必要的权限
  2. 延迟加载: 非关键功能延迟加载
  3. 缓存数据: 合理使用storage缓存
  4. 优化网络: 批量请求,减少API调用
  5. 内存管理: 及时清理不需要的监听器
  6. 代码分割: 使用动态import分割代码

安全最佳实践

  1. 内容安全策略: 配置严格的CSP
  2. 输入验证: 验证所有用户输入
  3. HTTPS优先: 优先使用HTTPS
  4. 最小权限: 只请求必要权限
  5. 数据加密: 敏感数据加密存储
  6. 定期更新: 及时更新依赖

依赖安装

npm install

直接运行脚本

# 开发模式
npm run dev

# 构建所有浏览器版本
npm run build

# 构建特定浏览器
npm run build:chrome
npm run build:firefox
npm run build:edge
npm run build:safari

# 测试
npm test

# 代码检查
npm run lint

# 发布
npm run publish

注意事项

  1. Chrome和Edge使用相同的Manifest V3格式
  2. Firefox使用Manifest V3但有一些差异
  3. Safari需要特殊的适配
  4. 不同浏览器的API实现可能有差异
  5. 权限声明需要根据实际需求调整
  6. 测试时需要在不同浏览器中验证

验证

生成后检查:

  1. 项目结构是否完整
  2. Manifest文件是否正确
  3. 构建脚本是否可执行
  4. 代码质量是否达标
  5. 跨浏览器兼容性是否良好