動かざることバグの如し

近づきたいよ 君の理想に

Chrome拡張機能 Manifest V3でContentScriptを実行する

マジでダルい

Manifest v3とは

現行ではManifest v2が主だが、現時点で2023年6月に動かなくなると言われている。(絶対ムリだろ

softantenna.com

つまりこれから作るChrome拡張機能はV3対応で書かなければいけないってわけ。

やりたいこと

SPA対応ContentScriptを実装する。

通常のContentScriptではmanifest.jsonを以下のようにして

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.js"]
    }
  ],
  ...
}

でcontentScript.jsを用意すれば実行できるが、これはbodyがロードされたタイミンのみ実行される。

昨今ではSPAで実装されているサイトが多く、その場合だと初回は実行されるが遷移先やブラウザバックしたあとは実行されなくなってしまう。

そこでbackgrorund.jsを駆使したやり方が裏技として一般的だったりする。

mem-archive.com

これのV3対応が面倒だった。

manifest.json

重要な箇所だけ抜き出している

{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.bundle.js"
  },
  "host_permissions": ["https://example.com/"],
  "permissions": ["tabs", "scripting"]
}
  • manifest_version: 当然3を指定する
  • background.service_worker: ファイル名は任意だが書き方がV2と異なるので注意。background.htmlはもう使えない
  • host_permissions: ここではContentScriptを実行したいサイトを列挙する必要がある
  • permissions:「tabs」は今までも必要だったが、それに加えて「scripting」も追加する必要がある

background.js

ここはV2とやっている内容は変わらないが、コードは大きく変わっている。

chrome.tabs.onUpdated.addListener(function (tabId, info, tab) {
  if (
    info.status === 'complete' &&
    tab.url.indexOf('https://example.com') !== -1
  ) {
    chrome.scripting.executeScript({
      target: { tabId: tab.id, allFrames: true },
      files: ['./contentScript.bundle.js'],
    });
  }
});

V2では「chrome.tabs.executeScript」だったが廃止された。V3では「chrome.scripting.executeScript()」を使う。

chrome.tabs.onUpdated.addListener()は仕様はあまり変わってない模様

サンプルコード

以下にアップした。

thr3a/mercari-chrome-extension

まとめ

V3まじで百害あって一利無し 滅びろ