Chrome拡張機能を作ってみる

前記事同様、この記事はZennに書いてましたが、難易度的にはQiita向けっぽく思えてきたため、こっちにもも同じもの投稿してちょっと反応見させてもらいます

普段使いのブラウザを自由にカスタマイズできると便利そう
バニラJS経験の多い人間として何ができるか
世にプロダクト出すとして、ササッとお出しできるものはなにかないか

このあたり考えて調べたた結果「Chrome拡張機能作ってみるのが良さそう」という結論に達したので、まず簡単なものから作ってみて、方法を掴んでいくことにしました

# TL;DR
非常に簡単なChrome拡張機能を作る
自分のところにだけ読み込んで試す
これらを通じて実装方法を学ぶ

-----
## 要件定義
拡張機能については、backgroundとか色々ファイルが必要になるということだが、基本的には `manifest.json` （バージョン番号とか、構造をChromeに知らせるとか）と `content.js` （機能を記述）の2つがあれば事足りる、らしく

今回の「簡単に作る」ということから、単にURLを見てなにか返す、くらいでいいか、となったため
「開いているページのURLが `http://` ＝SSL非対応であればポップアップで警告を出す」
だけの簡単なものにする、と決定しました

## 設計
どシンプルなので内部も外部もなく設計
`location.protocol` でプロトコル情報（http://, https:// ）が取れるので、

```js
if(location.protcol === "http:") alert("警告で表示する内容");
```
コードについてはこれだけで事足りると考えました

が、後で `manifest.json` を作成する時に、動くページのURL書式を設定できる（後述、 "content_scripts" の "maches" ）とわかり、こっちにhttp:のページだけで動くようにすればこのif文すらいらないとわかり、後述のようにかなりシンプルな形になりました

あとは `manifest.json` に、だいたいテンプレ通りな記述を入れれば済むのでコードを実際に書いていきます

## 作成
結局記述としては以下のような形に

```js:content.js
(function (window, document) {
  alert("Here is not HTTPS!");
}) (window, document);
```
（即時関数にしているのは自分の手癖）

```json:manifest.json
{
  "name": "httpAlert",  //拡張機能の名前
  "version": "1.0.0",
  "manifest_version": 2,
  "description": "Notice alert in not https pages.",  //拡張機能の説明
  "content_scripts": [{  //動作対象ページ指定したいときとか
    "matches": ["http://*/"],  //動作対象ページのURL書式
    "js": [
      "content.js"  //動かしたいJSファイル
    ]
  }]
}
```
コメント無いところはほぼこのままでOKな箇所（バージョン番号なので今後変わる可能性はもちろんあり）
ここで動作対象ページをURLで指定できるので、非SSLページのみにすることで、 `content.js` でのif文がいらなくなりました

## テスト・実装
単体テスト的なもの（コード問題ないか試す）のはChrome開発者ツールでできたため、早速実装へ

![Extention0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/867b051d-3647-bde8-a969-d1c4bee7be2c.png)

「拡張機能を管理」から「パッケージ化されていない拡張機能を読み込む」を選び、読み込み対象フォルダとして、作成した拡張機能のフォルダを選択しました
が、
![Extention_error1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/8a1db5ee-069e-62a5-fe67-0676f5aa8fb4.png)
ここでエラー発生

「マニフェストファイルが見つからないか読み込めない」とのことですが、これについてはフォルダの構成を以下のようにしていたことが原因でした

```
httpAlert
└ src
   ├ manifest.json
   └ content.js
```
うっかり `src` フォルダなんか作ってその配下に各ファイルを置いたせいでマニフェストファイルが読み込めない状態になっていたようです（「httpAlert」フォルダを選んで読み込ませていた）

```
httpAlert
├ manifest.json
├ content.js
└ src
```
フォルダ構成を上記のように変更することで対応完了（srcフォルダはカラであり、残しておく意味はない）
が、この状態でもまだエラーが発生しました
![Extention_error2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/27ebf1fc-2a7f-591e-c5f5-fab0cecd7a7c.png)

今度は「マニフェストファイルが（見つかりはしたが）読み込めない」ということで
ファイル書式の間違いなのかどうか調べ、記述を見返したところ、 "matches" が以下のようになっていたことが判明

```
"matches": ["http://*"],
```
どうやら最後に `/` が無いと、matchesの記述として適切でないらしく
前述の記述（完成版）の通り、最後に `/` を足すことでちゃんと読み込まれ、追加されるようになりました
![Extention1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/0afdd7f8-830c-af3a-34b1-2dec015650d4.png)

よかったよかった

-----
実際に確認してみると、ちゃんとSSL非対応のページで動くのがわかります
![Extention2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/0b7daa28-d53f-32b0-2bc9-a7b2a5ebccdd.png)

よくベンチマークに使われる某氏のページが http:// で始まるので確認に使用

これにて実装ヨシ！


# 学び
・とりあえず `manifest.json`と `content.js` があれば拡張機能は作れる
・`manifest.json` はだいたい定形でもOK（用途による）、matchesのURLの最後に `/` が要る
・`manifest.json` はフォルダ直下に置く必要がある
・`content.js` に動作を書く
あたり

特に邪魔になるものでも無いのでそのまま入れ続けてます
Chromeが非SSLページに警告出すようになって既に2－3年くらい経ったと思いますが、たまにこのAlert出て、「あ、ここSSL非対応なのか」と気づくことが多く（TTFCとか）

とりあえず作り方はわかったので、次は（こんなものでも）ストアに並べるか、もう少し複雑なものを作ってみるかしてみようか