😢

ブラウザ拡張機能を作成するためのテンプレートをつくった

2021/07/25に公開
  • parcel
  • TypeScript
  • Optionページ、Popupページのホットリロード(HMR)
  • refine-githubを参考にした拡張しやすいアーキテクチャ

これらの機能を搭載した最小構成のブラウザ拡張機能テンプレートを作成しました。
Chromeのみで動作確認をしています。

https://github.com/HikaruEgashira/browser-extension-ts-template

ブラウザ拡張機能を作成するには?

まずはmanifest.jsonの仕様を把握する必要がありそうです。

manifest.jsonのプロパティで、拡張機能でできることの全体像を把握することができます。

以下にchromeとfirefoxの公式ドキュメントを示しています。

https://developer.chrome.com/docs/extensions/mv2/
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions

  • ブラウザ全体に必要な権限(タブやストレージ)はbackground
  • ページにスクリプトを挿入するときにはcontent-script

など、セキュリティなどの観点からいくつかの制約があります。

manifest.jsonについては上記のドキュメントの他に以下の情報を参考にするといいでしょう。

https://qiita.com/mdstoy/items/9866544e37987337dc79

また最近発表されたmanifest V3については以下の情報を参考に移行すればいいと思います。

https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/

Parcelでの開発

Parcelはゼロコンフィグで高速な開発を行うのに非常に便利なバンドラーです。

https://v2.parceljs.org/

拡張機能を作成するときにはwebpackを利用するのが一般的ですがコンフィグが複雑なので、慣れが必要です。

シンプルな例ですと、HTMLでTypeScriptとScssを利用した開発を行いたいときは、

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="./style.scss" />
  </head>
  <body>
    <img src="./images/header.png" />
    More content: <a href="./other.html">Link to another page</a>.

    <script type="module" src="./index.ts"></script>
  </body>
</html>

とそのまま呼んであげると、parcelが解析して自動でコンフィグをインストール・作成してくれます。
キャッシュが効くのでホットリロードも速いです。最新バージョンではSWC(Rust製コンパイラ)を利用しています。

webpackが初めてでwebpackで消耗したくない人は、一度parcelを使ってみるのがいいと思います。

今回はwebextensionのコンフィグを使うので、ベータバージョンのParcelV2を用いています。

fregante/browser-extension-templateの利用

ところで、refine-github(有名な拡張機能OSS)のコアメンテナであるfregante氏によるテンプレートではparcelが利用されています。

https://github.com/fregante/browser-extension-template

このシンプルなテンプレートをTypeScript対応させていきます。

自作テンプレートの作成

https://github.com/HikaruEgashira/browser-extension-ts-template

TypeScript対応

Parcelなのでコンフィグの設定はありません。
jsで書かれたファイルをtsで書くようにして、webextension-polyfill-tsを導入しました。
これにより、chromeにとどまらない規格化した開発が可能となります。

https://github.com/Lusito/webextension-polyfill-ts

feature-toggleの作成

refine-githubを参考に
機能ごとにオンオフの機能をつけました。

import { createFeature } from '../domains/feature';
import * as pageDetect from '../interface/page-detect';

const feature = createFeature({
	name: 'hello',
    description: 'console `hello`',
	include: [pageDetect.isHome],
	init: async option => {
		console.log(`awesome extension is ${option}!`);
	}
});

export default feature;

上記のように機能を作成するとオプションページにてその機能のオンオフができます。

まとめ

これを作成したあとに、もっといいテンプレートをantfu氏がリリースしました。
こちらの紹介はあとで書こうと思います。

https://github.com/antfu/vitesse-webext

Discussion