Chrome拡張の作り方まとめ

Chrome拡張のサービスを作成してみたのであとで見返す用に作成方法をまとめました。公式ドキュメントは英語ですが、日本語の情報もたくさんあります。

## やってみたこと
- chrome拡張作成
    - フォルダ構成
    - manifest.json作成
    - background.js作成
    - default_popup系作成
- chrome上で動かす
    - インストール
    - デバッグ
- ストアへの公開申請
- ソースは丸見えなので注意

## Chrome拡張公式ドキュメント
公式のチュートリアルもあるので、英語が読める人はこちらを見るのが良さそう。サンプルのソースとかAPIリファレンスなどなど。
https://developer.chrome.com/extensions

- チュートリアル 
https://developer.chrome.com/extensions/getstarted
    
- 機能一覧
https://developer.chrome.com/extensions/devguide

- サンプル
https://developer.chrome.com/extensions/samples

## フォルダ構成
決まり等はありません。編集しやすいように変更していくのがよいと思われますが、今回は以下のような形で作成しました（重要なところだけピックアップ）。作成するファイルは基本的にmanifest.jsonとhtml・css・js・images（アイコン画像）です。jsのフレームワーク等の利用もできるので、利用する場合はフォルダ構成変わってくると思います。

```
├── bootstrap # bootstrapをcssフレームワークとして使用
├── css
│   └── popup.css
├── html
│   └── popup.html
├── images
├── js
│   ├── background.js
│   └── popup.js
├── lib
│   └── jquery-3.3.1.min.js
└── manifest.json
```
 
## マニフェストファイルの作成
作成するChrome拡張の設定全般を記述するファイルで、必ず作成する必要があります。この設定ファイルさえ理解できれば、あとはWebページを作る要領でhtml・css・jsをいじるだけで作れます。

```json:manifest.json
{
  "name": "Picker",
  "version": "1.0",
  "description": "Picker",
  "permissions": ["notifications","alarms", "http://*/*", "https://*/*"],
  "background": {
    "scripts": ["lib/jquery-3.3.1.min.js", "js/background.js"],
    "persistent": true
  },
  "browser_action": {
    "default_popup": "html/popup.html",
    "default_icon": {
      "16": "images/picker16.png",
      "32": "images/picker32.png",
      "48": "images/picker48.png",
      "128": "images/picker128.png"
    }
  },
  "icons": {
    "16": "images/picker16.png",
    "32": "images/picker32.png",
    "48": "images/picker48.png",
    "128": "images/picker128.png"
  },
  "manifest_version": 2
}
```

マニュフェストファイルの作成は公式ドキュメントやこの記事が非常に参考になります。
[Chrome 拡張機能のマニフェストファイルの書き方](https://qiita.com/mdstoy/items/9866544e37987337dc79)

以下マニュフェストファイルの重要な項目です。

## permission
ここで利用するChromeAPIを記述しないとScriptに記述しても実行されないので要注意です。
[公式のパーミッション一覧](https://developer.chrome.com/extensions/declare_permissions)

## background
　Chrome拡張がインストールしてされてから実行されるページです。scriptsに初期化処理や、定期実行する処理、イベントリスナー等の記述等行うといいでしょう。

### バックグラウンドページ

```
 "persistent": true 
```
と記述することで バックグラウンドページとして扱われます。常にメモリに常駐し続けます。
[Chrome機能拡張のバックグラウンドページについて](https://oxynotes.com/?p=8906)

### イベントページ

```
 "persistent": false
```

と記述することで、イベントページとして扱われます。
[Chrome拡張のイベントページについて](https://oxynotes.com/?p=8928)

## browser_action
ブラウザ全体に作用する拡張機能（常時表示される）を記述します。browser_actionとpage_actionを同時に利用することはできず、どちらか一方のみ記述を行う必要があります。

### default_popup
アイコンを左クリックした際に表示されるポップアップページで表示するhtmlを指定します。アイコンをクリックした時に初めてスクリプトが実行されます。

## page_action
今回は使用しませんでしたが、特定のURLに対してのみ実行したいactionがある場合はこちらを使用します。google.comのドメインを表示している時のみアイコンを表示させる等の動作をさせることができます。


## その他重要なオプション

### options_page
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366054/f2c0f9b6-cd22-f0b2-181e-25bfe5ac693b.png)
アイコンを右クリックした際に表示されるメニュー内の「オプション」メニューをクリックした際に表示される画面を指定できます。オプションという名の通り、アプリ自体のオプションを設定できる画面を表示する際に使用すると良さそうです。

```json
"options_page": "html/options.html"
```

### content_script
今回は使用しませんでしたが、特定のURLに対してのみ実行したいスクリプトがある場合はこちらを使用します。以下はドメインqiita.comに対してのみ有効にしたいスクリプトのサンプルです。

```json
"content_scripts": [
    {
        "matches": [ "http://qiita.com/*", "https://qiita.com/*" ],
        "js": [ "content_script.js" ]
    }
]
```

## background.jsの作成
bakgroud.jsのサンプルです。「Hello」と1分に一回デスクトップ通知を行ってくれます。

```javascript:backgroud.js
(function($){
  var timer = function(){
    chrome.alarms.create('ALARM_NAME', {periodInMinutes: 1});
    chrome.alarms.onAlarm.addListener((alarm) => {
      if (alarm.name === 'ALARM_NAME') {
        notice();
      }
    });
  };

  var notice = function(){    
    var msg = "Hello!!";
    new Notification(msg);
  };

  var init = function(){
    timer();
    chrome.browserAction.setBadgeText({text: 'ON'});
    chrome.browserAction.setBadgeBackgroundColor({color: '#4688F1'});
  };

  init();

})(jQuery);

```

## popup系の作成
popup系のサンプルです。フォームに入力したキーワードをデスクトップ通知にて通知してくれます。

```html:popup.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/popup.css">
    <script src="/lib/jquery-3.3.1.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <div class="form-row align-items-center">
        <div class="col-sm-3 my-1">
          <input type="text" class="form-control keyword" id="inlineFormInputKeyword" placeholder="Keyword">
        </div>
        <div class="col-auto my-1">
          <button type="submit" class="btn btn-primary submit">Submit</button>
        </div>
      </div>
      <script src="/js/popup.js"></script>
    </div>
  </body>
</html>
```

```javascript:popup.js
(function($) {
  var keyword = "";

  var notice = function(){    
    new Notification(keyword);
  };

  var init = function() {
    var submit = document.querySelector('.submit');
    
    submit.onclick = function(e) {
      keyword = document.querySelector('.keyword').value;
      notice();
    };
  };

  init();

})(jQuery);
```

## 作成したchrome拡張をインストールする
作成したChrome拡張をChromeで実行してみましょう。Chromeの設定画面から、拡張機能をクリックします。
![option.png](https://qiita-image-store.s3.amazonaws.com/0/366054/3dda7cc6-1cb2-7477-9914-5821ec75f5da.png)
画面右上、デベロッパーモードのボタンをクリックするとすぐ下にメニューが追加されます。
「パーケージ化されていない拡張機能を読み込む」をクリックし、作成した拡張機能のフォルダを選択すると一覧に追加されます。
![option2.png](https://qiita-image-store.s3.amazonaws.com/0/366054/de9ee58d-4896-1ef2-624e-b4d4f4ee133d.png)

インストールした時点でbackgroundスクリプトの処理が実行されます。

## デバッグ方法
### background.js
一覧に表示されている「ビューを検証」リンクをクリックすると、backgroundに対しDeveloper Toolが起動するのデバッグを行うことができます。

### option.html
Chrome拡張の詳細を表示すると「拡張機能のオプション」メニューがあるので、クリックすると画面が表示されデバッグを行うことが可能です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366054/6468ce1e-cc50-cd60-3483-a45dd0e81575.png)

### popup.html
メニュー等から標示することはできないので、ブラウザに以下を入力することでDeveloper Toolにてデバッグを行うことが可能です。

```
chrome-extension://{エクステンションID}/popup.html
```

エクステンションIDとは一覧または詳細に表示されているIDのことです。上記の方法でoptionのページを表示することも可能です。

## ストアへ公開
作成したChrome拡張はストアに公開することができます。以下参考です。

https://developer.chrome.com/webstore/publish
https://qiita.com/sqrtxx/items/19fd2114430e9e1fb57f

## ソースが丸見え問題
chrome拡張のソースはローカルのフォルダを覗くと丸見えなので、ソースをいじることができればほかの人が作成した拡張機能をさらに拡張することも可能です（ストアに公開はできないと思いますが）。ソースが丸見えなので、重要な情報はソースに書かない要注意が必要です。

様々なChrome拡張をインストールして中身を見てみるとどういう風に作ればいいかもわかるので、色々見てみるのもいいでしょう。悪意のあるものをインストールしない様に注意しましょう。以下参考です。

https://qiita.com/samuraijap/items/56baecaeda730e8a6e5c
https://loumo.jp/wp/archive/20170125180001/

## 終わりに
作成すること自体はHTML・CSS・Javascriptの知識があれば作成することができます。修正は必要ですがCordova（元はPhoneGap）等を使用すると、少ない変更でクロスプラットフォームのアプリ等も作成できそうなので、そちらの方も作成してみようと思います。

英語を雰囲気でしか読めない私にとっては、ドキュメントが英語というのが少し大変でした。日本語で書かれた記事等も結構あるので参考になりました。JSフレームワーク等を使用することも可能なので、色々作成して見るといいと思います。