◆ module の script タグを作って append
◆ 拡張機能内の JavaScript をロードするために web_accessible_resources の指定必要

拡張機能と module

ブラウザ拡張機能は module 機能が出る前に作られたものなので module を考慮されていないものもあります
module は HTML から JavaScript をロードするときに script タグに type="module" を指定する というものなので 普通に HTML を書く オプションやポップアップやその他の拡張機能で特別扱いされない任意のページなら問題ありません

バックグラウンド処理も本来はページが存在するので HTML で module として JavaScript をロードすれば問題ありません
ただ バックグラウンドの処理なのでほとんどの場合は HTML は不要で JavaScript のみで良いことから楽に書けるように一般的に知られてるのはこうなっています

  "background": {
"scripts": ["bg.js"]
}

こうかけば自動で _generated_background_page.html という HTML が作られてそこに script タグが配置されて設定した JavaScript ファイルをロードしてくれます

module としてロードするなら

  "background": {
"page": "bg.html"
}

とページを指定して その HTML に type="module" にした script タグを書けば良いです

そうなると残るはたぶん content script だけです

content script

content script は拡張機能の領域で動く他のとは違って 各ページ内で実行するものです
バックグラウンドの処理から chrome.tabs.executeScript を使ってページ中でコードを実行したり manifest で設定した通りにページにコードを埋め込んだりできます

これは HTML を使うものではなく実行する JavaScript を指定して実行させるものです
なのでバックグラウンド処理のようには行きません

方法はコードを実行するページの document 中に type="module" の script タグを埋め込んで モジュールとして実行させるというものです
これだけで伝わる人には伝わると思いますが 一応簡単な例を作りました

構造
- manifest.json
- loader.js
- content-script/
- index.js
- module1.js
- module2.js

manifest.json
{
"name": "content script",
"manifest_version": 2,
"version": "1",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["loader.js"]
}
],
"web_accessible_resources": ["content-script/*"]
}

例なのでどのページでも実行させます
content script として実際に埋め込むファイルは loader.js です
これが script タグを作って module として本来ロードしたいモジュールファイルをロードさせます
ウェブページから拡張機能の JavaScript ファイルにアクセスすることになるので web_accessible_resources を使ってアクセス可能にします

loader.js
{
const exid = chrome.runtime.id
const elid = exid + "-script"

if(document.getElementById(elid)) return

const scr = document.createElement("script")
scr.id = elid
scr.src = chrome.runtime.getURL("content-script/index.js")
scr.type = "module"
document.head.append(scr)
}

一応二重ロードをしないようにしてますが バックグラウンドからページの更新イベントで実行するのではなく manifest で指定して実行する場合は pushState などで再実行されないと思うので別になくとも良いと思います

これで content-script/index.js が module としてロードされます

content-script/index.js
import module1 from "./module1.js"

module1()

content-script/module1.js
import module2 from "./module2.js"

export default () => {
console.log(1)
module2()
}

content-script/module2.js
export default () => console.log(2)

適当にページを開いてコンソールを開くと

12:49:51.230  1           module1.js:4
12:49:51.230 2 module2.js:1

モジュールが正常にロードされてますね
そろそろ module が使えるようになって結構経ちますし 拡張機能周りも module をデフォルトに移行してくれればいいのにと思います

ただ manifest_version 3 は web request の機能廃止とか言われてるのでその辺は不便になるのであまり変わってほしくない気持ちもあるんですよね
特定リクエストをブロックしたり CSS を自分で管理してるのにリダイレクトさせてカスタマイズしたテーマにしたりというのができなくなりますし