クロスブラウザなブラウザ拡張を開発・審査・公開するまで【Chrome拡張】

# はじめに
そのChrome拡張、Firefox や Edge などで出したいと思ったことはありませんか。

しかし、いざやるとなると調べることも多く面倒臭いです。

そこで本記事は「ブラウザ拡張の開発から公開まで」を以下の2点を軸にまとめていきます。

- 開発の工程を減らす
  - クロスブラウザ拡張用パッケージによる開発・デバッグ・パッケージ化
- 申請・公開をスムーズに
  - 各ベンダーの審査の共通点・相違点をまとめ、準備の負担を軽減

# 対象の読者
- これからChrome拡張などを作りたい方
- ブラウザ拡張のクロスブラウザ対応をしたい方
	- ただし Chrome, Firefox, Opera, Edge に限ります
- 各ベンダーの審査の違いについて知りたい方

## 必要な知識
- ターミナルコマンドが打てる
  - npmなどが実行できる
- 拡張に必要なJavaScript, CSSなどが書ける

# 作るもの
今回は簡単な例として「Qiita記事のヘッダーを色分けする拡張」を作ります。

Qiita記事の各ヘッダーがこのように表示されるようにします。
![Promo-Image-Small_440x280.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/396434b5-2dbd-e5d2-c0e3-14d93ed5f758.png)


実際に公開したものはこちらです。

- Chrome: [Qiita Rainbow Header - Chrome ウェブストア](https://chrome.google.com/webstore/detail/qiita-rainbow-header/nccgheinjagepglbgloplfiekhepeodb)
- Firefox: [Qiita Rainbow Header – 🦊 Firefox (ja) 向け拡張機能を入手](https://addons.mozilla.org/ja/firefox/addon/qiita-rainbow-header/)
- Opera: [Qiita Rainbow Header extension - Opera add-ons](https://addons.opera.com/ja/extensions/details/qiita-rainbow-header/)
- Edge: [Qiita Rainbow Header – Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/qiita-rainbow-header/ecmebkdhlpljelacipkajemapilfalpo)

# 目次
大きく3つのセクションにわけて説明していきます。

1. 拡張機能の開発
2. 審査の準備
3. 審査・公開

# 1. 拡張機能の開発

Node.js が必要となりますので、もし入っていない方は [こちら](https://nodejs.org/ja/download/) からインストールお願いします。

クロスブラウザ対応のため `webextension-toolbox` というパッケージを使っていきます。
ブラウザごとの違いなどを気にせずに、簡単に各ブラウザ用のパッケージを出力できる神ツールです。

https://github.com/webextension-toolbox/webextension-toolbox

## サンプルコード
記事で使っているコードの最終形はこちらに公開しています。
https://github.com/yamadashy-sandbox/webextension-toolbox-example

また、今回は記事用に極力シンプルにしたものを使っていきますが、実際に使用しているコードはこちらになります。
webpack部分のカスタムに加え、TypeScriptやESLintなどにも対応しています。
https://github.com/yamadashy/qiita-rainbow-header

## 雛形からコード生成
さっそく開発していきます。


###### 1. 必要なパッケージをインストール

- `yo` 雛形作成パッケージ
- `generator-web-extension` webextension-toolbox の雛形作成パッケージ

```shell
$ npm install -g yo generator-web-extension
```

###### 2. 開発用のフォルダを作成、移動

```shell
$ mkdir my-web-extension && cd $_
```

###### 3. コード生成

```shell
$ yo web-extension
```

以下の選択肢以外はそのままEnterで大丈夫です

- `Would you like to use UI Action?` Content ScriptsだけSpaceで選択しEnter
- `Would you like to install promo images for the Chrome Web Store?`  yをおしてEnter


## 拡張機能の実装

いくつかのファイルを書き換えていきます。

###### 1. `app/scripts/contentscript.js` を書き換え
今回はJavaScriptは必要ないので中身を消してください。
ファイルを消しても大丈夫です。

###### 2. `app/styles/contentscript.css` を書き換え

```css
.allWrapper .it-MdContent h1 { color: #c35c5c; border-bottom-color: #c35c5c; }
.allWrapper .it-MdContent h2 { color: #bf905d; border-bottom-color: #bf905d; }
.allWrapper .it-MdContent h3 { color: #9b9b4c; }
.allWrapper .it-MdContent h4 { color: #4a944a; }
.allWrapper .it-MdContent h5 { color: #468a8a; }
.allWrapper .it-MdContent h6 { color: #6464a5; }
```

###### 3. `app/_locals/en/messages.json` の書き換え
 `en` フォルダの名前を `ja` にして、 `message.json` を書き換えてください。
（json内のコメントは消してください）

```json
{
  // 拡張機能の表示名
  "appName": {
    "message": "Qiita Rainbow Header"
  },
  // URLなどに使う短縮名
  "appShortName": {
    "message": "qiita-rainbow-header"
  },
  // 拡張の説明
  "appDescription": {
    "message": "Qiita記事のヘッダーの色を段階によって変えます"
  }
}
```

###### 4. `app/manifest.json` を書き換え

```json
{
  "manifest_version": 2,

  // messages.json から自動で取得されます
  "name": "__MSG_appName__",
  "short_name": "__MSG_appShortName__",
  "description": "__MSG_appDescription__",

  // 自由な値で大丈夫です
  "version": "0.1.0",
  "default_locale": "ja",
  "author": "作者名",

  // 拡張のアイコン
  "icons": {
    "16": "images/icon-16.png",
    "128": "images/icon-128.png"
  },

  "content_scripts": [
    {
      // 拡張を有効化するURLにマッチする文字列
      "matches": [
        "https://qiita.com/*"
      ],
      "js": [
        "scripts/contentscript.js"
      ],
      "css": [
        "styles/contentscript.css"
      ],
      // 実行タイミング。document_startはDOMの読み込み中
      "run_at": "document_start"
    }
  ]
}
```

`manifest.json` についてはここが参考になるかと思います。

https://qiita.com/mdstoy/items/9866544e37987337dc79

また、`run_at` についてはこちらを参考に。

https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes/RunAt


これで機能の実装は終わりです。
アイコンの変更などは後ほど説明します。


## 各ブラウザでデバッグ

### ブラウザ共通
以下のコマンドで開発用にビルドでき、`dist/<ブラウザ名>` のフォルダに出力されます。

```shell
$ npm run dev <ブラウザ名>

# 以下のどれか
$ npm run dev chrome
$ npm run dev firefox
$ npm run dev opera
$ npm run dev edge
```

また、この開発用ビルドを終了させない限りは、ファイル変更を検知して自動で再ビルドしてくれます。

### Chrome拡張のデバッグ
1. URL欄に `chrome://extensions` でEnter

2. 右上の「デベロッパーモード」をON
![chrome-dev-mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/1e0da1e7-e3d7-7034-b3e9-faaf9059492f.png)


3. `dist/chrome` フォルダをドラッグ&ドロップ

4. 対象ページを再読み込みして確認
![拡張機能の動作確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/7d19e286-2e87-c573-7336-2811a9f61b56.png)


無事、ヘッダーの色が変わることを確認できました。

### Firefoxアドオンのデバッグ

1. URL欄に `about:debugging#/runtime/this-firefox` でEnter

2. 「一時的なアドオンを読み込む...」から `dist/firefox/manifest.json` を開く
![firefox拡張読み込みページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/239ba3a6-a126-3fee-a6d9-8a43ba533e9b.png)



3. 対象ページを再読み込みして確認


### Operaアドオンのデバッグ

1. URL欄に `opera://extensions` でEnter

2. 右上の「開発者モード」をON
![opera-dev-mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/7e16da23-c180-236b-b37c-c937c51ae0b2.png)


3. `dist/opera` フォルダをドラッグ&ドロップ

4. 対象ページを再読み込みして確認



対応したいブラウザの確認ができたら、審査の準備をしていきます。


### Edge拡張のデバッグ
1. URL欄に `edge://extensions` でEnter

2. 左下の「開発者モード」をON
![edge-dev-mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/e11d7643-5667-c326-aeab-329e930c8616.png)


3. `dist/edge` フォルダをドラッグ&ドロップ

4. 対象ページを再読み込みして確認



# 2. 審査の準備

## アイコン画像などの用意
各ブラウザで用途などを比較していきます。

### アイコン画像
最低限 `128x128` が必要です。
各ブラウザごとの違いの表です。

|サイズ|Chrome|Firefox|Opera|Edge|
|--|--|--|--|--|
|全般|必須サイズあり<br>[ガイドライン](https://developer.chrome.com/docs/webstore/images/)|なければデフォルト|Chromeと同じ|Chromeと同じ|
|16x16|拡張機能ページのファビコン||Chromeと同じ|Chromeと同じ|
|32x32|Windows向けにあると良い||||
|48x48|拡張機能ページ|理想のサイズ|Chromeと同じ|Chromeと同じ|
|96x96|表示される実際のサイズ|公式の例で使用|||
|**128x128**|**必須**。Chromeウェブストア||Chromeと同じ|Chromeと同じ|

画像が用意できたら `app/images` フォルダに入れ、 `app/manifest.json` も用意した画像の分書き換えてください。
以下は `48x48` `128x128` を用意したパターンです。

```diff
-    "16": "images/icon-16.png",
-    "128": "images/icon-128.png"
+    "48": "images/icon-48.png",
+    "128": "images/icon-128.png"
```

今回は[FireAlpaca](https://firealpaca.com/ja/)というペイントソフトで適当にアイコンを作りました。
![store-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/1a0a89ce-ea12-3c87-0e6b-851fed2d588e.png)


### プロモーション画像
`440x280` が必要となります。
スクリーンショットだと弾かれる可能性がありますが、用意が面倒なのでスクショで一旦申請してみても良いと思います。

|サイズ|Chrome|Firefox|Opera|Edge|
|--|--|--|--|--|
|全般|画像ありは優先表示|設定不可|未設定だとフィーチャーされない||
|**440x280**|**必須**。Small|x|x|**必須**|
|920x680|Large|x|x||
|1400x560|Marquee|x|x|あると良い|
|300x188||x|設定可能||




### スクリーンショット画像
1つは必要です。
`1280x800` があると良いと思います。

|サイズ|Chrome|Firefox|Opera|Edge|
|--|--|--|--|--|
|全般|最低1つ|あると良い(?)|ないとリジェクトの可能性あり|あると良い|
|640x400|設定可|||設定可|
|1280x800|望ましい|||設定可|


## 詳細用の文章の用意
`messages.json` のdescriptionとは別に、下の赤枠に表示するような詳細な文章が表示できます。
![chromeストアの説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/4ec8f9e8-77cd-2f19-22ad-cc734b305cfd.png)


こちらは効率化のためなので任意ですが、コードで管理しておいたほうが多言語化の際に楽になります。

自分の場合は、 `app/_locals/<言語コード>/detailed-description.txt` に入れています。

## プライバシーポリシー
アナリティクスなど、個人情報を収集する処理を入れている場合は必要となります。

今回の記事は特にデータ収集などはしていないですが、以下のようなプラポリを設定しています。
https://github.com/yamadashy/qiita-rainbow-header/wiki/Privacy-Policy-JA

## レビュアー用の説明
レビュアーが拡張機能を試す際に必要な情報を事前にまとめておきます。Firefox, Edgeの申請時に使います。

- 確認用のURL
- 確認の手順
- SNS用の拡張など、アカウントが必要となる場合はデバッグ用アカウントの情報

この拡張だと以下のようになります。

```
確認手順
1. 拡張機能をインストール
2. qiita.com を開き、適当な記事に飛びます
3. 記事内のヘッダーの色が変わっていることが確認できます。
```

Slackの拡張を作るとしたらこんな感じになると思います。

```
確認用の情報
- Slackワークスペース: 〇〇〇.slack.com
- アカウント: 〇〇〇@gmail.com
- パスワード: 〇〇〇

確認手順
1. 拡張機能をインストール
2. slackのワークスペースにログイン
3. 〇〇〇が確認できます
```

## パッケージ化
審査に提出するためのパッケージを作ります。

以下のコマンドで各ブラウザ向けのパッケージが `packages` フォルダに出力されます

```shell
$ npm run build <ブラウザ名>

# 以下のどれか
$ npm run build chrome
$ npm run build firefox
$ npm run build opera
$ npm run build edge
```

## レビュー提出用ソースコード
Firefoxのレビューでは必要になります。

git管理している場合は `git archive` で簡単にzipが作れます。

```shell
$ git archive HEAD -o source.zip
```

`package.json` の `scripts` に追加しておくと便利です

```json
{
  "scripts": {
    "archive": "git archive HEAD -o source.zip"
  }
}
```

# 3. 審査・公開
いよいよ申請です。

各ベンダーへの審査について、迷いそうな点を重点的に説明していきます。

## ブラウザ共通
以下の情報があると良いです。
Webサイトなどは、GitHubのリポジトリをREADMEを置くだけでも良いので作ると便利です。

- 拡張の情報
   - Webサイト ... GitHubのURLで大丈夫です
   - サポートページ ... GitHubのissueページ
   - プライバシーポリシー ... GitHubのWikiにページを作って設定
- ストアの情報
   - 説明 ... 事前に説明をまとめておきます。 または `detailed-description.txt` を使います

## Chrome拡張の申請
[公式のガイドライン](https://developer.chrome.com/docs/webstore/publish/)

### 1. 開発者アカウント登録
Googleアカウントを作り、デベロッパーとして登録します。
**最初だけ500円の支払いが必要**です。
https://chrome.google.com/webstore/devconsole/register

### 2. パッケージのアップロード
以下のページを開き「新しいアイテム」からアップロードできます。
https://chrome.google.com/webstore/devconsole/


### 3. 内容を設定

#### 「ストア掲載情報」を設定
- 説明 ... 事前にまとめた内容か `detailed-description.txt` を使います
- カテゴリ選択
- 画像設定 ... 用意しておいたアイコンとスクショなどを設定
- ホームページURL ... GitHubのページなど
- サポートURL ... GitHubのissueページなど

#### 「プライバシーへの取り組み」を設定
- 拡張機能の用途
- 権限が必要な理由 ... なにかしらの権限を要求している場合は、権限ごとにその理由を記載
- データ使用 ... 特にデータを使用していない場合は、下のほうにある3つのチェックボックスを選択しておけば大丈夫です
![chrome設定プライバシー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/66676866-e75b-33f9-3f56-fb60f849e80a.png)


最近のChromeは審査が厳しくなっているので、**使用する権限は必要最低限に**したほうが良いです。

### 4. プライバシーポリシーの設定

ダッシュボードのトップページの「アカウント」から設定します。

プライバシーポリシーを設定しないとリジェクトされる可能性があります。

今回は以下のように記載しています。
ユーザーのデータを収集するか、収集する場合どう扱うかなどを明記していれば大丈夫なようです。
https://github.com/yamadashy/qiita-rainbow-header/wiki/Privacy-Policy-JA

### 5. 審査待ち
https://chrome.google.com/webstore/devconsole
![chrome審査中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/2ba08b33-cd8c-99b4-ecf8-9ae22d639623.png)


1,2日で審査結果が出ます。
体感的にリジェクトされるときは3,4日経ってからリジェクトされます。

## Firefoxアドオンの申請

### 1. 開発者アカウント登録
開発者アカウント登録します。
https://addons.mozilla.org/ja/developers/

### 2. パッケージのアップロード
「新しいアドオンを登録」ページを開き、パッケージをアップロードします。
https://addons.mozilla.org/ja/developers/addon/submit/distribution

また、今回のようにwebpackなどを使用している場合は、ソースコードの提出が必要なので、[レビュー提出用ソースコード](#レビュー提出用ソースコード) の項を参考にzipを作り提出します。

### 3. 内容を設定
以下を埋めていきます

- 概要 ... 特に変更は必要ないです。
- 説明 ... 用意した内容か `detailed-description.txt` を使います
- カテゴリ選択
- メールアドレス
- サポートサイト ... GitHubのissueページなど
- ライセンス
- 審査担当者へのメモ ... 拡張機能の説明や動作確認の手順などを書きます

一旦ここで登録が完了し審査が始まりますが、まだアイコンなどを登録していないので編集します。

### 4. アイコンなどの設定
アドオン管理ページから対象のアドオンのページを開きます。
https://addons.mozilla.org/ja/developers/addons

画像の「編集」ボタンから、アイコンとスクショを設定できます。

### 5. 審査待ち
https://addons.mozilla.org/ja/developers/addons
![firefox審査中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/02f6fa45-eff7-0508-8c18-5f18b984abb6.png)


2,3日で審査結果が出ます。
以前はかなり早かったのですが、コロナによる影響で遅くなっているようです。

## Operaアドオンの申請
[公式のガイドライン](https://dev.opera.com/extensions/publishing-guidelines/)

### 1. Operaアカウントを作成
以下からOperaのアカウントを作成します。
https://auth.opera.com/account/signup

### 2. パッケージをアップロード
Opera拡張ダッシュボードを開き「Upload new addon」からアップロードします。
https://addons.opera.com/developer/

### 3. 内容を設定
#### 「General」の設定
- カテゴリ
- 「I want my extension to be available for auto-publishing.」にチェック。自動で公開するかの設定です。

#### 「Versions」の設定

気づきづらいのですが、`Versions`タブ内に表示されている各バージョンをクリックして、パッケージ説明などの編集ができます。
![review-opera-package-page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/a5b060b5-8a50-ab27-dd39-9db1edfdcf6c.png)

以下の項目を設定します。
**1つ設定するごとにチェックマークで保存**するのを忘れないようにしてください。

- General
  - ウェブサイトURL
  - サポートURL ,,, GitHubのissueページなど
  - ソースコードURL ... GitHubのページで大丈夫です（ソースが公開されている場合）
  - 審査担当者用の情報
      - ソースコードURL
      - ビルド方法 ... 審査担当者用にコードのビルド方法を記載
  - ライセンス
  - プライバシーポリシー ... URLだけで良いです。
- Media
  - スクショ `1280x800`
  - アイコン `64x64`
- Translations
  - 用意した内容か `detailed-description.txt` を使います

記入が終わったらGeneralの「Submit Changes」で保存します。
同時に審査も始まります。

#### 「Promotional Image」の設定
`300x188` の画像を設定します


### 4. 審査待ち
「Conversation」タブで確認できます。
![opera審査中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/e17f7c4a-825c-c5ca-a97a-e564f96ccc44.png)


自分の場合は3分で審査が通りました。
よっぽど内容がおかしくない場合は一瞬で通りそうです。

## Edge拡張の申請

[公式のガイドライン](https://docs.microsoft.com/ja-jp/microsoft-edge/extensions-chromium/publish/publish-extension)

### 1. アカウント作成
Microsoftのアカウントを作成し、開発者として登録してください。
https://partner.microsoft.com/dashboard/microsoftedge

### 2. パッケージのアップロード
以下のページの「拡張機能を作成」からパッケージをアップロードします。
https://partner.microsoft.com/ja-jp/dashboard/microsoftedge/overview

### 3. 内容を設定

以下のようなページになるので、左側の「プロパティ」などを選択して設定していきます。
![edge設定ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/ac6a0721-41ae-230f-ca43-67ed77f69a19.png)


#### 「プロパティの設定」を設定
- カテゴリ
- プライバシーポリシー
- Webサイト
- サポート連絡先（サポートサイト） ... GitHubのissueページなど

#### 「Store登録情報」を設定
画像のドラッグ&ドロップなどもできず、また多言語対応している場合は1つ1つ設定しないといけないので結構面倒です。

- 拡張機能の説明 ... `message.json` と `detailed-description.txt` をあわせた内容を設定します。

### 4. 審査用の説明を記載
最後に審査担当者が確認するための説明を記載して申請します。

### 5. 審査待ち
https://partner.microsoft.com/ja-jp/dashboard/microsoftedge/overview
![edge申請中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/f76a1c16-ffd6-3f15-3780-4fcc9500c298.png)


審査結果が出るまで4,5日程度かかります。
7営業日以内には審査結果が出ると公式には書かれています。

## 公開
無事すべて公開されました。

- Chrome: [Qiita Rainbow Header - Chrome ウェブストア](https://chrome.google.com/webstore/detail/qiita-rainbow-header/nccgheinjagepglbgloplfiekhepeodb)
- Firefox: [Qiita Rainbow Header – 🦊 Firefox (ja) 向け拡張機能を入手](https://addons.mozilla.org/ja/firefox/addon/qiita-rainbow-header/)
- Opera: [Qiita Rainbow Header extension - Opera add-ons](https://addons.opera.com/ja/extensions/details/qiita-rainbow-header/)
- Edge: [Qiita Rainbow Header – Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/qiita-rainbow-header/ecmebkdhlpljelacipkajemapilfalpo)

審査は体感だとOperaが一番早くEdgeが一番遅いです。
またChromeが一番厳しいです。


# おわりに
要点だけを書きましたが、それでもやること多いですね。


各ベンダーで協力して共通の拡張ストアページ作ってくれないですかね...。
最近のニュースで [大手のベンダー達がブラウザ拡張を改善するワーキンググループを作った](https://www.w3.org/community/webextensions/2021/06/04/forming-the-wecg/) みたいな話があるので、改善されていくことを願います。