くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Chrome拡張機能を作ってみる | 2. 登場人物編

とりあえず、Hello Worldできたので、
登場人物やディレクトリ構成とかを調べてみる(*´ω`*)

前回の記事はこちら。

www.memory-lovers.blog

最小は2つのファイル

./
  popup.html    ... 拡張機能をクリックしたときに表示するHTML
  manifest.json ... 拡張機能の設定情報

拡張機能をクリックした際に表示するpopup.htmlというファイル名も含め、
manifest.jsonに書いておく形。

他に、Service Worker(background.js)Content Scripts(contentscript.js)を含め、
以下のような関係になっているっぽい。

ChromeExtensionArchitecture

基本的な構成要素

基本的には以下の3つ

  • manifest.json
  • UI elements ... (popup.html / popup.js)
  • Service Worker ... (background.js)
  • Content Scripts ... (contentscript.js)

それぞれの違いは以下の通り。

  • UI elements
    • 拡張機能のボタンをクリック時のポップアップ
    • DOM操作、常駐起動は不可。イベントのモニター一部可?
  • Service Worker
    • バックグラウンドで常駐するスクリプト
    • 常駐起動とブラウザイベントのモニターは可。DOM操作不可
  • Content Scripts
    • 表示しているWebページに挿入したり、他の要素から起動できるスクリプト
    • DOM操作は可。常駐起動とブラウザイベントのモニターは不可。

manifest.json

拡張機能の名前やバージョンやアイコンなど、
拡張機能に関する情報を書いておくjson

最低限、以下が必要。

{
  "manifest_version": 3,
  "name": "chrome-extension-sample",
  "version": "0.0.1",
  "action": {
    "default_popup": "popup.html"
  }
}

UI elements

拡張機能のボタンをクリックした際に表示するポップアップを含め、
拡張機能を操作するUI全般が含まれる。

ほかにも、Tooltip/Badge/Context Menu/Keybord Sortcutなどなど

Service Worker

バックグラウンドに常駐できるサービスワーカー。
ブラウザなどのイベントをモニターしたり、
index.htmlなどにメッセージを送ったりできる。

ただ、ページの情報を読み取ったり、変更したりすることはできないので、
Content Scriptsにメッセージを送って、操作してもらう。

manifest.jsonservice_workerを追加すれば利用できる。
また、使うChrome APIあわせて、permissionsも追加する。

{
  background: {
    service_worker: "background.js",
    type: "module"
  },
  permissions: ["storage"]
}

Content Scripts

ページの情報を読み取ったり、変更したりする場合は、こっち。
対象のページに挿入したり、Service Workerなどから呼び出しできる。

対象のページに自動挿入(Inject with static declarations)

manifest.jsonにこんな感じで書いておけば、
matchesと一致したjs/cssを挿入してくれる。

{
  content_scripts: [
    {
      matches: ["https://*.example.com/*"],
      css: ["foo.css"],
      js: ["content_script.js"]
    }
  ]
}
他の要素から呼び出す(Inject programmatically)

必要なときにだけ、呼び出すこともできる。

ブラウザがクリックされたときに、
Service Worker(background.js)でクリックイベントを検知して、
Content Scripts(content-script.js)を呼び出して、DOMを操作する例。

// background.js:
chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    files: ['content-script.js']
  });
});

// content-script.js
document.body.style.backgroundColor = 'orange';

その他

プロジェクト構成のサンプル

プロジェクト構成のサンプルがあった。

Project Structure

Iconを設定する

必要なアイコンのサイズは以下の通り。形式はPNGがよいっぽい。

Icon Size Icon Use
16x16 拡張機能で表示されるアイコン
32x32 Windowsで必要なサイズ
48x48 拡張機能の管理画面で表示されるサイズ
128x128 Chrome Web Storeのインストール画面で表示されるサイズ

用意したら、manifest.jsonに書いておけばOK

{
  "name": "My Awesome Extension",
  ...
  "action": {
    "default_icon": {
      "16": "icon_16.png",
      "32": "icon_32.png"
    }
  }
  "icons": {
    "16": "icon_16.png",
    "32": "icon_32.png",
    "48": "icon_48.png",
    "128": "icon_128.png"
  }
  ...
}

TypeScriptで開発する

Chrome APIの型定義が提供されている。

$ npm i -D chrome-types

もろもろ

参考にしたサイト様