Chrome 拡張機能のマニフェストファイルの書き方

# お断り (2022-12-13 追記)

この記事はマニフェストのバージョンが 2 の時点で作成したものですが、マニフェストの最新バージョンは 3 であり、Chrome Web Store においてはバージョン 2 の拡張機能が [すでに受け付けられない状態](https://developer.chrome.com/docs/extensions/mv3/intro/#start-the-conversion) です。
それでもなおこの記事を参照される場合は、公式の [マイグレーションガイド](https://developer.chrome.com/docs/extensions/mv3/mv3-migration/) も合わせてご確認いただければと思います。

# Overview

https://developer.chrome.com/extensions/manifest についての自分用おぼえがきです。
マニフェストファイルの書き方にフォーカスしていますので、個々の用語の説明などは端折ったりしています。

# 記載が必須の項目

以下の項目は、マニフェストファイルに必須です。

## manifest_version

マニフェストファイル自身のバージョンです。
現在のバージョンは 2 で、なおかつ現在有効なバージョンは 2 しかありません。
なので、とにかく

```json:manifest.json
"manifest_version": 2
```

と書けばいいです。
バージョンは数値なのでクォートは不要です。

## name

拡張機能の名称です。45 文字まで。I18N に対応しています。

```json:manifest.json
"name": "Extension name"
```

また、これは必須ではないですが、`short_name` で略称を定義することもできます。12 文字までが推奨されます。

```json:manifest.json
"short_name": "Ext name"
```

## version

拡張機能のバージョンです。
1 から 4 つの数値を dot で区切って並べて作ることができます。それぞれの数値は 0 から 65535 までの範囲を取ることができます。
0 以外の数字の前に 0 をつけることはできません。つまり "032" などはできません。
拡張機能の自動更新機能でバージョンの上下関係がチェックされるので、適当に付けてはいけないし、拡張機能を更新する際には必ずバージョンが上がってなくてはなりません。

```json:manifest.json
"version": "1.0.12.3456"
```

### バージョンの比較

バージョン間の比較をする際は、ドット区切りのより左にあるバージョンが優先されます。つまり `1.1` は `1.0.9999` より上位のバージョンとみなされます。
区切りが 4 つ未満の時は、足りない部分は 0 が入っているとみなされます。なので `1.1.0.1` は `1.1` より上位のバージョンとなります。

# 記載が推奨される項目

以下の項目は、必須ではありませんが、記載することが推奨されています。

## default_locale

拡張機能のデフォルトの言語を指定します。

```json:manifest.json
"default_locale": "ja_JP"
```

この項目の必要性はちょっと特殊で、当該拡張機能が I18N に対応している場合（_locales ディレクトリ以下が存在する場合）は記載が必須、そうでない場合は記載 *してはいけません* 。

## description

拡張機能の説明文です。132 文字まで。I18N に対応しています。

```json:manifest.json
"description": "a extention for Google Chrome",
```

## icons

拡張機能のアイコンです。サイズは 128x128, 48x48, 16x16 があるといいようです。それぞれ、Chrome ウェブストアや拡張機能の管理ページやファビコンなどに使われます。
画像の形式は png が推奨されています。

```json:manifest.json
"icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
},
```

# どちらか一つ（またはどちらも選ばない）

ブラウザアクションとページアクションは、使用する場合どちらか一つしか選べません。どちらも使用しない、というのはありです。

## browser_action

ブラウザアクションを使用する場合に記載します。

```json:manifest.json
"browser_action": {
    "default_icon": {
        "19": "icon19.png"
    },
    "default_title": "Ext title",
    "default_popup": "popup.html"
},
```

### 子要素

<dl>
<dt>default_icon</dt>
<dd>browser_action に対する任意の項目で、アドレスバーの右に表示するアイコンを指定します。サイズは 19px が推奨されます。（大きいサイズのアイコンを指定した場合、表示サイズに縮小されます。）</dd>
<dt>default_title</dt>
<dd>browser_action に対する任意の項目で、アドレスバーの右に表示するアイコンから出るツールチップに表示される文字列です。省略すると、name が使われます。</dd>
<dt>default_popup</dt>
<dd>browser_action に対する任意の項目で、アドレスバーの右に表示するアイコンをクリックした際に表示されるポップアップの中の html を指定します。</dd>
</dl>

## page_action

ページアクションを使用する場合に記載します。

```json:manifest.json
"page_action": {
    "default_icon": {
        "19": "icon19.png"
    },
    "default_title": "Ext title",
    "default_popup": "popup.html"
},
```

`browser_action` が `page_action` になった以外は、マニフェストファイルの書式としては同じです。

# オプション項目

以下の項目は必要に応じて追加します。

## content_scripts

コンテントスクリプトを使用する場合に記載します。

```json:manifest.json
"content_scripts": [
    {
        "matches": [ "http://*/*", "https://*/*" ],
        "js": [ "script.js" ]
    }
],
```

### 子要素

<dl>
<dt>matches</dt>
<dd>content_scripts に対する必須の項目で、動作対象となる URL を
<a href="https://developer.chrome.com/extensions/match_patterns">Match Patterns</a>
の形式で設定します。もちろんリストです。</dd>
<dt>js</dt>
<dd>content_scripts に対する任意の項目で、動作させるスクリプトをリストで設定します。</dd>
</dl>

## background

バックグラウンドページまたはイベントページを使用する場合に記載します。

*注意：[バックグラウンドページの解説ページ](https://developer.chrome.com/extensions/background_pages)の冒頭に警告が記載されているとおり、バックグラウンドページの使用は推奨されていません。可能な限りイベントページを使用するようにしましょう。*

```json:manifest.json
"background": {
    "scripts": [ "background.js" ],
    // recommended
    "persistent": false
},
```

### 子要素

<dl>
<dt>scripts</dt>
<dd>バックグラウンドで動作する JavaScript ファイルを設定します。
複数のファイルが使えるので、設定値はファイル名のリストになることに注意。</dd>
<dt>persistent</dt>
<dd>`"persistent": false` が含まれる場合がイベントページで、それ以外がバックグラウンドページとなります。`persistent` というキーワードでわかるように、バックグラウンドページは永続的に裏で動き続けるのに対して、イベントページにすると必要に応じてのみロードされるようになります。そのため、可能な限りイベントページを使用することが推奨されています。
</dd>
</dl>

## permissions

主に chrome.* API を使うときなどに、使う対象を設定する必要があります。
[設定できるパーミッションの一覧](https://developer.chrome.com/extensions/declare_permissions)

```json:manifest.json
"permissions": [
    "tabs",
    "bookmarks"
],
```

## options_page

オプションページを使用する場合に設定します。

```json:manifest.json
"options_page": "options.html",
```

## minimum_chrome_version

拡張機能が最低限必要とする Chrome のバージョンを設定します。特定のバージョン以降でしか動かない機能を使っているのなら設定します。

## homepage_url

拡張機能のホームページの URL を設定します。
ウェブストアや拡張機能の管理ページや、ブラウザアクションを使用している場合、アイコンを右クリックした時に出るメニューの一番上のタイトルをクリックした時の遷移先などにも使用されます。

# わかる人・必要な人だけが設定すればいい項目

## content_security_policy

[Content Security Policy](http://w3c.github.io/webappsec/specs/content-security-policy/csp-specification.dev.html) を設定します。
下記の設定例がデフォルトの設定となります。

```json:manifest.json
"content_security_policy": "script-src 'self'; object-src 'self'",
```

外部との接続を許可したりする場合に設定を変更する項目であり、うかつな設定はセキュリティに直接関わってきます。
セキュリティについての知識が足りず意味がわからないという人はこの設定を触るべきではありません。また、ローカルで閉じていて eval やインラインスクリプトを使わない拡張機能を作る分にはそもそも設定する必要はありません。

# 基本的に自分で設定する必要はない項目

## key

キーはアップロードしたりパッケージ化した時などに自動で付与されるので、自分でつける必要はありません。

## update_url

デベロッパーダッシュボード経由で更新している分には、設定する必要はありません。
自分で更新サイトを作って管理する場合のみ、そのサイトの URL を設定する必要があります。

# 限定機能項目

## file_browser_handlers

https://developer.chrome.com/extensions/fileBrowserHandler
> Important: This API works only on Chrome OS.

ということで、この項目は Chrome OS でしか動作しません。