Help us understand the problem. What is going on with this article?

Chromeブラウザの拡張機能を作ってみたい初心者向けに開発方法を紹介!【サンプルあり】

先日、初めてアドベントカレンダー(クソアプリ2)に参加しました。

そこでたっくさんの面白いサービスと巡り会ったのですが、拡張機能を作っていらっしゃる方が多い!!!ブラウザをハックしている感あって、めっちゃ面白そう!

ってことで、自分も拡張機能に初トライしたのですが、概念や作り方に慣れるまで四苦八苦…。

そこで今回、拡張機能を作りたいけど一歩踏み出すのに苦労している方に向けて、自分の経験も踏まえながら、作り方をまとめてみました。サンプルソースも添えてあります。

少しでも参考になれば幸いです!

※もし間違えやご指摘などございましたら、コメント頂けると嬉しいですm(_ _)m

※githubに簡単なサンプルをupしたので、こっちもチェックしてみてください!
gurutaka/extensions_hundsOn

使用する言語

  • html
  • css
  • JavaScript

設定ファイルが必要!

拡張機能を作るにあたって、manifest.jsonが必要になります。ソースはこんな感じ!

manifest.json
{
    "manifest_version": 2,
    "name": "",
    "description": "",
    "version": "1.0",
    "icons": {
        "32": "icon_32.png",
        "48": "icon_48.png",
        "128": "icon_128.png"
    },
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*" ],
        "js": ["content_scripts.js"],
        "css": ["content_scripts.css"]
    }],
    "background": {
        "scripts": ["background.js"]
    },
    "browser_action": {
        "default_icon": "icon_32.png",
        "default_title": "",
         "default_popup": "popup.html"
    },
    "permissions": [
        "tabs",
        "background",
        "http://*/*",
        "https://*/*"
    ]
}

参考:【結構簡単】ブラウザアクションボタン発火の自作Chrome拡張機能の作り方&サンプル

色々な設定がありそうで複雑にみえますが、ご安心ください。開発にあたって、特に重要なのは、この3つです!

  • default_popup
  • background
  • content_scripts

上記3つが拡張機能の処理に大きく関係してきます。こちらについて、説明していきます。

※manifest.jsonの設定や用語を網羅した超わかりやすい解説を知りたい方は、こちらをチェックしてみて下さい!
参考:Chrome 拡張機能のマニフェストファイルの書き方

browser_actionpage_actionに変更することも可能です。もしくは書かない選択肢もあります!

処理の流れやイメージ

まず、噛み砕いてみた用語の説明から!

  • default_popup:拡張機能のポップアップ(まんま)
  • content_scripts:開いているwebページに影響するscript
  • background:content_scriptやdefault_popupとの連携(イベント)

default_popupの一例が下図です!拡張機能をクリックして表示されるポップアップを意味しています。ここのscriptは、popup内の世界で動いています。
スクリーンショット_2018-12-30_15_48_12.png

一方で、content_scriptsは開いているブラウザで動くscriptです。

例えば, content_scriptscssでバックグラウンドを黒、jsでDOMを差し込むと、開いているブラウザの背景が黒くなります!

スクリーンショット_2018-12-30_16_31_10.png

manifest.json
{
  "name": "BaclkgroundColor",
  "manifest_version": 2,
  "version": "1.0",
  "browser_action": {
    "default_title": "BaclkgroundColor"
  },

  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "css": ["content_scripts.css"],
      "js": ["jquery.min.js", "content_scripts.js"]
    }
  ]
}

content_scripts.js
$("body").prepend('<div class="txt">Hello World!</div>');
content_scripts.css
body {
  background-color: black;
}

.txt {
  color: white;
  font-size: 50px;
}

ここで1つの問題が…。

どうやって、連携するの???

例えば、ポップアップ内のボタンをクリックして、ブラウザの背景を黒くする処理をやろうとしても、上記の処理だけではできません。

そんな時に使うのが、chrome.* APIです!APIを使うことでscript間の連携ができます。処理のイメージ図がこちら!

スクリーンショット 2018-12-30 21.52.01.png

backgroundcontent_scriptsなどで制約されているAPIを使う時などに重宝します!

chrome.* APIでメッセージのやり取りをする!

chrome.*には色んなモノがありますが、最も基本的なのはsendとlistenを使ったメッセージのやり取りです!

以下が簡単なテンプレと意味合いになります。またイメージできるようなgif動画も紹介しています。

send.js
//変数sendをメッセージで送る
chrome.runtime.sendMessage(send, function(response) {
   console.log(response);//メッセージの受け手がレスを返したときキャッチできる
});
listen.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
  console.log(msg);//送られたメッセージをキャッチ
  sendResponse(response);//sendResponseでmsgを送ったスクリプト側にレスを返せる
});

api_res_check.gif

このgifはポップアップのボタンを押すことで、メッセージが送られます。そして、バックグラウンドでメッセージをリッスン。その後、送り手にレスを返すプログラムになります。

このようにchrome.* APIを使えば、スクリプト間でやり取りができます!
(ディベロッパーツール@左:バックグラウンド, 右:ポップアップ)

manifest.json

{
  "name": "API_SAMPLE",
  "manifest_version": 2,
  "version": "1.0",
  "browser_action": {
    "default_title": "API_SAMPLE",
    "default_popup": "popup.html"
  },

  "background": {
    "scripts": ["background.js"]
  }

}
popup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <script src="jquery.min.js"></script>
    <style>
      body {
        width: 100px;
      }
    </style>
  </head>
  <body>
    <button id="btn">helloと伝える!</button>
    <script src="popup.js"></script>
  </body>
</html>

popup.js
  $("#btn").on("click", () => {
    chrome.runtime.sendMessage({ greeting: "hello" }, function(response) {
      console.log(response);
    });
  });

【注意】ファイルによって使えないコマンドあり

厄介なことに、スクリプトによってchrome.* APIの一部コマンドが使えない場合があります。これは随時、ググりながら確認するしかありません。

例えば、上記のchrome.runtime.sendMessageでポップアップからmsgを送っても、content_scriptsには届きません。この時は、chrome.tabs.querychrome.tabs.sendMessageを使って、msgを送ります。

ポップアップ内のボタンを押して、ブラウザのバックグラウンドを黒にしたい場合は、こんなソースになります!
color.gif

manifest.json
{
  "name": "SAMPLE_2",
  "manifest_version": 2,
  "version": "1.0",
  "browser_action": {
    "default_title": "SAMPLE_2",
    "default_popup": "popup.html"
  },

  "content_scripts": [
    {
      "js": ["jquery.min.js", "content_script.js"],
      "matches": ["http://*/*", "https://*/*"]
    }
  ]

}
popup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <script src="jquery.min.js"></script>
    <style>
      body {
        width: 100px;
      }
    </style>
  </head>
  <body>
    <button id="black">背景を黒にする!</button>
    <button id="red">背景を赤にする!</button>
    <script src="popup.js"></script>
  </body>
</html>

popup.js
$("#black").on("click", () => {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {
      color: "black"
    });
  });
});

$("#red").on("click", () => {
  //送れない!!
  // chrome.runtime.sendMessage({ color: "red" });

  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {
      color: "red"
    });
  });
});

content_script.js
chrome.runtime.onMessage.addListener(function(msg) {
  $("body").css("background-color", msg.color);
});

何か動かないな…と思ったら、指定したscriptでは動かないかも…?と怪しんでみてください。
(私はこの事実に気づかず、半日くらい消耗しました爆)

デバッグの方法

意外に曲者なのがデバッグです!図で解説していきます。

まずchrome://extensions/をブラウザで開いて、拡張機能のファイルを読み込みましょう!
スクリーンショット_2018-12-30_17_12_52.png

ポップアップのデバック

スクリーンショット_2018-12-30_17_16_25.png
スクリーンショット_2018-12-30_17_16_33.png

content_scriptsのデバック

ブラウザのディベロッパーツールでチェック!
スクリーンショット_2018-12-30_17_20_44.png

バックグラウンドのデバック

スクリーンショット_2019-01-03_20_14_09.png

スクリーンショット_2018-12-30_17_25_08.png

キャッシュ残るので注意!

デバッグする際はキャッシュを無視してリロード(スーパーリロード)しましょう(cmd + R + shift)

キャッシュが残っていると、更新が反映されない場合があるのでお気をつけください。

最後に

初めてグーグル拡張機能の開発したい方向けに、作り方をまとめました。開発の参考になれば幸いです!

神すぎる参考URL

おまけ:初めて作った記念すべき拡張機能

四季を代表するアイコン(桜、葉、紅葉、雪)がブラウザ上を舞い落ちる拡張機能を作りました!(自己満 オブ 自己満)

リリースもしましたので、ぜひ遊んでみて下さい!
Chrome 拡張機能:四季
kakucyou.gif

guru_taka
ぐるたかです。0→1を作る人に憧れ、2018.10からプログラミングを学び、今はとある会社で、webサービスを開発中。家ではARアプリやwebサービス、拡張機能など色々と個人開発してます。前まではUnityに夢中でしたが、最近はNuxtにハマっています。代表作はおっぱい関数ジェネレーターと塗り絵AR。
https://gurutaka-log.com/
admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。
https://admin-guild.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした