mcpField
B
build-chrome-extension

build-chrome-extension

github.com/yigitkonur開発1338 回インストール2 日前に更新
リポジトリ

build-chrome-extension について

Chrome Manifest V3拡張機能の構築、デバッグ、検証、パッケージ化を支援するスキルです。サービスワーカーのライフサイクル、コンテンツスクリプトの分離、最小権限、Web Store審査準備を重視します。

主な機能

  1. 01Manifest V3拡張機能のワークフロー
  2. 02サービスワーカーのライフサイクル指針
  3. 03コンテンツスクリプトの分離パターン
  4. 04最小権限の計画
  5. 05ビルド検証とパッケージ化

活用シーン

  1. 01新しいChrome拡張機能の作成
  2. 02拡張機能のMV2からMV3への移行
  3. 03サービスワーカーやメッセージの問題解決
  4. 04Web 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 の各ワールド間でコンテンツスクリプトを橋渡しする場合や、クロスオリジンのホスト権限を利用するためにサービスワーカー経由でフェッチを行う場合
  • MV2 拡張機能を MV3 に移行する場合(バックグラウンドページ → サービスワーカー、ブロッキングの webRequest → declarativeNetRequest、browser_action → action)
  • ビルド済みの dist/ または .output/chrome-mv3/ フォルダーを検証する場合、Web Store 用の zip をパッケージ化する場合、プライバシーや権限の正当性を説明する場合、審査用のメモを準備する場合
  • 新しいプロジェクト向けに Chrome MV3 フレームワークを選択または比較する場合

次の場合はこのスキルを使用しないでください。

  • 対象が Firefox、Safari、またはクロスブラウザーのポリフィル(browser.* 名前空間、web-ext ツール、Safari App Extensions)の場合
  • 拡張機能のコンテキスト外で、一般的なブラウザー自動化を行うリクエストの場合 — run-agent-browser に振り分けます
  • 通常の npm パッケージやライブラリを公開する場合 — publish-npm-package に振り分けます
  • 別のプラットフォームの拡張機能(Raycast のスクリプトコマンド、VS Code 拡張機能、Edge のエンタープライズポリシーパッケージ)を構築する場合 — 該当するプラットフォームのスキルに振り分けます

固定のデフォルト — コードを生成する前に適用

項目デフォルト
Manifest の対象manifest_version: 3 のみ。MV2 は生成しない
新規プロジェクトのフレームワークリポジトリですでに別の MV3 ツールを選択している場合を除き、WXT
永続状態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
パッケージ化前の事前確認zip 化する前に、本番ビルドを対象として scripts/check-mv3-manifest.sh と scripts/preflight-extension.sh を実行

MV3 の落とし穴 — 常に意識しておくこと

MV3 のビルドでは、次の問題が繰り返し発生します。コードを書く前に頭に入れておいてください。

  • サービスワーカーはアイドル状態になると停止します(デフォルトで約30秒)。モジュールのグローバルスコープにある状態は、イベント間で失われます。各 await の前に永続化し、イベント開始時に再読み込みしてください。
  • chrome.runtime.onMessage、onInstalled、onStartup、アラーム、タブの各リスナーは、トップレベルで同期的に登録してください。登録が遅れると、起動イベントを取りこぼします。
  • setTimeout/setInterval ではサービスワーカーを稼働状態に保てず、アイドルサイクルをまたいで確実に実行されることもありません。periodInMinutes >= 0.5 を指定して chrome.alarms.create を使用してください。
  • Chrome 148 以降では、chrome.runtime.onMessage リスナーは Promise の返却または async の使用をネイティブでサポートします。後方互換性(148 未満およびクロスブラウザー)を保つには、非同期ハンドラーは同期的に return true を返し、処理完了時に sendResponse を呼び出す必要があります。そうしないと、メッセージチャネルがすぐに閉じ、送信側は undefined を受け取るか、"The message port closed before a response was received" で拒否されます。
  • サービスワーカー内のローカル WebSocket 接続は、約30秒間通信がないと切断されます。Chrome 116 以降のアイドルタイマーをリセットするには、アクティブなハートビート ping(間隔は30秒未満、たとえば24秒)を維持する必要があります。アイドル状態のソケットを開いたままにしても、ワーカーの稼働は維持されません。
  • 127.0.0.1 でリッスンするローカル WebSocket は、悪意のあるウェブページからのクロスサイト WebSocket ハイジャック(CSWSH)の危険にさらされます。デーモンは Origin ヘッダーが chrome-extension://<id> と一致することを必ず検証し、HTTP Upgrade 時に認証トークンを要求してください。
  • Native Messaging ホストは、デバッグログや書式化されていない出力を標準出力(stdout)に絶対に書き込んではいけません。フレーム化されていない stdout 出力は32ビットの長さプレフィックスを破損させ、接続をクラッシュさせます。ログは stderr に送信してください。
  • Native Messaging ホストから Chrome に送信するメッセージは、厳密に1 MBまでに制限されています。1 MBを超えると、プロセスはただちに終了します。
  • コンテンツスクリプトは、デフォルトで分離されたワールドで実行されます。ページの JS、フレームワーク、window.* グローバルにはアクセスできません。ページの JS にアクセスする場合に限り world: "MAIN" を使用し、その後、postMessage と同一オリジンのトークンを使ってブリッジしてください。
  • 拡張機能オリジンからの fetch には、一致する host_permissions が必要です。コンテンツスクリプトからの fetch はページのオリジンと CORS ルールに従います。特権が必要なリクエストは、chrome.runtime.sendMessage を介してサービスワーカーにルーティングしてください。
  • MV3 の CSP では、拡張機能ページ内のインライン <script>、eval()、new Function()、リモートの実行可能コードが禁止されています。すべてをバンドルし、CDN からスクリプトを読み込まないでください。(例外は manifest.sandbox 内のサンドボックスページのみで、unsafe-eval が許可されています。)
  • 手書きの manifest.json のパスは、ビルド済みの成果物(例:background.js、content.js、popup.html)を指す必要があります。src/*.ts や未ビルドのソースを指定してはいけません。
  • インストール時に <all_urls> や広範なホスト権限を要求すると、ウェブストアの審査が厳しくなります。activeTab と任意のホスト権限の付与を優先してください。

判断ルール

判断項目デフォルト次の場合は再検討
バックグラウンドの状態chrome.storage.session/localトランザクション、大規模なインデックス、バイナリデータ → IndexedDB
定期処理chrome.alarmsリアルタイムストリーム → 再接続とキューを設計
ネットワークの変更declarativeNetRequest読み取り専用の監視 → ノンブロッキングの webRequest
ページデータの取得ホスト権限を使ったサービスワーカーの fetchページのオリジンで十分 → コンテンツスクリプトの fetch
ページの JS へのアクセスペイロードを検証する world: "MAIN" ブリッジDOM のみへのアクセス → ISOLATED ワールドを使用
UI 状態の永続化chrome.storage.sessionブラウザーの再起動後も保持する必要がある → local または sync
ホストへのアクセスactiveTab または任意のホスト権限インストール時のホストアクセスがないと拡張機能が機能しない
サイドパネルとポップアップ常時表示するコンパニオン UI にはサイドパネルクイックアクションや短いフォーム → ポップアップ
オフスクリーンドキュメントサービスワーカーから DOM/キャンバス/クリップボード/オーディオ/Worker を利用ポップアップ/オプションページ/コンテンツスクリプトで対応できる → 使用しない
デスクトップとの通信CSWSH 対策を施したローカル WebSocket(ws://127.0.0.1:<port>)OS との深い統合/エンタープライズ配布/ローカルポートの露出をゼロにする必要がある → chrome.runtime.connectNative

ルーティングの境界

リクエストの内容対応
「Chrome 拡張機能を作る」このスキルを使用し、MV3 を対象にする
「Chrome と Firefox 向けに作る」ここでは Chrome MV3 に限定する。クロスブラウザー層は対象外
「ブラウザーでウェブサイトを自動化する」run-agent-browser に振り分ける
「拡張機能の Playwright テストを書く」拡張機能の起動/読み込みに関する注意事項はここを参照する。より広範な Playwright のテスト作成は、このパックの対象外
「npm に公開する」publish-npm-package に振り分ける
「Chrome ウェブストアに申請する」このスキルを使用し、references/publishing/web-store.md を読む
「エンタープライズポリシーでデプロイする」専用のエンタープライズスキルがない限り対象外

ワークフロー

1. 拡張機能の範囲を決める

次のように尋ねます:「どの拡張機能の画面や機能があり、どの Chrome API が必要で、どの権限を実行時まで先送りできますか?」

  1. 必要な画面や機能を列挙します:ポップアップ、オプションページ、サイドパネル、コンテンツスクリプト、サービスワーカー、オフスクリーンドキュメント、devtools。
  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
  • ポップアップ、オプションページ、サイドパネル、devtools、新しいタブの画面 → references/patterns/ui-surfaces.md
  • 1 回限りのメッセージ、ポート、外部/ネイティブメッセージング、ページブリッジ → references/apis/messaging.md
  • デスクトップとの通信、Raycast Companion、Native Messaging → references/patterns/desktop-ipc.md
  • chrome.storage の領域、クォータ、型付きラッパー、移行 → references/apis/storage.md
  • タブ、スクリプティング、アラーム、DNR、サイドパネル、オフスクリーン、ランタイム → references/apis/core-apis.md
  • Manifest、権限、MV2 の移行に関する判断は、この SKILL.md の固定デフォルトとガードレールで扱います。

境界を越えるすべてのペイロードを検証します。対象は、メッセージ、ストレージの読み取り値、外部 API の応答、MAIN ワールドブリッジのデータです。

4. ビルド成果物を検証する

次の点を確認します。「Chrome でこのフォルダーをそのまま読み込めますか? また、manifest 内のパスはすべて存在しますか?」

skill ディレクトリから、ビルドフォルダーを対象に実行します。

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 → 「パッケージ化されていない拡張機能を読み込む」から、ビルド成果物を手動で読み込みます。
  • 拡張機能のページからサービスワーカーを調べ、アイドル状態への移行と再起動のサイクルを実行します。
  • 許可された URL と許可されていない URL で、コンテンツスクリプトの注入をテストします。
  • ホストへの呼び出し前に、実行時の権限リクエスト UX(chrome.permissions.request)を確認します。

拡張機能固有のテストについては references/testing/testing-guide.md を、サービスワーカー、ポップアップ、コンテンツスクリプト、権限、ストレージのデバッグについては references/testing/debugging.md を読んでください。

6. Web Store 審査用にパッケージ化する

次の点を確認します。「審査担当者は、単一の目的、各権限が必要な理由、データの使用方法、リモートコードに関する方針を、それぞれ一文で説明できますか?」

  1. 本番用の出力をビルドします。
  2. その本番ビルドに対して、同梱された両方のスクリプトを実行します。
  3. zip 化する前に不要なファイルを除去します。ソースマップ(意図的に同梱する場合を除く)、テスト、.DS_Store、__MACOSX、フレームワークのキャッシュが対象です。
  4. ビルド成果物のフォルダー内から zip を作成します(manifest.json が zip のルートに配置されるようにします)。
  5. 次の項目を準備します。プライバシーに関する取り組み、権限ごとの正当な理由、リモートコードの開示、データ使用の認証、審査担当者向けのテスト手順。
  6. 提出前に references/publishing/web-store.md を読んでください。

最小限のビルド証跡

作業を終了する前に、タスクに応じた証跡をそろえます。

タスク証跡
新しいスキャフォールドビルド成果物のパス + check-mv3-manifest.sh の結果
機能の変更関連するユニット/統合テスト + Chrome の動作を変更した場合は手動読み込みの記録
manifest/権限の変更check-mv3-manifest.sh の結果 + 権限の正当な理由
コンテンツスクリプトの変更許可 URL への注入結果 + 許可されていない URL への注入結果
サービスワーカーの変更再起動時の耐性に関する記録、または明示的な「未テスト」の注記
パッケージ/Web Store の作業preflight-extension.sh の結果 + zip のパス + 審査担当者向けの注記

出力要件

最終報告には次の項目を含めます。

  • 読み込んだビルドディレクトリ
  • zip のパス(パッケージ化した場合)
  • 手動テストを行った場合は、手動読み込みに使用した Chrome のバージョン
  • 権限の概要とホスト権限の正当な理由
  • Web Store ポリシーへの準拠状況:単一の目的、データ使用、リモートコード、MV3 への準拠
  • 実行したスクリプト/テストと、その失敗
  • 残っている手動確認事項についての審査担当者向け注記

ガードレール

  • 新しい作業で Manifest V2 を生成したり、そのまま維持したりしてはいけません。
  • フレームワークが読み込み可能なコードを明示的に出力する場合を除き、Chrome に src/ を読み込ませてはいけません。
  • サービスワーカー内のモジュールスコープのグローバル変数に、永続化が必要な状態を保持してはいけません。
  • サービスワーカーを存続させるために setTimeout/setInterval に依存してはいけません。
  • MV3 で通常のネットワーク変更を行うために、ブロッキング型の webRequest を使用してはいけません。
  • 機能レベルの正当な理由と、より範囲の狭い代替手段の記録がない限り、<all_urls> をリクエストしてはいけません。
  • 認証されていないコンテンツスクリプトのメッセージを介して、任意のバックグラウンド fetch を公開してはいけません。
  • リモートの実行可能コードや、宣言されていないリモートコードの動作を同梱してはいけません。
  • 完了を報告する前に、ビルド成果物のパスを manifest.json と照合して、必ず検証します。
  • 各権限について、一文で説明できるようにします。

要点

MV3では、サービスワーカーの状態の消失、リスナーの登録の遅れ、タイマーに依存したスケジューリング、隔離されたワールドによる予期しない動作、広すぎる権限、ビルド済みの出力ではなくsrc/を出荷するといった同じ過ちが繰り返し問題になります。固定されたデフォルトを適用し、詳細は参照資料に誘導し、ビルド済みフォルダーに対して同梱のスクリプトを実行して、レビューに適した証拠を用意してください。

コメント