本記事について
Firefoxのブラウザ拡張がChromeと互換性のあるWebExtensionという形式になったことを知り、FirefoxとChrome両方で動くブラウザ拡張を作ってみた。
これが、自身にとってはじめてのブラウザ拡張開発である。
その作成の過程を記す。
ブラウザ拡張の題材(作ったもの)
ブラウザのアドレスバーに、日本語を含むURLが表示されている場合があるが、そのような日本語を含むURLをブラウザからクリップボードにコピーすると、日本語ではなくURLエンコードされた状態のURLになる。
URLを日本語のままコピーしたいときがあったので、日本語のままコピーできるブラウザ拡張を作成した。
ブラウザ拡張の作成方法をざっと学ぶ
MDN Web Docsのブラウザー拡張機能のページに載っている入門的な記事を読んだり軽く手を動かしたりしながら、ブラウザ拡張の作成方法をざっと学んだ。
- 以下のページをみながら実際に手を動かして、ブラウザ拡張を作成する簡単な流れを把握した
- 以下のページを見て、ブラウザ拡張に必要なもの(ブラウザ拡張の構成要素)を把握した
ブラウザ拡張の実装サンプルから、自分の作りたい拡張に近いものがないか探す
GitHub上にmozillaによるWebExtensionの実装サンプルが公開されている。
この中から、自分が作りたいものと関連ありそうなものがないか探してみた。あれば、そこから実装方法等を拝借できると思ったので。
見つけたのが以下。
https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
予想以上に、自分が作りたいものに必要な要素が含まれているものが見つかった。
とりあえずFirefoxだけを対象に実装を進める
上記サンプルを土台にして、mdnのWebExtensionのページのAPIのページ等を眺めつつ実装を進めて最初のバージョンが完成。
勉強のために、国際化 - Mozilla | MDNのページを見ながら、メッセージ文言は最初からコード内に書かず、messages.jsonに外出しした。(最初は日本語のメッセージしか用意しなかったけれど)
アドオン開発者センターから作成した拡張を登録。
登録した後、公開される前に審査があり若干ドキドキしたが、とくに指摘もなく公開された。
この時点のソースコード: https://github.com/szk0u/copy-decoded-url/tree/v1.0
Chromeにも対応してみる
結論から言うと、mozilla/webextension-polyfill: A lightweight polyfill library for Promise-based WebExtension APIs in Chromeを使用した。
最初は、Firefox向けに作成したものがそのままChromeでも動くと思っていたが、そんなことはなかった。
Chrome との非互換性 - Mozilla | MDNを見て、ChromeとFirefoxの差異を知った。
- MDNを見ながら実装を進めた結果、
browser
というネームスペースを使用して各種APIを呼び出す実装にしていたが - Chromeでは
chrome
というネームスペースを使用して各種APIを呼び出すらしい - 互換性のためにFirefoxでも
chrome
というネームスペースが使用できるみたいなので、browser
と書いている箇所をchrome
に置換すれば良さそうだが、もっと良い方法はないかと思っていると -
browser
を使って書いた拡張機能をChromeでも動かせるようにするpolyfillなるものがあるということなので、このpolyfillを使うことにした
以下の手順でpolyfillを適用し、Chromeでも動作させることに成功。
- https://github.com/mozilla/webextension-polyfill をPC上にクローン
- クローンしてできた webextension-polyfill ディレクトリに移動して
npm install
とnpm build
を実行 - すると、distディレクトリにファイルが作成されているので、その中から browser-polyfill.min.js をコピーして自分のブラウザ拡張のコードベースに追加
- このような感じで、manifest.jsonの background > scripts に browser-polyfill.min.js を追加
ただし一部の機能がFirefoxのみ対応していてChromeでは動作しなかったので、Firefoxの場合のみ当該機能を使用するようにした。
- Firefoxでのみ動作したという機能は、タブを右クリックしたときのコンテキストメニューにメニューを追加する機能
- 実行中のブラウザがFirefoxなのかChromeなのか判定する方法に悩んだが、browser.runtime.getBrowserInfoを使用してブラウザの情報を取得して判定するように実装した。
この時点のソースコード: https://github.com/szk0u/copy-decoded-url/tree/f4bdabc1068e870cd812e896aa1837e8e275ac8f
web-extツールを使ってみる
作成したブラウザ拡張をアドオン開発センターから公開する際、ソースコードをZIPに固めてアップロードする必要がある。
(ZIPコマンド等で固めてもよいのだが)ブラウザ拡張用のパッケージングツールのようなものはないかと思い、調べてみたところ見つかったので、使用してみた。
ツールの名前はweb-extで、以下のページを見ながら使ってみた。
このツールを使うと
- ブラウザ拡張を登録するためのZIP化
- ブラウザ拡張の静的コード解析(lint)
- 開発中の拡張をインストールしたFirefoxの起動
などがコマンドライン操作で実行できる。
web-extツールにはいくつかコマンドラインオプションがある。
それらのオプションは設定ファイルでの指定も可能なので設定ファイルを作成した。
- web-extはカレントディレクトリにある「web-ext-config.js」という名前の設定ファイルを自動で読み取るため、設定ファイルの名前はこの名前にした
最終的にはyarnでweb-extをインストールし、yarn build
でパッケージングしたり、yarn start
で開発中の拡張をインストールしたブラウザを起動するように設定してみた。
(機能追加)アドレスバーにアイコンを表示してみる
ブラウザのアドレスバーにアイコンを表示して、そのアイコンをクリックしたらURLをコピーできるようにした。
pageActionを使用することで実現できた。
ただし、Chromeではアドレスバーにアイコンを表示することはできなかった。
- Chromeでは、昔はアドレスバーにアイコンを表示できたが、現在はツールバーに表示するようになったらしい