シン・Chrome拡張機能を作ってみよう！初めましての人も把握しやすい解説あり

Chrome拡張をこれから始めたい人へ向けてまずはおおざっぱなChrome拡張の仕組みおよび作り方を紹介する記事を作りました。

自分は過去に英語圏のユーザー向けに <a href="https://chrome.google.com/webstore/detail/extension-youtube-player/cfjbdignpheklanjahlbdogdnbaklhig
">Extension Youtube Player</a> というアプリ作ってお試し公開していたりします
（宣伝なしで地味にユーザー数300人超えてた）

記事の中盤からHello Worldアプリを作るレクチャーを載せています。
成果物： https://github.com/yoshisansan/chrome-extension-helloworld

## Chrome拡張機能ってどうやってできているのか（おおざっぱに仕組み、作り方を把握しよう）
Chrome拡張機能の概要についてある程度わかってるよな人はパスして「最低限の構成でHello Worldしよう！」まで飛ばしてみてください。

ご存知のようにChrome拡張機能とはChromeブラウザ専用のアプリになります。
<a href="https://chrome.google.com/webstore/category/extensions?hl=ja">Chromeウェブストア</a>にさまざまなアプリがあります。

基本的にはHTML/CSS/JavaScriptだけで作ることができているのでアプリ開発の中でも敷居が低い方だと思います。
Webサイトを作る基礎知識 + Chrome拡張機能に特有の処理 を把握しておけばすぐに作れるようになります。

ただし公開を想定している場合、一時期は審査がゆるい時期があったそうですが最近は悪意のあるアプリなどを取り締まる流れでどんなアプリでも審査に通るわけではなくなっています。

### Chrome拡張機能に特有の処理とは
・ manifest.json を必ず用意する
・ 主に popup(主にview側)、background(主にscript側)やcontent（主に開いているWebページを操作）の３つに使い分けて処理をかく
・ 色々なメソッドの入ったchromeオブジェクトを使ってデータのやりとりやブラウザ操作などを行う

Chrome拡張機能を作る際にファイルの親に必ず manifest.json というファイルを作り基本的なオプション設定を行います。

JavaScriptに慣れ親しんでいる人であれば package.json をいじったことが一度はあるかと思いますが manifest.json は package.json にあたるようなChrome拡張機能に必ず求められるファイルです。
サンプルとして下にChrome公式サンプルの manifest.json を貼りました。

```manifest.json
{
  "name": "Getting Started Example",
  "description": "Build an Extension!",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  },
  "options_page": "options.html"
}

```
<a href="https://github.com/GoogleChrome/chrome-extensions-samples">GitHub(chrome-extensions-samples)</a>より

ちなみに上記の manifest.json はバージョン3のものです（20年9月よりv3へ）。
バージョン２系の manifest.json で書かれている記事の方がまだまだ多いと思うので混乱しないよう注意しましょう。

manifest.json 3系についての詳細は <a href="https://developer.chrome.com/docs/extensions/mv3/intro/">Welcome to Manifest V3</a> をどうぞ。

"permissions"で許可していない操作が含まれているとうまく動作しない場合や申請が通らないことがあるのでそこも注意ポイント。
（実際に申請する場合は使用していないpermissionsの指定も弾かれる理由の一つとなります。不要なものは削除）

### jQueryやReact,TypeScriptなども使える
当然ですが、HTMLも使えてJavaScriptも使えるためjQueryが使えますし使ったアプリも作ったことがあります。

また、最終的にjsファイルやhtmlファイルへコンパイルすれば良いわけですのでJS系のフレームワーク全般も扱えますし過去に自分はTypeScriptを使ってChrome拡張機能アプリを作ったことがあります。

APIを叩いてくることもできるため自由度は比較的に高いです。

Reactで使いたい人はそれ用の環境構築の記事を用意したのでこっちをどうぞ
 <a href="https://qiita.com/akifumiyoshimu/items/07ef1d28efa1cafcf2f1">Chrome拡張機能を React x TypeScript で作るための環境構築した</a>


### 個人で使用するだけなら審査は不要でそのまま使える
実は過去に作ったChrome拡張機能で審査に弾かれたものがあります。残念ですが個人で使っています。

<img width="240px" alt="STOP-TWITTER" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/b515553d-61d2-96c3-09e6-bdbfbcb2b874.png">

↑弾かれたのはこの指定した時間はTwitterを開けなくするSTOP Twitterというアプリ
<a href="https://github.com/yoshisansan/stop-twitter">GitHubで公開している</a>のでTwitter廃人からそろそろ脱してみたい人は使ってみてください。OSS活動してくれる人も待ってます。

Chromeの"設定" > 左下らへんにある"拡張機能" > "パッケージ化されていない拡張機能を読み込む"によりクローンしたファイル選択で使えます。

### Chrome拡張機能の公開するためのショバ代は５ドルを一回限り
公開するために課金する必要がありますが自分が申請した2020年度は5ドルでした。スタバやチー牛を一回我慢すれば公開できるやすさ！

## 最低限の構成でHello Worldしよう！
実際に手を動かしてみましょう。

（21/11/14追記：popup.htmlのディレクトリの位置を間違えていたので修正しました。親階層に設置しないと読み込みません。ただし、子階層で読み込みたい場合はindex.htmlなどの名前に変えるとうまく読み込めたので名前を変えてみると良いかと。）

```
HelloWorld
 assets
  earth-32px.png
  earth-48px.png
 src
  css
   index.css
  background.js
 popup.html
 manifest.json
```

上記の構成でファイルを作ってください。

```manifest.json
{
  "name": "Hello World",
  "description" : "Chrome拡張機能のテストアプリ",
  "version": "1.0.1",
  "manifest_version": 3,
  "background": {
    "service_worker": "src/background.js"
  },
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "32": "/assets/earth-32px.png",
      "48": "/assets/earth-48px.png"
    }
  },
  "icons": {
    "32": "/assets/earth-32px.png",
    "48": "assets/earth-48px.png"
  }
}

```
↑今回、contentの処理は不要なのでオプション指定なし

```popup.html
<!DOCTYPE html>
<html>
<head>
  <title>Hello World</title>
  <link rel="stylesheet" href="css/index.css">
</head>
<body>
  <p>Hello World!</p>
</body>
</html>
```

```index.css
body {
  width: 200px;
  height: 200px;
}
```

background.jsは一旦空のままにしておきます。
assetsディレクトリ以下の画像は<a href="https://github.com/yoshisansan/chrome-extension-helloworld/tree/main/assets">ここからDL</a>するか、<a href="https://icooon-mono.com/">ICOON MONO</a>より任意の画像をDLして名前変更してください。

## ファイルをブラウザへアップロード
HelloWorldファイルをアップロードすればすぐに使えるようになります。デバッグしながら触れるようになります。

Chromeの"設定" > 左下らへんにある"拡張機能" > "パッケージ化されていない拡張機能を読み込む"でHelloWorldを選択しましょう。

<img width="480px" alt="chrome拡張一覧ページ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/fe0de957-f1be-0662-3d24-89fecd101396.png">


アイコンをクリックすることでHelloWorldが表示されます。

<img width="480px" alt="Hello World画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/e6854c05-20ed-2816-fd40-d3b3f985e3f3.png">

popup.htmlに記述したHTMLが読み込まれています。あとはWebサイト制作と同じ容量でコーディングしていけば好きに装飾できます。

以上がHello Worldに最低限必要なファイル構成でした。

## background.jsを使ってchromeオブジェクトを使ってみる
chromeオブジェクトのメソッドを利用することでさまざまなブラウザ操作が拡張機能より可能となります。

```background.js
chrome.runtime.onInstalled.addListener(async () => {
  const url = chrome.runtime.getURL("src/popup.html");
  const tab = await chrome.tabs.create({ url });
  console.log(`タブのID：${tab.id}`);
});
```

chrome.runtime.onInstalledメソッドはChrome拡張をインストールした直後にイベントを発火させます。
それを利用して popup.html をタブに表示させるスクリプトを公式サンプルを参考に記載しました。
（pupup.htmlでなくとも任意のhtmlファイルを使用できます）

一度　"パッケージ化されていない拡張機能を読み込む" で追加した拡張機能を削除して、再び "パッケージ化されていない拡張機能を読み込む" で追加するとタブが開かれます。

<img width="480px" alt="Hello World画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651103/603bb0a1-a6a1-dcf1-7a3d-2b3f7fa23473.png">


## よく使うメソッド

```
chrome.storage.local
```
↑は拡張機能側でCRUDを実装する場合にローカルへデータを保存する際によく使います。

```
chrome.runtime.onMessage
```
background→popup側やまたはその逆などのファイル間でデータをやり取りする場合に使いました。

その他のメソッドは <a href="https://developer.chrome.com/docs/extensions/reference/">Chrome Developers - API Reference</a> かもしくは <a href="https://github.com/GoogleChrome/chrome-extensions-samples">サンプル</a> を参考にどうぞ。