アーキテクチャの概要

拡張機能は、ウェブ プラットフォームで使用される HTML、CSS、JavaScript、画像などのファイルを ZIP にまとめたもので、Google Chrome のブラウジング環境をカスタマイズします。拡張機能はウェブ テクノロジーを使用して構築されており、ブラウザがオープンウェブに提供するのと同じ API を使用できます。

拡張機能にはさまざまな機能があります。ユーザーが表示して操作するウェブ コンテンツを変更したり、ブラウザ自体の動作を拡張、変更したりできます。

拡張機能は、Chrome ブラウザをよりパーソナライズされたブラウザにするためのゲートウェイであるとお考えください。

拡張ファイル

拡張機能はファイルの種類とディレクトリの量によって異なりますが、すべての拡張機能に [manifest][docs-manifest] が必要です。基本的かつ有用な拡張機能には、マニフェストとそのツールバー アイコンのみで構成されるものもあります。

manifest.json というマニフェスト ファイルには、最も重要なファイルや拡張機能が使用する機能など、拡張機能に関する情報がブラウザに渡されます。

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

拡張機能では、ブラウザのツールバーにアイコンを配置する必要があります。ツールバー アイコンによって簡単にアクセスでき、どの拡張機能がインストールされているかをユーザーは把握できます。ほとんどのユーザーは、ポップアップを使用する拡張機能で、このアイコンをクリックして操作します。

この Google Mail Checker 拡張機能では、ブラウザ アクションを使用します。

Google Mail Checker 拡張機能のスクリーンショット

この Mappy 拡張機能は、ページ アクションコンテンツ スクリプトを使用します。

Mappy 拡張機能のスクリーンショット

ファイルの参照

拡張機能のファイルは、通常の HTML ページのファイルと同様に、相対 URL を使用して参照できます。

<img src="images/my_image.png">

また、各ファイルには絶対 URL を使用してアクセスすることもできます。

chrome-extension://EXTENSION_ID/PATH_TO_FILE

絶対 URL の EXTENSION_ID は、拡張機能システムが各拡張機能に対して生成する一意の識別子です。読み込まれたすべての拡張機能の ID は、URL chrome://extensions で確認できます。PATH_TO_FILE は、拡張機能の最上位フォルダの下にあるファイルの場所であり、相対 URL と一致します。

拡張機能 ID は、パッケージ化されていない拡張機能で作業している最中に変更される可能性があります。具体的には、拡張機能が別のディレクトリから読み込まれると、パッケージ化されていない拡張機能の ID は変更されます。拡張機能がパッケージ化されると、この ID は再度変更されます。拡張機能のコードが絶対 URL に依存している場合は、chrome.runtime.getURL() メソッドを使用して、開発中に ID のハードコードを回避できます。

アーキテクチャ

拡張機能のアーキテクチャはその機能に依存しますが、堅牢な拡張機能の多くは、次のような複数のコンポーネントを含みます。

バックグラウンド スクリプト

バックグラウンド スクリプトは、拡張機能のイベント ハンドラです。拡張機能にとって重要なブラウザ イベントのリスナーが含まれています。イベントが発生し、命令されたロジックが実行されるまで、休止状態になります。有効なバックグラウンド スクリプトは、必要な場合にのみ読み込まれ、アイドル状態になるとアンロードされます。

UI 要素

拡張機能のユーザー インターフェースは、目的を絞って最小限のものにします。UI はブラウジング エクスペリエンスを妨げずにカスタマイズまたは強化する必要があります。ほとんどの拡張機能にはブラウザ アクションページ アクションがありますが、コンテキスト メニューアドレスバーの使用、キーボード ショートカットの作成など、他の形式の UI も含めることができます。

ポップアップなどの拡張機能 UI ページには、JavaScript ロジックを使用して通常の HTML ページを含めることができます。また、拡張機能 tabs.create または window.open() を呼び出して、拡張機能に存在する追加の HTML ファイルを表示することもできます。

ページ アクションとポップアップを使用する拡張機能では、宣言型コンテンツ API を使用して、ポップアップがユーザーに表示される場合について、バックグラウンド スクリプトにルールを設定できます。条件が満たされると、バックグラウンド スクリプトはポップアップと通信して、アイコンをユーザーにクリックできるようにします。

ポップアップを表示しているページ アクションが表示されたブラウザ ウィンドウ

コンテンツ スクリプト

ウェブページの読み取りや書き込みを行う拡張機能では、コンテンツ スクリプトを利用します。コンテンツ スクリプトには、ブラウザに読み込まれたページのコンテキストで実行される JavaScript が含まれています。コンテンツ スクリプトは、ブラウザがアクセスするウェブページの DOM を読み取って変更します。

ページ アクションとコンテンツ スクリプトが表示されているブラウザ ウィンドウ

コンテンツ スクリプトは、storage API を使用してメッセージを交換し、値を保存することで、親拡張機能と通信できます。

コンテンツ スクリプトと親拡張機能間の通信パスを表示します

オプション ページ

拡張機能で Chrome ブラウザをカスタマイズできるのと同様に、オプション ページで拡張機能をカスタマイズできます。オプションを使用して機能を有効にし、ユーザーがニーズに関連する機能を選択できるようにします。

Chrome API の使用

拡張機能は、ウェブページと同じ API にアクセスできるだけでなく、ブラウザと緊密に統合する拡張機能固有の API を使用することもできます。拡張機能とウェブページはどちらも標準の window.open() メソッドにアクセスして URL を開くことができますが、拡張機能は Chrome API の tabs.create メソッドを使用して、URL を表示するウィンドウを指定できます。

非同期メソッドと同期メソッド

ほとんどの Chrome API メソッドは非同期で、処理の完了を待たずにすぐに戻ります。拡張機能が非同期処理の結果を知る必要がある場合は、メソッドにコールバック関数を渡すことができます。コールバックは後で(場合によってはメソッドが返された後に)実行されます。

拡張機能は、ユーザーが現在選択されているタブを新しい URL に移動する必要がある場合は、現在のタブの ID を取得してから、そのタブのアドレスを新しい URL に更新する必要があります。

tabs.query メソッドが同期の場合、次のようになります。

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

query() が非同期のため、このアプローチは失敗します。処理の完了を待たずに戻り、値は返しません。署名でコールバック パラメータが使用可能な場合、メソッドは非同期になります。

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

タブを正しくクエリして URL を更新するには、拡張機能でコールバック パラメータを使用する必要があります。

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

上記のコードでは、行は 1、4、2 の順に実行されます。query() に指定されたコールバック関数が呼び出されて、2 行目を実行しますが、これは現在選択されているタブに関する情報が利用可能になった後でのみです。これは、query() が返されると発生します。update() は非同期ですが、拡張機能は更新の結果について何もしないため、コールバック パラメータを使用しません。

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

このメソッドは同期的に URL を string として返し、その他の非同期処理を行いません。

詳細

詳しくは、Chrome API リファレンス ドキュメントと次の動画をご覧ください。

ページ間の通信

拡張機能のさまざまなコンポーネントが相互に通信する必要が生じることはよくあります。異なる HTML ページは、getViews()getBackgroundPage() などの chrome.extension メソッドを使用することで相互に検出できます。ページから他の拡張ページへの参照を持つと、最初の拡張ページは他のページの関数を呼び出して DOM を操作できます。また、拡張機能のすべてのコンポーネントは、storage API を使用して保存された値にアクセスし、メッセージの受け渡しを介して通信できます。

データの保存とシークレット モード

拡張機能では、storage API または HTML5 web storage API を使用するか、データの保存につながるサーバー リクエストを行って、データを保存できます。拡張機能でなんらかの保存が必要な場合は、まずシークレット ウィンドウからのものかどうかを確認します。デフォルトでは、拡張機能はシークレット ウィンドウでは実行されません。

シークレット モード: ウィンドウにすべてのトラックが留まることが保証されます。シークレット ウィンドウのデータを処理する場合、拡張機能はこの約束を尊重する必要があります。拡張機能で通常閲覧履歴が保存される場合は、シークレット ウィンドウの履歴を保存しないでください。ただし、拡張機能は、シークレット モードかどうかにかかわらず、任意のウィンドウから設定を保存できます。

ウィンドウがシークレット モードかどうかを検出するには、関連する tabs.Tab オブジェクトまたは windows.Window オブジェクトの incognito プロパティを確認します。

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

次のステップ

概要を読み、スタートガイド チュートリアルを修了すると、独自の拡張機能の作成を開始できるようになります。次のリソースでカスタム Chrome についてさらに詳しく学びましょう。

  • 拡張機能のデバッグに使用できるオプションについては、デバッグ チュートリアルをご覧ください。
  • Chrome 拡張機能では、オープンウェブで提供されている以上の強力な API にアクセスできます。chrome.* API のドキュメントでは、各 API について説明しています。
  • 拡張機能の開発の概要には、高度な拡張機能の作成に関連するドキュメントへの追加リンクが多数含まれています。