wataメモ

日々のメモをつらつらと書くだけ

Chrome Extensionを作ってみた

 前から1回作ってみようと考えてはいたのだが、優先順位が中々上がらず今まで着手していなかった。そんな中manifestのバージョンが上がり、Content Security Policy (CSP)が今後主流になる(したい)などを聞きいい機会だと作って見ることにした。

 まずはどういった作りなのかを把握するために本家のドキュメントへ。非公式の日本語訳があるので、日本語が良い方はこちらも参照してください。

 なんとなくChromeのExtensionは使っていて、アドレスバーの中に出るタイプとアイコンとしてアドレスバーの隣に出るのは知っていた。アドレスバーの中のタイプはpage actionsと呼ばれていて、特定のページでアイコンを表示、非表示するのに適しているとのこと。そしてもう1つのアドレスバーの隣に出るアイコンはbrowser actionsと呼ばれている。どちらもツールチップ、バッジやポップアップをつけることが出来る。

 作り方としては以下の流れになる。

  1. マニフェストを作成
  2. アイコン、HTMLやJavaScriptを作成
  3. 拡張機能デベロッパー モードにする
  4. 「パッケージ化されていない拡張機能を読み込む...」から2で作ったファイルのディレクトリを指定し読み込む
  5. 修正したらリロードで反映しながら開発していく

 必要な技術要素としてはマニフェストファイルを書くためにJSONとHTMLとJavaScriptのみ。イメージとしてはWeb画面を作っている感じなので今までのWebサイトの構築のノウハウをそのまま使うことが出来る。ディレクトリ構成を作って画像やらを入れておけばアイコンとして使えたりもする。

 マニフェストファイルは作りたいExtensionの設定を以下の様に書いていく。

{
  "name": "test",     // 拡張機能
  "version": "0.0.1", // バージョン:公開する時に必ず増やして行かなければ行けない値
  "icons": { "48": "img/icon-on-48.png",
            "128": "img/icon-on-128.png" },
  "description": "sample extension", // 拡張機能の説明
  "background": {     // バックグラウンドで動く処理(Chrome起動時に呼ばれる)
    "scripts": [
      "chrome_ex_oauthsimple.js",
      "chrome_ex_oauth.js",
      "jquery.min.js",
      "background.js"
    ]
  },
  "browser_action": { // browser actionsを作る場合に必要な指定
    "default_title": "",
    "default_icon": "img/icon-off-19.png",
    "default_popup": "popup.html" // 押した時にポップアップメニューを表示する場合は指定
  },
  "manifest_version": 2, // マニフェストのバージョン、そろそろ1はサポートされなくなるので2を指定
  "web_accessible_resources": [ // セキュリティの為、Ajax等で外部リソースにアクセス出来るファイルを指定しなければいけない
    "chrome_ex_oauth.html",
    "popup.html"
  ]
}

 アイコンの画像と指定したHTMLとJavaScriptを書くだけ。JavaScriptにはAPIが提供されていて、ブラウザに対して色々な処理が出来る様になっている。当然HTMLとJavaScriptなのでデバッグもブラウザで出来る。ポップアップ等のHTMLを含む場合は「chrome-extension://[ID]/[デバッグ対象HTML]」でアクセスしてデバッグする ことが出来る。「ID」はExtensionとして追加しないと発番されないので、「拡張機能」でデベロッパー モードにして自分の作成したExtensionを追加する。

f:id:wata_htn:20120829143428p:plain

 バックグラウンドで動く処理もあるのでそれをデバッグするにはchrome://chrome/extensions/からデベロッパーツールを起動する形になる。

f:id:wata_htn:20120829142638p:plain

 APIは基本的には値をreturnするのではなく、結果を非同期でコールバック関数の引数に渡す形式になっている。Cookie情報を取得する関数もコールバックなので記述が若干面倒だと感じた。単純にCookieの値を取得して何か処理を行いたいだけなのに、わざわざコールバック関数を作ってそこで処理しないと行けないためだ。コールバックにしている思想としては重い処理で処理をブロックしないように非同期で行う為だとは思うのだが・・・。

 JavaScriptはHTMLの中にscriptタグを作ってインラインに書くことは出来ず、必ず別のjsファイルとして分けることが必須となっている。ちょっと面倒だがセキュリティ観点の為だそうだ。

 Extensionを公開するにはChrome ウェブストアのデベロッパー登録($5.00)が必要。そして「デベロッパーダッシュボード」からExtensionを登録する。Extensionに必要なファイルを固めたのをアップロードするのだが、Chromeで「拡張機能のパッケージ化」したファイルでは拡張子がzipではないのでダメだと言われた。なので拡張子をzipに変えてアップロードした。

f:id:wata_htn:20120829142714p:plain

 そして通常のExtension同様にChrome ウェブストアからインストールすることも出来る。一般公開の前にテスターに公開するというモードもあるので、開発時はこちらを利用するのがいいのかもしれない。ただ、テスターのみ公開でも更新する時はバージョン番号はやはり増やさないと行けないので注意。

f:id:wata_htn:20120829142729p:plain

 今回実装してみて、Extensionの実装によってはChromeが遅くなるというのを理解できた。自分でsetTimeout等でぐるぐるバックグラウンドで動かれたり、リクエストを投げまくったりされてもChrome側で防ぎようが無い為だ。今後はBackground PagesではなくEvent Pagesを使うように推奨されている。必要な時にリソースを確保し、不要な場合は破棄するようだ。このあたりの活動も重くなる対策の1つだろう。

  基本APIを見ながらJavaScriptを書くだけなので、非常に簡単に作ることは出来る。だがやはりコールバック地獄になるのは何とかしたいところだ。ただ、逆を言えばそれぐらいで通常のWeb開発者が簡単にChrome Extensionを作ることが出来るのは魅力ではないだろうか。