自作Chrome拡張をManifest V3移行した記録
Mouse Dictionaryという拡張をManifest V3移行した記録です。
前提
Manifest V3とは
既存のChrome拡張は2023年には動かなくなります。Manifest V3に移行しない限り。
Manifest V2 support timelineより
追記: V2廃止は延期されました
そもそもV3って何なの?という話は本題ではないので詳しくは公式ドキュメントや先人の記事をご参照ください。
Mouse Dictionaryは2018年にリリースされた拡張で当然V2でつくられているため、遅かれ早かれV3への移行が必要でした。
(追記)
世間のV3移行状況が気になったので調べました。
クロスブラウザ問題
2022年5月時点ではFirefoxはManifest V3に未対応のため、Firefox版はV2を維持する必要があります。つまり、クロスブラウザな拡張機能はV2とV3への両対応が必要なため、なかなか面倒なことになります。
Mouse DictionaryではChrome版はV3に移行しつつFirefox対応も維持してみたので、似たような境遇の方はぜひご参考ください。
実際の移行
公式移行ガイドがあります。
以下は実際の泥臭い移行の記録。
下準備1: evalの排除
Manifest V3では、eval()やnew Function()への制約が強くなります。
Mouse DictionaryはMustacheエンジンとしてHogan.jsを使用していたのですが、これが内部的にnew Function()を使っていたため、上記Manifest V3の制約にひっかかることになりました。
そこで、Hogan.jsからmustache.jsに移行することでnew Function()を排除しました。
なお、もともとMustacheエンジンとしてHogan.js、mustache.js、Handlebarsを候補としており、(Mouse Dictionaryの用途において)最も高速だったHogan.jsを採用したという背景がありました。mustache.jsも十分高速で互換性も高く問題なく移行できました。
下準備2: ブラウザごとのビルド
Chrome版をV3移行しつつFirefox版も維持したい場合は、全ブラウザ対応用のmanifest.jsonひとつ用意しておく、という方法が不可能になります。Mouse Dictionaryの場合はこんな感じにして、ビルド時に適切なmanifest.jsonがパッケージに含まれるようにしています。
コードや設定の変更
コード
chrome.browserAction -> chrome.action
V3ではchrome.browserActionをchrome.actionに変更する必要があるのですが、逆にV2(Firefox)ではchrome.actionが無くchrome.browserActionを使う必要があるので、クロスブラウザにするにはなんらかの工夫が必要になります。
いろいろ方法はあると思いますが、クロスブラウザ対応する必要があるのはここ一箇所だけだったので、単純にwebpackの定数で分岐するようにしました。あまり大げさな仕組みを入れてもV2がこの世から消えたら無駄になるので、こんな感じで十分でしょう。
if (BROWSER === "CHROME") {
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["main.js"],
});
});
} else {
chrome.browserAction.onClicked.addListener(() => {
chrome.tabs.executeScript({
file: "./main.js",
});
});
}
ちなみにこんな感じにしてもクロスブラウザで動きます。
if (chrome.action) {
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["main.js"],
});
});
} else {
chrome.browserAction.onClicked.addListener(() => {
chrome.tabs.executeScript({
file: "./main.js",
});
});
}
不要な方の処理がビルド時に消え去るという点で、前者の方が少しお得です。
chrome.extension -> chrome.runtime
V2(Firefox)でもchrome.extensionとchrome.runtime両方動くようだったので、こちらは単純に差し替えました。
- const url = chrome.extension.getURL(fname);
+ const url = chrome.runtime.getURL(fname);
manifest.json
permissions
- "permissions": ["storage", "unlimitedStorage", "activeTab"],
+ "permissions": ["storage", "unlimitedStorage", "activeTab", "scripting"],
background
"background": {
- "scripts": ["background.js"],
- "persistent": false
+ "service_worker": "background.js"
},
commands
"commands": {
- "_execute_browser_action": {
+ "_execute_action": {
"description": "Activate the extension"
},
web_accessible_resources
- "web_accessible_resources": ["data/*.json"]
+ "web_accessible_resources": [
+ {
+ "resources": ["data/rule.json", "data/dict*.json"],
+ "matches": ["<all_urls>"]
+ }
+ ]
解決できていない問題
ローカルファイルで動かない (解決済み)
Mouse DictionaryはローカルのHTMLをChromeで開いたやつに対しても使えたのですが、V3移行で使えなくなってしまいました。原因はわかっていて、file:///~ で開いているタブにweb_accessible_resourcesが効かないことなのですが、公式情報が見つからないので、これがV3での意図した変更なのか、Chromeのバグなのかわからず、様子見状態です。
類似現象。
- https://stackoverflow.com/questions/69736887/web-accessible-resources-manifest-key-is-ignored-if-respective-resources-are-i
- https://bugs.chromium.org/p/chromium/issues/detail?id=1264366
(2022年11月追記) 少なくともChrome 107では、この挙動は修正されているようです(いつ直ったのかは不明)(やっぱバグだったんかい)
ショートカットキー設定の挙動がおかしい (解決済み)
Mouse Dictionaryはショートカットキーを設定することができるのですが、V3移行後の挙動がいまいち不安定です。どうも、ショートカットキーを設定してもすぐには反映されず、Chromeを再起動したりすると反映されるようです。これも拡張開発者側でできることがなく、様子見状態です。
(2022年11月追記) 少なくともChrome 107では、この挙動は修正されている気配があります(いつ直ったのかは不明)
Vivaldiでショートカットキーが効かない
効きません。原因はわかりません。他のChromiumブラウザ(Edge, Brave等)では効くみたいなのでますますわかりません。
(2023年8月追記) Vivaldi既知の問題らしいですが、未だになおっていません https://github.com/wtetsu/mouse-dictionary/pull/84
感想
あくまでMouse Dictionaryの場合ですが、変更したコード量は少なめでした。ただしWeb上にManifest V3移行の経験談的な情報がまだ少なく、どのように変更したらV2と同様に動くようになるかの調査・試行錯誤・検証が大変です。
Discussion
このバージョンアップ、実際、ほんとにやるんですかね。
Adblockとか、ScriptAutoRunnerとかが、
V2からV3で軒並み使えなくなりそうというか、
ユーザーにブラウザ上でスクリプトを動かせるような設定をさせないようになってきて
そういうのを締め付けるためにやっているような気もします。
セキュリティと利便性を天秤にかけて、利便性を捨ててセキュリティ側にふろうとしているというかなんというか。
「ほんとにやるんですかね」という感覚はわかります。
世間の拡張のV3移行進行は鈍いし、Googleの拡張もV2のままです。
ちょうど私もv3に移行して今審査待ち状態です。Googleアナリティクスもつかえなくなったしバージョンアップするメリットがありませんでした。 Googleが出してる拡張がv2ってのはひどいですね。。。