mcpField
B
build-chrome-extension

build-chrome-extension

github.com/yigitkonur开发1338 次安装2 天前更新
代码仓库

关于 build-chrome-extension

用于构建、调试、验证和打包 Chrome Manifest V3 扩展的 Skill。重点涵盖服务工作线程生命周期、内容脚本隔离、最小权限和 Web Store 准备。

主要功能

  1. 01Manifest V3 扩展工作流
  2. 02服务工作线程生命周期指引
  3. 03内容脚本隔离模式
  4. 04最小权限规划
  5. 05构建验证与打包

适用场景

  1. 01搭建新的 Chrome 扩展
  2. 02将扩展从 MV2 迁移到 MV3
  3. 03排查服务工作线程或消息问题
  4. 04准备 Web Store 审核构建

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yigitkonur/skills-by-yigitkonur --skill build-chrome-extension

安装后在 Claude Code 中输入/build-chrome-extension确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
agents/
openai.yaml
references/apis/
core-apis.md
messaging.md
storage.md
references/frameworks/
comparison.md
references/patterns/
content-scripts.md
desktop-ipc.md
service-worker.md
ui-surfaces.md
references/publishing/
web-store.md
references/testing/
debugging.md
testing-guide.md
scripts/
check-mv3-manifest.md
check-mv3-manifest.sh
preflight-extension.md
preflight-extension.sh

详细介绍

构建 Chrome 扩展

构建、调试、打包并发布 Chrome Manifest V3 扩展。重点优化服务工作线程在重启后安全运行、内容脚本隔离、最小权限原则,以及做好通过 Web Store 审核的准备。

适用场景

遇到以下任一需求时触发:

  • 创建新的 Chrome MV3 扩展,或使用框架(WXT、Plasmo、CRXJS、Vite)搭建项目
  • 编辑或生成 manifest.json,其中包含 manifest_version: 3、service_worker、content_scripts、host_permissions、action 或 side_panel 字段
  • 实现或调试 chrome.runtime、chrome.storage、chrome.alarms、chrome.scripting、chrome.tabs、chrome.declarativeNetRequest、chrome.sidePanel 或 chrome.offscreen API
  • 将 Chrome 扩展连接到桌面应用或本地守护进程(Raycast Companion、本地 WebSocket 服务、Native Messaging 主机)
  • 修复 MV3 服务工作线程生命周期问题:空闲终止、在顶层注册监听器、异步 onMessage 返回值、chrome.alarms 与 setInterval 的取舍
  • 在 ISOLATED 和 MAIN 世界之间桥接内容脚本,或通过服务工作线程路由 fetch 请求,以使用跨域主机权限
  • 将 MV2 扩展迁移到 MV3(后台页面 → 服务工作线程、阻塞式 webRequest → declarativeNetRequest、browser_action → action)
  • 验证已构建的 dist/ 或 .output/chrome-mv3/ 文件夹、打包 Web Store zip、撰写隐私和权限说明,或准备审核备注
  • 为新项目选择或比较 Chrome MV3 框架

以下情况请勿使用此技能:

  • 目标平台是 Firefox、Safari,或跨浏览器 polyfill(browser.* 命名空间、web-ext 工具、Safari App Extensions)
  • 需求是在扩展环境之外进行通用浏览器自动化——请转至 run-agent-browser
  • 发布普通 npm 包或库——请转至 publish-npm-package
  • 构建其他平台的扩展(Raycast 脚本命令、VS Code 扩展、Edge 企业策略包)——请转至对应平台的技能

固定默认项——生成代码前应用

键默认值
Manifest 目标仅使用 manifest_version: 3;绝不生成 MV2
全新项目框架使用 WXT,除非仓库已选用其他 MV3 工具
持久状态使用 chrome.storage.local;临时且需在重启后安全保留的状态使用 chrome.storage.session
后台模型事件驱动的服务工作线程,监听器在顶层同步注册
定期工作使用 chrome.alarms——后台调度绝不使用 setTimeout/setInterval
网络修改使用 chrome.declarativeNetRequest——绝不使用阻塞式 webRequest
权限遵循最小权限原则;优先通过 chrome.permissions.request 授予 optional_permissions 和 optional_host_permissions
加载的文件夹仅加载构建产物:WXT .output/chrome-mv3-dev/ 或 .output/chrome-mv3/;Plasmo build/chrome-mv3-*;CRXJS/Vite dist/
桌面 IPC 传输无特权守护进程使用本地 WebSocket;需要安装程序的系统工具使用 Native Messaging
打包前检查压缩前,针对生产构建运行 scripts/check-mv3-manifest.sh 和 scripts/preflight-extension.sh

MV3 易踩问题 — 请牢记

这些故障在每次 MV3 构建中都会反复出现。编写代码前,请牢记:

  • Service worker 会在空闲时退出(默认约 30 秒)。模块作用域的全局状态会在事件之间消失。每次 await 前持久化,并在事件入口处重新加载。
  • 在顶层同步注册 chrome.runtime.onMessage、onInstalled、onStartup、alarm 和 tab 监听器。延迟注册的监听器会错过唤醒事件。
  • setTimeout/setInterval 无法让 service worker 保持运行,也无法保证在空闲周期之间可靠触发。请使用 chrome.alarms.create,并将 periodInMinutes 设为 >= 0.5。
  • 在 Chrome 148 及更高版本中,chrome.runtime.onMessage 监听器原生支持返回 Promise 或使用 async。为保持向后兼容(<148 且跨浏览器),异步处理程序必须同步 return true,并在完成时调用 sendResponse;否则消息通道会立即关闭,发送方收到 undefined(或因 "The message port closed before a response was received" 而被拒绝)。
  • Service worker 中的本地 WebSocket 连接在空闲约 30 秒后会终止。必须维持活跃的心跳 ping(间隔 <30 秒,例如 24 秒),以重置 Chrome 116 及更高版本的空闲计时器。空闲的开放套接字无法让 worker 保持运行。
  • 监听 127.0.0.1 的本地 WebSocket 容易受到恶意网页发起的跨站 WebSocket 劫持(CSWSH)。守护进程必须根据 chrome-extension://<id> 验证 Origin 标头,并在 HTTP Upgrade 期间要求提供身份验证令牌。
  • Native Messaging 主机绝不能向标准输出(stdout)写入调试日志或未格式化的输出。任何非帧格式的标准输出都会破坏 32 位长度前缀并导致连接崩溃。日志应发送到 stderr。
  • Native Messaging 主机发送给 Chrome 的消息严格限制为 1 MB。超过 1 MB 会立即终止进程。
  • Content script 默认运行在隔离世界中。页面的 JS、框架和 window.* 全局变量都不可见。仅在需要访问页面 JS 时使用 world: "MAIN",随后通过 postMessage 和同源令牌建立桥接。
  • 扩展来源的 fetch 需要匹配的 host_permissions。Content script 的 fetch 受页面来源和 CORS 规则约束;请通过 chrome.runtime.sendMessage 将需要特权的请求路由到 service worker。
  • MV3 CSP 禁止扩展页面中的内联 <script>、eval()、new Function() 和远程可执行代码。请打包所有内容;不要从 CDN 加载脚本。(manifest.sandbox 中的沙盒页面是唯一例外,允许使用 unsafe-eval。)
  • 手写的 manifest.json 路径必须指向构建产物(例如 background.js、content.js、popup.html),不能指向 src/*.ts 或未构建的源文件。
  • 安装时申请 <all_urls> 或广泛的主机权限会增加 Web Store 审核阻力。优先使用 activeTab 加上可选的主机授权。

决策规则

决策默认方案在以下情况升级处理
后台状态chrome.storage.session/local事务、大型索引、二进制数据 → IndexedDB
定期工作chrome.alarms实时流 → 设计重连机制和队列
网络修改declarativeNetRequest只读观察 → 使用非阻塞的 webRequest
获取页面数据服务工作线程通过 fetch 配合主机权限页面源足以满足需求 → 内容脚本通过 fetch 获取
访问页面 JS使用 world: "MAIN" 桥接,并验证负载仅访问 DOM → 保持在 ISOLATED world
UI 状态持久化chrome.storage.session必须在浏览器重启后保留 → 使用 local 或 sync
主机访问权限activeTab 或可选主机授权若没有安装时授予的主机访问权限,扩展将无法运行
侧边面板还是弹出窗口持续显示的配套 UI 使用侧边面板快速操作或简短表单 → 使用弹出窗口
离屏文档从服务工作线程访问 DOM/canvas/clipboard/audio/Worker若弹出窗口、选项页或内容脚本可以处理 → 跳过
桌面通信本地 WebSocket(ws://127.0.0.1:<port>),并防范 CSWSH深度操作系统集成/企业分发/不暴露本地端口 → 使用 chrome.runtime.connectNative

路由边界

请求类型操作
"Build a Chrome extension"使用此技能;目标为 MV3
"Build for Chrome and Firefox"在此保留 Chrome MV3;跨浏览器层不在范围内
"Automate a website in a browser"路由至 run-agent-browser
"Write Playwright tests for an extension"此处提供扩展启动/加载说明;本工具包不涵盖更广泛的 Playwright 编写
"Publish to npm"路由至 publish-npm-package
"Submit to Chrome Web Store"使用此技能;阅读 references/publishing/web-store.md
"Deploy via enterprise policy"不在范围内,除非存在专门的企业技能

工作流

1. 确定扩展范围

询问:「扩展包含哪些界面,需要哪些 Chrome API,哪些权限可以延后到运行时申请?」

  1. 列出所需界面:弹出窗口、选项页、侧边面板、内容脚本、服务工作线程、离屏文档、开发者工具。
  2. 列出所需的 Chrome API 及相应权限。
  3. 区分安装时权限与 optional_permissions/optional_host_permissions。
  4. 选择框架——参见 references/frameworks/comparison.md。
  5. 记录 Chrome 将加载的构建输出文件夹。
2. 搭建脚手架或改造现有项目

询问:「这是从零开始、基于现有框架构建,还是手写 manifest?」

  • 从零开始时默认使用:WXT。
  • 将现有 Vite 应用改造成扩展:CRXJS。
  • 自定义构建流程/需要明确控制:vanilla + Vite。
  • 现有仓库:遵循其框架和输出约定。

Chrome 必须加载构建输出文件夹,绝不能加载 src/ 或未打包的 TypeScript。

3. 实现扩展上下文

询问:「由哪个上下文管理状态,哪个上下文管理 DOM,哪些消息会跨越边界?」

编写代码前阅读对应的参考资料:

  • 服务工作线程生命周期、持久化、定时任务、离屏文档 → references/patterns/service-worker.md
  • 内容脚本、世界隔离、幂等性、跨源路由 → references/patterns/content-scripts.md
  • 弹出窗口、选项页、侧边面板、开发者工具、新标签页界面 → references/patterns/ui-surfaces.md
  • 一次性消息、端口、外部/原生消息传递、页面桥接 → references/apis/messaging.md
  • 桌面通信、Raycast Companion、原生消息传递 → references/patterns/desktop-ipc.md
  • chrome.storage 区域、配额、类型化封装、迁移 → references/apis/storage.md
  • 标签页、脚本、定时任务、DNR、侧边面板、离屏文档、运行时 → references/apis/core-apis.md
  • Manifest、权限和 MV2 迁移决策,参见此 SKILL.md 中锁定的默认设置和防护规则。

验证每个跨边界负载:消息、存储读取结果、外部 API 响应、MAIN world 桥接数据。

4. 验证构建产物

请问:“Chrome 能加载这个确切的文件夹吗?其中的所有清单路径都存在吗?”

在技能目录中,针对你的构建文件夹运行:

scripts/check-mv3-manifest.sh dist
scripts/preflight-extension.sh dist

根据框架调整路径:

框架开发输出生产输出
WXT.output/chrome-mv3-dev/.output/chrome-mv3/
Plasmobuild/chrome-mv3-dev/build/chrome-mv3-prod/
CRXJSdist/dist/
Vanilla Vitedist/dist/

修改任一脚本前,先阅读 scripts/check-mv3-manifest.md 和 scripts/preflight-extension.md。

5. 测试扩展行为

请问:“有什么故障只有在 Chrome 加载扩展后才会出现?”

  • 对纯逻辑和消息/存储辅助函数进行单元测试;只在边界处模拟 chrome.*。
  • 通过 chrome://extensions →“加载已解压的扩展程序”手动加载构建产物。
  • 从扩展程序页面检查 Service Worker;触发一次休眠/唤醒周期。
  • 在允许和禁止的 URL 上测试内容脚本注入。
  • 在调用主机之前,验证运行时权限请求的 UX(chrome.permissions.request)。

扩展专用测试请阅读 references/testing/testing-guide.md;Service Worker、弹出窗口、内容脚本、权限和存储的调试请阅读 references/testing/debugging.md。

6. 打包以供 Web Store 审核

请问:“审核者能否各用一句话说明唯一用途、每项权限的必要性、数据使用方式和远程代码策略?”

  1. 构建生产产物。
  2. 针对该生产构建运行两个打包脚本。
  3. 压缩前清理无关内容:源映射(除非有意随包发布)、测试、.DS_Store、__MACOSX、框架缓存。
  4. 在构建产物文件夹内创建 zip(确保 manifest.json 位于 zip 根目录)。
  5. 准备:隐私实践、逐项权限说明、远程代码披露、数据使用认证、审核者测试说明。
  6. 提交前阅读 references/publishing/web-store.md。

最低构建证据

停止前,根据任务匹配相应证据:

任务证据
新建脚手架构建产物路径 + check-mv3-manifest.sh 结果
功能变更相关单元/集成测试 + Chrome 行为发生变化时的手动加载说明
清单/权限变更check-mv3-manifest.sh 结果 + 权限说明
内容脚本变更允许的 URL 注入结果 + 禁止的 URL 注入结果
Service Worker 变更重启恢复说明,或明确注明“未测试”
打包/Web Store 工作preflight-extension.sh 结果 + zip 路径 + 审核者说明

输出要求

最终报告包括:

  • 已加载的构建目录
  • zip 路径(如已打包)
  • 手动测试时使用的 Chrome 版本
  • 权限摘要及主机权限说明
  • Web Store 政策合规情况:唯一用途、数据使用、远程代码、MV3 合规性
  • 运行过的脚本/测试,包括失败项
  • 剩余手动检查的审核者说明

防护原则

  • 新项目中绝不生成或保留 Manifest V2。
  • 除非框架明确在 src/ 中生成可加载代码,否则绝不在 Chrome 中加载 src/。
  • 绝不在 Service Worker 的模块级全局变量中保存持久状态。
  • 绝不依赖 setTimeout/setInterval 保持 Service Worker 运行。
  • 对常规 MV3 网络修改,绝不使用阻塞式 webRequest。
  • 未提供功能级理由且未记录更窄的替代方案时,绝不请求 <all_urls>。
  • 绝不通过未经身份验证的内容脚本消息开放任意后台 fetch。
  • 绝不发布远程可执行代码或未声明的远程代码行为。
  • 声称完成前,始终根据 manifest.json 验证构建产物路径。
  • 始终确保每项权限都能用一句话说明理由。

总结

MV3 会反复惩罚同样的错误:服务工作线程状态丢失、监听器注册过晚、基于计时器的调度、隔离世界带来的意外、权限范围过宽,以及发布 src/ 而非构建产物。应用固定的默认设置,深入了解时参阅相关资料,针对构建文件夹运行内置脚本,并提供可供审核的证据。

评论

支持 Markdown