ホーム自己紹介ブログ
NO.71
DATE2022. 01. 16

Chrome拡張機能(Manifest V3)の開発で知ったこと

皆さん、Chrome 拡張機能をご存知ですか? Chrome 拡張機能は、Chrome ブラウザをカスタマイズするための機能です。

私は、Chrome 拡張機能を過去(数年前)に 2 つ作っていて、その当時は、Chrome 拡張機能の仕様である Manifest V2 に従っていました。 そして、今再び、Chrome 拡張機能で作りたいものができたので、久々に作ろうと決意しました。 作ろうと思ったものの、どうやら今の Chrome 拡張機能の仕様は Manifest V3 を推奨しているようです。 そこで、今回、開発した際に知ったことをまとめようと思います。

ちなみに、実際に作ったものは次のものです。

  • https://github.com/silverbirder/chrome-extensions-tiktok-scraping-downloader
    • 上にある図が、この Chrome 拡張機能の設計図になります

※ Chrome 拡張機能の概要について詳しく知りたい方は、What are extensions? - Chrome Developersをご覧ください。

Chrome Extensions Components

Chrome 拡張機能は、主に次の 4 つのコンポーネントが存在します。

  • Background Scripts
    • サービスワーカー上で動作し、ブラウザ上のイベント駆動(ページ遷移やブックマーク差所など)で反応します。
    • manifestの backgroundフィールドで設定します。
  • Content Scripts
    • Web ページのコンテキスト上で動作し、DOM へアクセスできます。
    • manifestの content_scriptsフィールドで設定します。
  • UI Elements
    • URL バーの右側にあるボタンを押した(Action)際に表示される UI です。
    • ブラウザ体験を損なわさない最低限の機能だけの提供を推奨されています。
    • manifestの actionフィールドで設定します。
  • Options Page
    • Chrome 拡張機能アイコンを右クリックして、オプションを選択すると表示される UI です。
    • Chrome 拡張機能をカスタマイズしたい設定ページに使います。
    • manifestの options_pageフィールドで設定します。

私なりに、これらのコンポーネントの使い分けを考えると、次になります。

  • DOM へアクセスする必要がある
    • Content Scripts を使う
  • ページに依存しない処理がある
    • Background Scripts を使う
  • 環境変数の設定が必要
    • Option Page

UI Elements は、基本的に必要ないのかなと思いました。

Debug

デバッグって、どうやるんでしょうか。

  • Debugging extensions - Chrome Developers

こちらにやり方が書いてありました。 私なりに解釈した結果、次の 2 つで使い分けるのかなと思います。


  • ① そもそも、Chrome 拡張機能がロードできない場合

manifest.json ファイルに記述で誤りがあるなどで、Chrome 拡張機能がロードできない場面があります。 そういうときは、次の手順を実行します。

  1. chrome://extensions へアクセス
  2. 次の図にあるような ERROR ボタンをクリック
chrome extensions debug
chrome extensions debug

恐らく、何かしらエラーメッセージが出力されていると思います。 それを解決しましょう。


  • ② ① 以外の場合

Chrome 拡張機能はロードできるが、期待通りに動作しない場面があると思います。 そういうときは、DevTools を開きましょう。

  • Background Scripts の場合
    • chrome://extensions へアクセスし、inspect viewsの右にあるリンクをクリック。(上図)
      • DevTools が開きます。
  • Content Scripts, UI Elements, Options Page の場合
    • UI 上で右クリックして Inspect をクリック
      • DevTools が開きます。

DevTools には、console タブがあるはずです。そこのログメッセージを確認しましょう。

Message Passing

各コンポーネント間で、通信するのは、どうしたら良いのでしょうか。 例えば、Content Scripts から Background Scripts へデータを渡したいときなどです。 次の資料が、参考になります。

  • Message passing - Chrome Developers

資料を読むと、次のようなパターンの通信ができるようです。

  • 各コンポーネント間の通信
    • Background Scripts ⇔ Content Scripts など
  • Chrome 拡張機能間の通信
    • A Chrome 拡張機能 ⇔ B Chrome 拡張機能
    • Chrome 拡張機能の ID を使って通信します
  • Web ページからの通信(Sending messages from web pages)
    • Web ページ ⇔ Chrome 拡張機能のコンポーネント

通信の具体的なコードは、chrome.runtime.sendMessageメソッドを使います。 Background Scripts から Content Scripts へ通信する場合、どの Chrome タブに送信するかchrome.tabs.queryで事前に id を見つけておく必要があります。

また、後で紹介しますが、Web Accessible Resourcesでアクセス可能な Javascript を Web ページへ Inject(document.querySelector('body').append())した場合、その Javascript と Content Scripts の通信は、window.postMessageとwindow.addEventListenerを使いましょう。 chrome.runtimeが使えないので。

Web Accessible Resources

Content Scripts から Web ページの DOM へアクセスできますが、window オブジェクトにある変数へアクセスすることができません。

  • 'javascript - Can the window object be modified from a Chrome extension? - Stack Overflow'

window オブジェクトへアクセスするには、Web Accessible Resources を使う方法があります。

  • Manifest - Web Accessible Resources - Chrome Developers

具体的にコードで説明しましょう。

manifest.json で必要なフィールドの例は、次のとおりです。

{
  "manifest_version": 3,
  "content_scripts": [
    {
      "js": ["content-script.js"],
      "matches": ["https://*/*"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["web_accessible_resources.js"],
      "matches": ["https://*/*"]
    }
  ]
}

Content Scripts と Web Accessible Resources の Javascript は次のとおりです。

// content-script.js
const injectScript = (filePath, tag) => {
  var node = document.getElementsByTagName(tag)[0];
  var script = document.createElement("script");
  script.setAttribute("type", "text/javascript");
  script.setAttribute("src", filePath);
  node.appendChild(script);
};
injectScript(chrome.runtime.getURL("web_accessible_resources.js"), "body");
// web_accessible_resources.js
console.log(window["hoge"]);
// Content Scriptsへ通信する場合は、window.postMessageを使います。

このように、web_accessible_resources.js を Web ページの body タグへ append します。 その web_accessible_resources.js では、window オブジェクトにアクセスすることができます。

chrome.webRequest API

Chrome ブラウザでネットワークトラフィックを監視する Chrome 拡張機能の API があります。 それが、chrome.webRequestです。

  • chrome.webRequest - Chrome Developers

これがあれば、Web ページでどういうリクエストが発生しているか分かるようになります。 manifest.json のフィールドで、host_permissionsの設定が必要です。


サンプルで、Background Scripts のコードを紹介します。 まず、manifest.json の必要なフィールドを書きます。

{
  "manifest_version": 3,
  "host_permissions": ["https://*/*"],
  "background": {
    "service_worker": "background.js"
  }
}

次に、Web ページからリクエストが完了(onCompleted)したイベントを監視するコードを書きます。

// background.js
chrome.webRequest.onCompleted.addListener(
  async (details) => {
    console.log(`request url is ${details.url}`);
  },
  {
    urls: ["https://*/*"],
  },
  ["responseHeaders"] // responseHeadersをdetailsオブジェクトに含めることができます。
);

この details にはリクエストの URL が含まれています。さらに詳しく知りたい人は、こちらをご確認ください。

最後に

Chrome 拡張機能、久々に開発してみると、進化しすぎていてキャッチアップに苦労しました。 私と同じような方の助けになれば、幸いです。

ブラウザ
成果物

-

シェアする

フォローする

次のページ

オミクロン株に感染したので、分かったことを書く

前のページ

Markdownで執筆するなら、WebComponentsが使えるSSG、Rocketがオススメ!

関連する記事

タグ「ブラウザ」の記事

DuckDB WASMとOPFSでGoogleマイアクティビティをブラウザ完結で可視化してみた

DuckDB WASMとOrigin Private File System (OPFS) を組み合わせ、Google マイアクティビティの履歴をブラウザ内に閉じたまま扱えるようにしたときの設計と学びを整理しました。

2025-09-17

開発ツール
ブラウザ
マイクロコピー、マイクロインタラクション、そしてリンク

こんにちは、@silverbirderです。最近、湖県に移住してWebフロントエンドのお仕事をしています。お仕事をしていると、ユーザー体験を良くするためには、大きな改善をせずとも小さな改善だけでも十分な効果があると思い始めました。本記事では、その小さな改善となる、3つのことについて書きたいと思います。

2025-08-27

フロントエンド
ブラウザ
OGPのテキストを任意の行で省略する、lineClampとbudoux

ブログ記事のOGP画像に、ブログタイトルを入れたい場面があります。その際、タイトルが長い場合は複数行に分けたり、省略したりする必要があります。今回は、試してみてよさそうだった2つの方法を紹介します。

2025-02-06

ブラウザ

タグ「成果物」の記事

個人サイトリニューアルの振り返り

個人サイト(ジブンノート)をリニューアルしました。本記事では、個人サイトをリニューアルした際にあった出来事などを振り返りたいと思います。ちなみに、個人サイトは以下のページです。ノート風デザインで、ブログ記事が読めるようになりました!🎉

2026-01-29

成果物
振り返り
個人サイトをリニューアルしました!

個人サイトをリニューアルしました!🎉 https://silverbirder.github.io リニューアルは、今回で6回目です。制作期間は、去年の12月27日から今年の1月28日までの約1ヶ月間です。個人的には最速の開発期間でした。AIの力は偉大ですね。本記事では、個人サイトのリニューアルでこだわったポイントについて紹介します。

2026-01-28

成果物
機能リクエスト投稿サービスを作った

個人開発として、機能リクエスト投稿サービスを作成しました。 サービス名は Fequest で、Feature Request の略です。 Fequest は、プロダクトに対して「この機能を追加してほしい」「ここを改善してほしい」といった要望

2025-12-28

成果物
← ブログ一覧へ