Chrome拡張機能を（ほぼ）最小構成で作る

## TL;DR

できあがったものがこちらです

hidao80/chrome-extension-sample： Minimal Chrome Extensions project.
https://github.com/hidao80/chrome-extension-sample

ソースのZipファイルのダウンロード
https://github.com/hidao80/chrome-extension-sample/archive/refs/heads/main.zip

※本記事ではChromeストアへの登録方法は取り扱いません。

## ざっくり解説

Chrome拡張機能はhtml、JavaScript、CSSとアイコン用の画像の他に権限や説明、動作するURLなどを指定するためにJSONで記述されたマニフェストファイル`manifest.json`で構成されます。

上記のZipファイルにはそれらがひとまとめになっており、展開（解凍）して開発者モードのChrome互換ブラウザ（Chrome、Edge、Brave、Chromiumなど）で動作させることができます。

## とりあえず動かしてみる

サンプルの拡張機能はChromeストアに公開されていないので、開発者モードを使ってソースからインストールします。
手順は以下のとおりです。

1. Zipファイルをダウンロードします。
2. ダウンロードしたZipファイルを展開（解凍）します。
3. Chrome対応ブラウザ（Chrome、Edge、Brave、Chromiumなど）を開き、「設定」の「拡張機能」ページを表示します。<chrome://extensions/>
4. 「開発者モード」スイッチを有効にします。
5. 「パッケージ化されていない拡張機能を読み込む」（ブラウザにより表現は異なる）をクリックし、ダイアログから解凍した拡張機能のフォルダ「chrome-extension-sample」を選択します。

### 動作確認をする

このサンプルの拡張機能では、URLが「<https://hidao80.github.io/>」で始まっているときだけ動くようにマニフェストファイルを記述しているので、インストールが終わったら次のURLへアクセスしてください。拙作Amazon URL短縮Webアプリへ移動します。

Amazon URL Shortener
https://hidao80.github.io/amazon-url-shortener/

英語の画面が表示されると同時に拡張機能が実行され、「OK!」と言う内容のダイアログが表示されます。
ダイアログの[OK]ボタンをクリックすると拡張機能が終了し、日本語環境のブラウザであればページの多言語化対応ライブラリ[^1]の機能でページの内容が日本語化されます。

## ソースの説明

内容的には`manifest.json`以外はほぼ空なのでサクサク行きます。

### ソースツリー
```
.
├── LICENSE                // GitHub用。拡張機能には必要ない
├── _locales/              // i18n(多言語化)フォルダ。このフォルダ名は変更できない
│   ├── en/                // en（英語）ロケール用言語ファイル用フォルダ。使用できるロケール文字列はGoogleの公式サイト参照
│   │   └── messages.json  // このファイル名も変更できないらしい（未検証）
│   └── ja/                // ja（日本語）ロケール用言語ファイル用フォルダ
│       └── messages.json
├── css/                   // cssファイル格納用フォルダ。必要ない
│   └── main.css
├── html/                  // htmlファイル格納用フォルダ。必要ない
├── img/                   // 画像格納用フォルダ。必要ない
│   └── icon_256.png       // 拡張機能のアイコンファイル。管理画面やアドレスバーの横に表示されるときに使う
├── js/                    // JavaScript格納用フォルダ。必要ない
│   └── main.js
├── manifest.json          // マニフェストファイル。拡張機能として認識させるために必要。各種情報を記述する
└── readme.md              // GitHub用。拡張機能には必要ない
```

LICENSEとreadme.mdについてはGitHub用のファイルたちで、拡張機能には必要ないので今回の説明からは割愛します。

### ソースファイル
JavaScriptは1行だけです。
```js:main.js
alert('OK!');
```
CSSに至っては何も記述されていない空のファイルです。なくても良いです。
```main.css
```
英語の辞書データです。英語環境のブラウザでこの拡張機能を見たとき、特殊な変数を仕込んでおけばここに記述してある文字列が表示されます。
マニフェストファイルで`default_locale`項目を設定しなければ必要ありません。
```json:_locales/en/messages.json
{
    "appName": {
        "message": "S.C.E."
    },
    "appDesc": {
        "message": "Sample Chrome Extension."
    }
}
```
日本語の辞書データです。日本語環境のブラウザでこの拡張機能を見たとき、特殊な変数を仕込んでおけばここに記述してある文字列が表示されます。
マニフェストファイルで`default_locale`項目を設定しなければ必要ありません。
```json:_locales/ja/messages.json
{
    "appName": {
        "message": "SCE"
    },
    "appDesc": {
        "message": "Chrome拡張機能のサンプルです。"
    }
}
```
本丸のマニフェストファイルです。本来はJSONなのでコメントを入れることはできませんが、ここでは便器上JavaScriptスタイルのコメントで説明します。
```js:manifest.json
{
    "name": "__MSG_appName__",         // 拡張機能の表示名です。"__MSG_{_locales/*/messages.jsonのキー}__"とすることで多言語対応できます
    "version": "1.0.1",                // バージョン番号。Chromeストアに公開するときは自動バージョンアップの指標になります
    "manifest_version": 3,             // マニフェストファイルの記述方法のバージョン。バージョン2以下は2024年以降ストアから排除されるそうです
    "description": "__MSG_appDesc__",  // 拡張機能の説明文です。説明についてはnameと同様です。直接文字列を記述することもできます
    "default_locale": "ja",            // デフォルトのロケール。_localesフォルダが無いときには記述してはいけません
    "homepage_url": "https://github.com/hidao80/chrome-extension-sample/", // 拡張機能管理ページからリンクが張られます
    "update_url": "https://github.com/hidao80/chrome_extension_sample/releases/", // ストアを使ってなければ利用できないかも…？（未検証）
    "icons": {
        "256": "img/icon_256.png"  // アイコンファイル。"64"（64x64px）や"128"(128x128px)など、複数指定できます
    },
    "content_scripts": [  // スクリプトファイルなどの場所を記述します
        {
            "matches": [  // この配列のURLにマッチするページのときだけこの機能拡張が動作します
                "https://hidao80.github.io/*"
            ],
            "js": [       // JavaScriptのファイルを指定します。jsフォルダは必須ではなく、複数ファイルを列挙することができます
                "js/main.js"
            ],
            "css": [      // CSSのファイルを指定します。cssフォルダは必須ではなく、複数ファイルを列挙することができます
                "css/main.css"
            ]
        }
    ]
}
```

Chromeストアに登録しようとすると他にもスクリーンショットやストアの見出しに使う画像を用意することを強く勧められるようですが、今回はローカルからインストールするので省略しました。
また、言語ファイル（`_locales`フォルダ以下）は私の趣味で入れているだけで必須ではありません。省略することができます。このとき、マニフェストファイルの`default_locale`を削除することも忘れずに。

## さいごに

この拡張機能のZipファイルに含まれる`main.js`や`main.css`ファイルを編集するだけでもかんたんな機能拡張は自作できるようになると思います。
他のタブにアクセスしたり、バックグラウンド処理をしたり、メニューを出したりするには諸々のファイルや利用する権限の宣言が必要になったりしますが、詳しくは別の記事に譲ります。

この記事がChrome拡張機能を作りたい方々の最初のハードルを超える一助になれば幸甚です。

[^1]: 拙作[multilingualization.js](https://gist.github.com/hidao80/1f0d830a18c6bbb15ddba4ff5954a13e)です。