初めてのChrome拡張機能としてGitHubでStarをつけたリポジトリをタグで管理できる機能を作った


# まえがき

Chrome拡張機能の作り方を説明している記事では**ありません**。

初めてChrome拡張機能を作ろうとした人が、
何を参照し、どこにつまづいたか、どんな手順で開発したのかを**体験記**と思って読んでください。（あとOSSの宣伝です...）

作ったものは[GitHub](https://github.com/s1r-J/octotag-for-stars)にあります。
よければ[Chromeウェブストア](https://chrome.google.com/webstore/detail/octotag-for-stars/ifdojicohdfelfppfdkpkidpgkhdhccb?utm_source=chrome-ntp-icon)からダウンロードして利用してみてください。

## 作ってみての感想

* JavaScript、HTML、CSSが書ければ簡単に作ることができた
* テストが簡単
* アイコンやらstoreでの表示など画像がやたらと必要で面倒くさかった
* 公開するには$5かかった

## 動機

GitHubでせっかくStarをつけたリポジトリをタグなどで管理しようとしましたが、イマイチ使い勝手が悪く...[^1]
ならつくってみるか！！と始めてみました。

# 作る前に

必要な実装は以下の3つと考えて、調査をしました。
1. DOMを注入する
2. 注入したDOMでボタンとかが動く
3. タグのデータをどっかに保管する

そもそもChrome拡張機能が何でできているかさえ知らなかったので、こちらの記事を読みました。

* [Chrome拡張の開発方法まとめ　その1：概念編](https://qiita.com/k7a/items/26d7a22233ecdf48fed8)

なんとなく、以下のことを理解しました。

* JavaScript、HTML、CSSが書ければいけそう
* マニフェストファイル：どのウェブサイトで実行されるのか、どんなファイルがあるのかなどを説明するファイル
* Content Scripts：プログラムの本体
* Background Script：Content Scriptでできない処理をやらせるプログラム（必須ではない）
* popup.html：ブラウザの右上にできるアイコンをクリックしたらでるページ

# ファイルを用意する

必要そうなファイルを作成し、動かしてみればわかるだろうというゴリ押しスタイルで開発をはじめました。
とりあえず、必要なファイルを用意しました。

* `manifest.json`（マニフェストファイル）
* `js/main.js`
* `js/background.js`
* `css/style.css`
* `popup.html`

# 実装のTIPS
## マニフェストファイル

この記事を見ながら書きました。

* [Chrome 拡張機能のマニフェストファイルの書き方](https://qiita.com/mdstoy/items/9866544e37987337dc79)

とりあえずコンソールにログを出すだけなら、あまり難しいことはないです。
DOMを追加する、データを読み書きするための追加は後述します。

## Content Scripts

以下の記事を見ながら書きました。

* [Chromeのオリジナル拡張機能を開発しよう（ソースコードあり）](https://liginc.co.jp/web/tool/browser/163575)
* [超最低限の Chrome エクステンションを開発しウェブストアで公開するまでの手順](https://qiita.com/otchy/items/e29bf2e377c5b7ddc2f7)

### データの読み書き

タグのデータを保存するため、Chrome拡張機能で提供されている機能を使います。
公式が一番わかりやすかったです。

* [Storage APIs](https://developer.chrome.com/apps/app_storage)

重要なことは`manifest.json`に以下のことを書き込むことです。

```JavaScript:manifest.json
"permissions": [
    "storage"
]
```

### DOMの注入

jQueryを利用しました。
普段はCDNを利用しているのですが、URLが含まれたDOMはセキュリティポリシーに違反するため、注入したりなどができません。

jQueryをダウンロードし、`js/lib/jquery-3.3.1.min.js`として配置しました。
さらに、Content Scriptsとして利用するファイルであることを宣言するため、マニフェストファイルを編集します。
これで`main.js`でjQueryが使えます。

```Javascript:manifest.json
"content_scripts": [
    {
        "matches": [
            // 略
        ],
        "css": ["css/style.css"],
        "js": [
           "js/lib/jquery-3.3.1.min.js", // これを追加する
            "js/main.js"
        ]
    }
],
```

## CSS

GitHubのheadタグにlinkタグでスタイルシートを入れましたが、そのhrefにはひと手間加える必要があります。

普通にパスを書いてしまうと、GitHubのパスを指定することになります。
拡張機能のファイルを探してもらうためには、`chrome.extension.getURL('<Your file path>')`といったようにし、`manifest.json`にそれらのファイルへのアクセスを宣言することが必要です。

```JavaScript:js/main.js
$('head').append($('<link>', {
    rel: 'stylesheet',
    href: chrome.extension.getURL('css/style.css'),
}));
```
```JavaScript:manifest.json
"web_accessible_resources": [
    "*.css"
],
```
### FontAwesome

アイコンなどの利用するため、[FontAwesome](https://fontawesome.com/)を利用しました。
こちらもCDNは利用できません。
ダウンロードして必要なファイルを配置、`manifest.json`へ書き込みます。

* `css/all.min.css`
* `webfonts`: ディレクトリごと配置します

`webfonts`以下に存在したファイルの拡張子を全部書きました。[^2]

```JavaScript:manifest.json
"web_accessible_resources": [
    "*.css",
    "*.eot",
    "*.svg",
    "*.woff",
    "*.woff2",
    "*.ttf"
],
```

## popup.html

フィードバックなどが欲しかったので、GitHubへのリンクを書いただけでした...

## background.js

なにか処理させようとしましたが何もなかったので、
ファイルだけ作成して中身は1文字も書きませんでした...

# テストする

とりあえずの段階でも、ローカルの環境で拡張機能をテストしました。

1. Chromeを開き、URLに`chrome://extensions/`を入力します。
2. 右上のデベロッパーモードをONにします。
3. 「パッケージ化されていない拡張機能を読み込む」をクリック、拡張機能を作成しているディレクトリを選択します。

![chromedev.PNG](https://qiita-image-store.s3.amazonaws.com/0/182261/e4da550a-1c89-ba1d-2aef-3df4580da7ca.png)

不足している項目がある、セキュリティポリシーで利用できない機能についてはエラーや警告として表示されるのでわかりやすいです。
また、ブラウザの違いを考えない（Chromeだけに対応するなら）ため、楽ちんでした。

# 公開する
## アップロード準備

マニフェストファイル、Content Scripts以外に、いくつかのサイズのアイコンが必要なので用意しましょう。上記の記事に必要な画像は説明されています。
アップロードするには、これらをすべて含めたzipにする必要があります。
Lhaplusでもなんでもお好きにzipに圧縮してください。
ChromeのデベロッパーツールONで出てきた「拡張機能をパッケージ化」ではないので注意。

## アップロード

chromeウェブストアに行き、歯車をクリック、「デベロッパーダッシュボード」をクリックします。
![store.PNG](https://qiita-image-store.s3.amazonaws.com/0/182261/13a285bc-6417-9c1b-7331-ea2a7389ee6e.png)

「新しいアイテムを追加する」をクリック、指示にしたがってファイルのアップロード、入力をおこないます。

特に面倒なのがストアに表示するための画像などが必要になることです。

## お金をはらう

諸々入力し、最後になると登録手数料が求められます。これは一回きり、他の拡張機能や現在の機能を更新しても再度払う必要はありません。

![payment.PNG](https://qiita-image-store.s3.amazonaws.com/0/182261/00cdcd1e-0e6a-ae7f-e080-cc667e9a8ec3.png)

# おわりに

繰り返しになりますが、この記事は拡張機能をつくったという**体験記**にすぎません。

Chrome拡張機能を一度でも作成した方にとっての新規な内容は無いと思います。
これから初めて挑む人が参考にして、一つでも不安やひっかかる点が解消されればと思い、書きました。

よい日々を。

[^1]: https://github.com/artisologic/github-stars-tagger , https://github.com/gabrielgodoy/github-stars-manager など
[^2]: 正規表現で`webfonts`以下のファイルという指定のほうがよかったと思う。