はじめに
記事の内容
仕事でもプライベートでも利用頻度の高いGoogle Cloud(旧称:GCP)を便利に利用するため、プロジェクト毎にコンソールのヘッダカラーを変更できるChrome拡張を作りました。
本番環境だけ色を変えたりできればオペミスが減ってハッピーですよね。作ったのはコレです。
作る上ではこちらを大変参考にさせていただきました。
想定読者
- GCPを便利化するものは作りましたが、記事の内容はGCPと一切関係ありません
- あくまでChrome拡張の入門的なものを読みたい方にオススメです
Chrome拡張
概要
説明するまでもないですが、ブラウザに独自の機能を追加することができる仕組みです。
主にHTML / CSS / JavaScript / 画像を組み合わせて実装します。
manifest.json
Chrome拡張にはmanifest.json
という設定ファイルが必須です。
manifest.json
に、「こういう処理が入ったらfoo.js
を呼び出してね」「ブラウザ右上の拡張機能のアイコン押されたらbar.html
を呼び出してね」といった決まりを書いておくと、その通りにブラウザが解釈し各ファイルを呼び出してくれるようになります。
manifest.json
がChrome拡張の処理のエントリーポイントになっているわけです。重要。
様々なフィールドや用語がありますが、基本を抑える上ではこちらの記事が大変分かりやすかったです🙇♂️
Chrome拡張機能をmanifest v3で開発した簡易記録とハマりポイントの解消方法
manifest.json、v2 or v3問題
manifest.json
の仕様(Chrome拡張の仕様)は今までv2だったのですが、2022年1月以降、Webストアでは新仕様であるv3しか受け付けられなくなりました。
「仕様が変更になりどうなったの?」については、manifest.json
の記述方法が変更になったり、呼び出すことができる機能が制限されたり追加されたりしました。
今後は特段理由がなければv3で作るのが良いと思います。
処理をどこに書くか
Chrome拡張の処理は主にBackground Script
かContent Script
のどちらかに書きます。
manifest.json
で言うところのservice_worker
かcontent_scripts
に指定するjsファイルです。
content_scripts
は、
- 特定のWebサイトと紐付き、かつ、DOM等に触ることもできるため、Webページ自体を弄ることができる
- 常駐せず、Webサイトが読み込まれるたびに一度呼び出される
- 一部の
chrome
APIにしかアクセスできない(ドキュメント)
といった特徴があります。
一方service_worker
は、
- バックグラウンドに常駐し、キー押下等のイベントに合わせて発火させることが可能
-
chrome
のAPIについて、そのほとんどを利用することができる - 基本的にはDOM等に触ることができない
といった特徴があります。
そのため、イベントを拾うような処理はservice_worker
に記述し、Webページ自体を触る処理についてはcontent_scripts
に書くのが基本方針になるかなと思います。
公式ドキュメントにも下記のように記載されています。
The background script is the extension's event handler
Extensions that read or write to web pages utilize a content script
(余談ですが、一応、無理矢理content_scripts
内にリスナを登録する方法やservice_worker
からDOMに触ることも可能ではあります。)
実装編
作ったもの
GCPコンソールのヘッダカラーはデフォルト#1A73E8
の青ですが、プロジェクト毎に色を変えられるようにしました。
下記は#000000
のピュアブラックに変更した例です。
主な利用用途としては、本番環境と開発環境の違いを視覚的に強く意識できるようになります。
ブラウザ右上のChrome拡張アイコンから設定を行うことができます。
プロジェクト名及びカラーコードを登録する画面と、登録した一覧を表示する画面があります。
ここで登録したカラーコード通りにコンソールのヘッダカラーが変更されます。
簡単な仕組み
chrome.storage
にプロジェクト名とカラーコードの組(ColorCode
)を保存します。
console.cloud.google.com
のタブを開くたびに設定したContent Script
が呼び出され、開いたプロジェクト名と保存済みのプロジェクト名が一致すればヘッダの色を塗り替えます。シンプル!
使用技術
React + TypeScript + Tailwind CSSを用いて作りました。
ビルドにはViteを使っています。
Chrome拡張は、スクリプトっぽくjs(ts)でイベントリスナとイベントハンドラを書いていくのがメインです。
Reactは、Chrome拡張アイコンをクリックしたときに出るオプション画面を作る場合にのみ利用しています。
ディレクトリ構成とmanifest.json
...
├── src
│ ├── App.tsx
│ ├── EditPage.tsx
│ ├── ListPage.tsx
│ ├── colorCode.ts
│ ├── colorCodeRepository.ts
│ ├── colorize.ts
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
...
重要なのはcolorize.ts
です。
こちらをContent Script
として設定し、GCPコンソールを開いたときに動作するようにします。
DOM要素を見て、ヘッダに該当するエレメントのカラーを書き換えています。
tsx
系のファイルによってオプション画面のUIを構成しています。
manifest.json
でindex.html
を指定しているので、Reactがビルドされた結果を読み込むことができています。
下記がmanifest.json
です。
Content Script
やオプション画面が読み込まれるように設定しています。
また、chrome.storage
上にプロジェクト名やカラーコードを保存しているため、パーミッションでstorage
を渡しています。
イベント発生はないのでBackground Script
は利用していません。
{
"manifest_version": 3,
"name": "gcp-benri-extension",
"version": "0.0.1",
"action": { "default_popup": "index.html" },
"content_scripts": [
{
"matches": ["https://console.cloud.google.com/*"],
"js": ["src/colorize.ts"]
}
],
"permissions": ["storage"]
}
今回rollup-plugin-chrome-extension
を利用しています。
manifest.json
を読み取ってChrome拡張用に賢くバンドルしてくれるプラグインです。
下記記事を参考にして簡単にセットアップできました。
どのようにローカル開発を進めたか
実装の内容としては特段書き立てる内容はないですが、Chrome拡張ビギナーの身からするとローカルでどのように開発を進めれば良いか当初戸惑ったので、メモ代わりにまとめます。
ファイルを読み込む方法
まず、Chrome拡張機能の管理画面chrome://extensions
を開いて、デベロッパーモードをONにします。
パッケージ化されていない拡張機能を読み込む
でmanifest.jsonが置いてあるフォルダを選択します。
自分の場合だと、npm run build
によってdist/
にビルド結果が吐き出されるのでdist/
を指定します。
これで、ブラウザ上から開発中のChrome拡張の動作を確認することができます。
開発を進めて変更が生まれた際は、読み込みボタンをクリックすることでブラウザ側に変更を読み込むことができます。便利ですね。
ログの確認
開発の中でチマチマconsole.log
吐いてプリントデバッグしたい場合もあるかもしれません。
Content Script
のログは動作しているWebページ上の開発者ツールから確認することができます。
Background Script
はService Worker上で動作するため、Webページ上にはログが表示されません。
chrome://extensions
のビューを検証
から確認することができます。
また、Chrome拡張のアイコンをクリックすると表示されるオプション画面のログも、オプション画面上を右クリックして検証ツールを開けばログを表示することができます。
終わりに
簡単なChrome拡張を作ることができました。
Cloud Shellウィンドウの最大化/最小化や複数アカウントの切り替え、BigQueryコンソールのショートカットキーの拡充等、将来的に追加したい機能はあるので、余力があればやっていきたいです🥺
2023-11-06追記
Plasmoなるものがあるらしい。