Corredor

ウェブ、プログラミングの勉強メモ。

Chrome 拡張機能のベースを作ってみる

自分がよく見るページにちょっとした加工をしてみたくて、Tampermonkey とかでユーザスクリプトを書いても良かったんだけど、試しに Chrome 拡張機能を自作してみたので、その時の実装を基に、ベースとなるファイルを載せておく。

自作の拡張機能を使うための準備

Chrome の「拡張機能」ページ chrome://extenions を開き、右上の「デベロッパーモード」を有効にする。

拡張機能を構成するファイルを用意する

まずは黙って以下の2ファイルを適当な作業ディレクトリに置く。

  • manifest.json
{
  "manifest_version": 2,
  "name": "my-extension",
  "version": "0.0.0",
  "description": "自作拡張機能",
  "browser_action": {
    "default_title": "My Extension"
  },
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "js": [
        "main.js"
      ]
    }
  ],
  "permissions": [
    "activeTab"
  ]
}
  • main.js
(() => {
  window.addEventListener('load', () => {
    console.log('Hello World');
  });
})();

自作の拡張機能をインストールする

Chrome の拡張機能ページにある「パッケージ化されていない拡張機能を読み込む」より、先程の2ファイルを置いた作業ディレクトリを選択する。

動いているか確かめる

拡張機能をインストールして有効にした後、開発者ツールを開いた状態で任意のページを開いてみる。「コンソール」に「Hello World」と表示されれば、main.js の内容が実行されている = manifest.json の内容に問題がなく、拡張機能として正常に動作している、と分かる。

manifest.json の書式について

簡単にまとめ。

  • namedescriptiondefault_title あたりを好きに直せば OK
  • manifest_version は本稿執筆時点で 2 固定
  • browser_action : 拡張機能の種類が大きく2つ、ブラウザ・アクションとページ・アクションというのが存在する。ウィンドウ右上に並ぶ拡張機能のアイコンをページによって無効にしたい場合はページアクション page_action を使う
  • content_scripts : 指定のページで自動的に実行されるスクリプトを定義する。ココが今回のメイン
  • matches はこのスクリプトを適用したい URL を指定できる。上の例では全ページに適用するようにした
  • js に読み込みたいファイルを配列で書いていく。複数書けるので、jquery を読み込んでから main.js を読み込む、みたいなこともできる
  • js と同じノリで css というプロパティを用意すれば CSS ファイルを適用したりもできる

main.js でやっていること

今回の main.js でやっていることは拡張機能はあまり関係なく、window.onload イベントを追加する即時関数を書いただけ。後はこの中で document.querySelector() とかして、読み込んだページを操作しても良いし、別のライブラリを読み込んであればそれを使ったりもできる。

ライブラリを簡単に読み込むなら

外部ライブラリを簡単に読み込むなら、昔ながらの Browserify を使うのが手軽だろうか。Browserify はグローバルインストールしても良いし、package.json を作ってローカルインストールしておいても良い。

window.buffer = require('buffer');
window.iconv = require('iconv-lite');

例えばこんなファイル ./src/bundle.src.js を作っておいて、

$ browserify ./src/bundle.js > ./dist/bundle.js

などとしてブラウザでも読めるように変換。manifest.jsonjs プロパティの配列に "./dist/bundle.js" を追加してやれば、main.js ファイル内では window.bufferwindow.iconv が使えるようになる、というワケ。コレで文字化けしたページを置換したりできるだろう。

  • main.js の例
(() => {
  window.addEventListener('load', () => {
    // 指定のクラス内のテキストを再エンコーディングする
    document.querySelectorAll('.garbled-text').forEach((elem) => {
      const input = elem.innerText;
      const encoded = window.iconv.encode(input, 'ISO-8859-1');
      const decoded = window.iconv.decode(window.buffer.Buffer.from(encoded), 'UTF-8');
      elem.innerText = decoded;
    });
  });
})();

ファイルの変更が反映されない

拡張機能を作成中、main.jsmanifest.json に変更を加えても、Chrome 上には反映されない。そんな時は、当該拡張機能のページを開いて「オン」「オフ」を切り替えてやれば強制的に反映させられる。

既存の拡張機能のソースコードを見る

こうして作ってみると、Chrome 拡張機能は JavaScript がベースなのが分かった。ということは、公開されている拡張機能の実装を見るのも難しくはなさそうだ。

インストール済の Chrome 拡張機能は以下のディレクトリに格納されている。

  • Mac : /Users/【ユーザ名】/Library/Application Support/Google/Chrome/Default/Extensions
  • Windows : C:\Users\【ユーザ名】\AppData\Local\Google\Chrome\User Data\Default\Extensions

配下のディレクトリは ID 別のディレクトリになっているので、Chrome Web Store の URL などで ID を確認して開けば良い。

以上

今回 Chrome Web Store での公開までは試さなかったが、少なくとも個人環境で作って動かすのは簡単だった。

参考文献

Chrome・Chromebook定番「拡張機能」セレクションズ (NextPublishing)

Chrome・Chromebook定番「拡張機能」セレクションズ (NextPublishing)