自己紹介
こんにちは。竹川です。@tttyya
2020年4月1日より新卒としてChatworkに入らせていただきました。
サーバーサイド開発部(Scala)にて、やらせてもらってます。
Chrome拡張作り始めたキッカケ
同じScalaチームの先輩と、
「Chatworkに新機能が付くならどんな機能が欲しい?」という雑談をしていました。
とある機能の話になったとき、
「この機能、軽くChrome拡張で実装してみたことあるんですけど」
と涼しい顔で画面共有しながら自慢してきました。
「軽く!!!????Chrome拡張で機能を追加!!!??」とビックリ仰天。
それは、機能としてしっかり動作していて、こんな立派なものが軽く作れるの???Chrome拡張スゲーーーー!!!と思いました。
何を隠そう、わたくし竹川、フロントエンドは知識も経験もほぼ一切ないのです。
どれくらいの工数で、どれくらいの苦労で実装されたのか。そう軽く作れるものなのか。
わからない…わからないならやってみよう。
さぁ竹川も軽くChrome拡張を作ってみよう。というのがキッカケです。
目次
何を作ろうか
Chatwork株式会社では、Chatworkを使用して連絡をとっています。
Chatworkを使用しているうちに、竹川が欲しいと思った機能はこちらです。
- To一覧を開くショートカットキー
- グルーピングして、まとめてToする機能
それぞれの説明をいたします。
To一覧を開くショートカットキー
キーボードから極力手を離したくない。マウスを使いたくない。
エンジニアなら誰しもがお思いでしょう(思わない人もいると思います)
現在、Toの一覧を開くショートカットキーがありません。
ショートカットキーでTo一覧が表示できれば、ハッピーになれますね。
グルーピングして、まとめてToする機能
Chatworkの社員数が150人を超えました。
社員数が増えるたび、比例してチャットの人数は増えていっています。
そして、社内には様々なチャットは存在しています。
社員全員が参加する共有チャットや、
Scalaチーム、PHPチーム、SREチームが参加する開発チャットなど。
開発チャットでは、ScalaチームにだけToしたい。という機会が多々あります。
検索機能があるとはいえ、数十人の中から、数人を選ぶ作業は、ちょっと大変です。
一気にドカンと、Scalaチーム全員をToできたらハッピーですね
結論
どっちも欲しいのでどっちも作りましょう。
技術選定
jQueryを検討しましたが、
jQuery使ってるとか(笑)みたいなノリをインターネット上で多く見受けられました。
なのでjQueryは使いません。
軽く実装するだけなので、生のJavaScriptでいいんじゃないか?
逆に生のJavaScriptで書くほうがカッコいいんじゃないか?
という厳正なる審査の結果、生のJavaScriptで書くことにしました。
Chrome拡張作成準備
今回のプロジェクト名はchatwork-to-extensionとします。
ChatworkのToの拡張だからです。
必要なモノ用意
- /chatwork-to-extension
- content.js (これは好きな名前でいい)
- manifest.json
content.js
読み込むJavaScriptファイルです。
とりあえず中身は空でOK。
manifest.json
Chrome拡張の設定ファイルです。
これを用意することで、Chrome拡張としてChromeに読み込ませることができます。
{ "manifest_version": 2, "name": "Chatwork To Extension", "short_name": "CTE", "version": "1", "content_scripts": [ { "matches": [ "https://www.chatwork.com/" ], "js": [ "content.js" ] } ] }
それぞれのパラメータについての説明は以下です。
- manifest_version
- 2じゃないとダメらしいです
- name
- 作るChrome拡張の名前。好きにしていい
- short_name
- 作るChrome拡張の名前の省略形。好きにしていい
- version
- 作るChrome拡張のversion。とりあえず1でいい
- content_scripts.matches
- JavaScriptを適用したいサイト
- 今回はChatworkでのみ拡張を適用したいのでChatworkのURLを指定
- content_scripts.js
- 適用したいJavaScriptを指定
- matchesで指定したURLに適用される
↓ 詳しい設定方法は下記に載っています。
Chromeで読み込む
chrome://extensions/ をChromeのURLにコピペするか、
右上の三点リーダから、[その他のツール] -> [拡張機能]と開きましょう
左上にパッケージ化されていない拡張機能を読み込むというボタンがあるので、そちらをクリック
あとは先程作成したフォルダを選択すると、拡張機能の一覧に自分の拡張機能が出てきます。
これで、拡張機能として、Chromeに設定することができました。
manifest.jsonで設定したとおり、https://www.chatwork.com/ にアクセスしたとき、content.jsが読み込まれるようになります。
試しに、アクセスするとalertが出るコードを書いてみましょう。
alert('Chrome拡張だよ')
更新ボタンを押すと、コードが再読み込みされます。
コードを更新した際は、必ず押すようにしましょう。
更新したならば、早速アクセスしちゃいましょう🎶
https://www.chatwork.com/ ←クリック
アラートが出たら、読み込めてると言うことです。やったー。
これでChrome拡張を書く準備はできました。
To一覧を開くショートカットキー
てなわけで作りました。
その時点でのコードです
10行にも満たない、それはそれは小さなコードでした。
// DOM読み込むのを待つ(2000は適当な数値) window.onload = () => setTimeout(listener, 2000); function listener() { window.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 't') document.getElementById("_to").click(); }) }
コードの説明をします。
// DOM読み込むのを待つ(2000は適当な数値) window.onload = () => setTimeout(listener, 2000);
こちらのコードでChatworkのDOMが生成されるのを待ちます。 わからないですけど、大体2000msも待てば大丈夫だろうというので2000を指定しています。 アクセスしてから、2000ms後に、listener関数が実行されます
function listener() { window.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 't') document.getElementById("_to").click(); }) }
こちらは、ctrlキーと、tキーが同時に入力された場合、_to
というidがついた要素をクリックする、という動作になっています。
_to
というidはどうやって調べたの?という話ですが、
(macでは)command + shift + c
を押してから、要素をクリックすると、クリックした要素のhtmlを表示してくれます。 (便利〜〜〜)
To一覧を開くには、_to
というidのついた要素を取得して、クリックすれば良いんだ。ということがわかります。
document.getElementById("_to").click(); // `_to`というidのついた要素を取得して、クリックしている
簡単ですね〜〜〜
Chrome拡張のイロハはこれで大丈夫です。
この知識を生かしてグルーピングして、まとめてToする機能もパパっと気楽に作っちゃいましょう。
グルーピングして、まとめてToする機能
てなわけで作りました。
すげーーーよChrome拡張。
たったの800行、たったの2,3週間の休日を全て費やすだけで新しい機能ができちゃった。
説明できる行数ではないので、アーキテクチャだけ紹介します。
矢印は依存の方向です。
- listener
- さっき作ったlistener関数です
- DOMApplier
- DOMBuilderで作ったDOMを適用するヤツです
- DOMBuilder
- DOMの生成をするヤツです
- BuildByDOM
- DOMからModelを組み立てるところです
- DOM操作部分は、どうしても汚くなってしまうので、こちらに集約しました
- Model
- ビジネスロジックを集約するためのヤツです
- DBからの取得、保存もコイツがやります
- chrome storage(DB)
- 拡張機能用のデータを保存するストレージです
- object形式で保存することが出来ます。
- 詳しくは → chrome.storage - Google Chrome
DOM操作は副作用の塊なので、とてつもなく消耗しました(;_;)
(DOM操作するときの、オススメなアーキテクチャがあれば、ぜひご紹介いただきたいです。)
感想
このように、Chrome拡張でも作る機能によってはデカい工数がかかってしまいます(それはそう)
また、800行というドデカいJavaScriptファイルが出来てしまったので、
ファイル分割できるようにライブラリを入れたりフレームワークを入れたりしたほうが多分幸せだと思います。
僕は生のJacaScriptでファイル分割が出来ないということを知らなかったです(;_;)
まとめ
このように、簡単に自分の好きなサイトを好きなように拡張することが出来ます。
みなさんも自分の使っているサイトを、便利に拡張してみてはいかがでしょうか。
僕は疲れたのでしばらくはいいです。