先日、初めてアドベントカレンダー(クソアプリ2)に参加しました。
そこでたっくさんの面白いサービスと巡り会ったのですが、拡張機能を作っていらっしゃる方が多い!!!ブラウザをハックしている感あって、めっちゃ面白そう!
ってことで、自分も拡張機能に初トライしたのですが、概念や作り方に慣れるまで四苦八苦…。
そこで今回、拡張機能を作りたいけど一歩踏み出すのに苦労している方に向けて、自分の経験も踏まえながら、作り方をまとめてみました。サンプルソースも添えてあります。
少しでも参考になれば幸いです!
※もし間違えやご指摘などございましたら、コメント頂けると嬉しいですm(_ _)m
※githubに簡単なサンプルをupしたので、こっちもチェックしてみてください!
→gurutaka/extensions_hundsOn
使用する言語
- html
- css
- JavaScript
設定ファイルが必要!
拡張機能を作るにあたって、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_action
はpage_action
に変更することも可能です。もしくは書かない選択肢もあります!
処理の流れやイメージ
まず、噛み砕いてみた用語の説明から!
- default_popup:拡張機能のポップアップ(まんま)
- content_scripts:開いているwebページに影響するscript
- background:content_scriptやdefault_popupとの連携(イベント)
default_popup
の一例が下図です!拡張機能をクリックして表示されるポップアップを意味しています。ここのscriptは、popup内の世界で動いています。
一方で、content_scripts
は開いているブラウザで動くscriptです。
例えば, content_scripts
のcss
でバックグラウンドを黒、js
でDOMを差し込むと、開いているブラウザの背景が黒くなります!
{
"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"]
}
]
}
$("body").prepend('<div class="txt">Hello World!</div>');
body {
background-color: black;
}
.txt {
color: white;
font-size: 50px;
}
ここで1つの問題が…。
どうやって、連携するの???
例えば、ポップアップ内のボタンをクリックして、ブラウザの背景を黒くする処理をやろうとしても、上記の処理だけではできません。
そんな時に使うのが、chrome.* APIです!APIを使うことでscript間の連携ができます。処理のイメージ図がこちら!
background
はcontent_scripts
などで制約されているAPIを使う時などに重宝します!
chrome.* APIでメッセージのやり取りをする!
chrome.*には色んなモノがありますが、最も基本的なのはsendとlistenを使ったメッセージのやり取りです!
以下が簡単なテンプレと意味合いになります。またイメージできるようなgif動画も紹介しています。
//変数sendをメッセージで送る
chrome.runtime.sendMessage(send, function(response) {
console.log(response);//メッセージの受け手がレスを返したときキャッチできる
});
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
console.log(msg);//送られたメッセージをキャッチ
sendResponse(response);//sendResponseでmsgを送ったスクリプト側にレスを返せる
});
このgifはポップアップのボタンを押すことで、メッセージが送られます。そして、バックグラウンドでメッセージをリッスン。その後、送り手にレスを返すプログラムになります。
このようにchrome.* APIを使えば、スクリプト間でやり取りができます!
(ディベロッパーツール@左:バックグラウンド, 右:ポップアップ)
{
"name": "API_SAMPLE",
"manifest_version": 2,
"version": "1.0",
"browser_action": {
"default_title": "API_SAMPLE",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"]
}
}
<!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>
$("#btn").on("click", () => {
chrome.runtime.sendMessage({ greeting: "hello" }, function(response) {
console.log(response);
});
});
【注意】ファイルによって使えないコマンドあり
厄介なことに、スクリプトによってchrome.* APIの一部コマンドが使えない場合があります。これは随時、ググりながら確認するしかありません。
例えば、上記のchrome.runtime.sendMessage
でポップアップからmsgを送っても、content_scripts
には届きません。この時は、chrome.tabs.query
とchrome.tabs.sendMessage
を使って、msgを送ります。
ポップアップ内のボタンを押して、ブラウザのバックグラウンドを黒にしたい場合は、こんなソースになります!
{
"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://*/*"]
}
]
}
<!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>
$("#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"
});
});
});
chrome.runtime.onMessage.addListener(function(msg) {
$("body").css("background-color", msg.color);
});
何か動かないな…と思ったら、指定したscriptでは動かないかも…?と怪しんでみてください。
(私はこの事実に気づかず、半日くらい消耗しました爆)
デバッグの方法
意外に曲者なのがデバッグです!図で解説していきます。
まずchrome://extensions/
をブラウザで開いて、拡張機能のファイルを読み込みましょう!
ポップアップのデバック
content_scriptsのデバック
バックグラウンドのデバック
キャッシュ残るので注意!
デバッグする際はキャッシュを無視してリロード(スーパーリロード)しましょう(cmd + R + shift
)
キャッシュが残っていると、更新が反映されない場合があるのでお気をつけください。
最後に
初めてグーグル拡張機能の開発したい方向けに、作り方をまとめました。開発の参考になれば幸いです!
神すぎる参考URL
- Chrome拡張の開発方法まとめ その1:概念編
- Chrome拡張 備忘録 1から10まで
- Chromeのオリジナル拡張機能を開発しよう(ソースコードあり)
- Chrome Extensionの実装方法 初心者向け
- 公式:Chrome APIs(extensions)
- Chrome 拡張機能のマニフェストファイルの書き方
おまけ:初めて作った記念すべき拡張機能
四季を代表するアイコン(桜、葉、紅葉、雪)がブラウザ上を舞い落ちる拡張機能を作りました!(自己満 オブ 自己満)
リリースもしましたので、ぜひ遊んでみて下さい!
Chrome 拡張機能:四季