初めてChromeExtension(Chrome拡張機能)を作ってみた

今回作ったもの

github.com

無事、Chromeウェブストアに公開されました!

chrome.google.com

何を作ったか

Githubでプロジェクトを進めて行くと、必ずコードレビューが発生してきます。

このとき、1PRで修正されたファイルが少なければ特に問題ないのですが、自動生成ファイルなどが含まれる、大量差分のPRを見るときに大変なのがこちら。

そう。Filesタブにある大量のファイルリストです。

Diff表示の方は個別表示/非表示や、一括表示/非表示を行うことができますが、サイドメニューにあるリストはできないのです。

(あ、Diff表示の一括表示/非表示は 「alt(macならoption)+diff表示/非表示ボタン」でできます。)

そこで、サイドメニューのファイルリスト + Diff表示部分の一括表示/非表示を行う専用ボタンを表示させる、拡張機能を作ってみました。

(使われると思っていませんが、まだExtensionを作ったことがなかったので、勉強がてら作ってみました。)

実装紹介

拡張機能用のディレクトリ構成とかは、特になさそうだったので、自分は以下のようにしておきました。

├── src
│   ├── assets
│   │   ├── icon-128.png
│   │   ├── icon-48.png
│   │   ├── icon-16.png
│   │   ├── jquery-3.6.0.min.js
│   │   └── usage.gif
│   ├── templates
│   │   ├── buttons.css
│   │   └── buttons.html
│   └── index.js
└── manifest.json

重要なのは manifest.json と実際に処理を書く index.js です。

今回の拡張機能では、拡張機能を実装する上で使える機能のごくごく一部分しか使えていないので、もっと詳しいことを知りたい方は、公式サイトをご覧ください。

developer.chrome.com

manifest.jsonの中身はこんな感じ。正しいか正しくないかは分からないですが、テストして拡張機能自体は動いてたから問題ないのかなと...

{
  "name": "SmartPullRequest",
  "version": "1.0.0",
  "manifest_version": 3,
  "description": "PullRequestのFilesタブの操作性を改善します。",
  "icons": {
    "16": "src/assets/icon-16.png",
    "48": "src/assets/icon-48.png",
    "128": "src/assets/icon-128.png"
  },
  "permissions": [],
  "content_scripts": [
    {
      "matches": ["https://github.com/*"],
      "js": ["src/assets/jquery-3.6.0.min.js"],
      "run_at": "document_start"
    },
    {
      "matches": ["https://github.com/*"],
      "js": ["src/index.js"],
      "css": ["src/templates/buttons.css"],
      "run_at": "document_end",
      "all_frames": true
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["src/templates/buttons.html"],
      "matches": ["https://github.com/*"]
    }
  ]
}

manifest_versionv3 を使うと、審査時間も短縮されるみたいです。公式がそう言ってるので間違いないはず。

ざっと重要な項目だけ触れておくと

  • permissions
  • content_scripts
  • web_accessible_resources

は抑えておきたいところですね。

permissions

これはその名の通り、拡張機能に付与する権限を指定します。権限を要求できるリストは以下にまとまっています。

developer.chrome.com

今回の拡張機能では、特にユーザーから権限を貰う必要がなかったため、空配列となっています。

content_scripts

このセクションでは、どのファイルに記述された機能(処理)をどのサイト・どのタイミングで実行するか。などの、拡張機能根幹の設定を行います。

developer.chrome.com

私の場合はjQueryを使いたかったので、documentの読み込みが始まった時点で先にloadしておき、documentの読み込みが終わった時点で、拡張機能本体を読み込ませるようにしました。

web_accessible_resources

そう。一番こいつに時間を取られました。このセクションでは、拡張機能側から自前のhtmlやimgなどのリソースを読み込むために、設定を記述するセクションです。

developer.chrome.com

index.js で画面にinjectしたいhtmlが書かれているファイルをloadしてきて、突っ込むという処理です。

なんの設定もしなくても、普通に読み込めるだろうと思ってたら全く読み込めず、こいつの存在を知るまで時間を溶かしてました。気をつけましょう。

$.get(chrome.runtime.getURL("src/templates/buttons.html"), function (data) {
  console.log(data);
  const parentNode = $(".subnav-search");
  console.log(parentNode);
  $(parentNode).after(data);
});

で、なんやかんやありましたが、無事申請中です。こうやってみんな作ってるんだなと知ることができました。

Tips

開発中の拡張機能をどうテストするかですが、まずはじめにChromeの拡張機能画面を開いて、デベロッパーモードを「ON」にする必要があります。

ONにすると、上からにゅっとメニューバーが表示されるので、「パッケージ化されていない拡張機能を読み込む」を選択します。

そうすると、フォルダ選択するウィンドウが開くので、manifest.json が置かれているフォルダを選択します。

実際にテストする際には、manifest.jsonが必要なので、先に作成しておきましょう。

すると、拡張機能のところに今作ってる拡張機能が表示されます。

パッケージ化されていない拡張機能を読み込むメリットは、わざわざ更新したものをパッケージ化して、再読み込みさせる必要がないというところです。

参照しているフォルダの処理を書き換え保存したら、読み込んだ拡張機能カードに表示されている、ローディングボタンをクリックします。

そうすると、参照しているフォルダの最新情報で拡張機能が更新されます。これを繰り返すことで開発を簡単に行うことができます。

おわり

簡単な拡張機能を試しで作ってみて、ぜひGithubに公開してみましょう!