結局 Chrome 拡張では ESModule が使えるのか

背景とか AI とか

たまに Chrome 拡張開発をするのだが、その度に混乱することがある。 それが ESModule を使うのか CommonJS を使うのか、ということだ。

昨今は仕事でもプライベートは基本的に ESM を使っていて、 require なんて全く見なくなった。 だから油断すると import 文を書いてしまうわけだが、 Chrome 拡張機能においては Cannot use import statement outside a module というエラーに見舞われる。もはやトラウマものである。

error がたくさん出る

この件を AI や AI Editor に聞いてみると、やれ ESModule は使える、指定するファイルが悪いので直しましょうか、など言われるが、どれも検討違い。 AI に任せても今は解決するフェーズにないらしい。

おそらくだが Chrome 拡張機能に関しては "実装→結果を確認→実装を修正" というフィードバックループを回すことができず、インターネットの断片的情報だけしか学習データを持っておらず、 AI の苦手分野なのだと思う。

Gemini Pro 3 がマルチモーダルへの対応性能を見せ、 Antigravity が画面の操作を AI Feedback loop の中に持ち込めるようになったのが先月で、AI 性能はまだブラウザそのものを AI で操作する範囲に収まっており、Chrome 拡張を load して自動で開発を行うフェーズには至っていない(あるいは興味を向けられていない)

本題

AI への脱線はこれくらいにして、本題というか知識。

Chrome 拡張機能で使われる主なファイルそれぞれについて、対応しているモジュールシステムが違う

content scripts : manifest の content_scripts で静的に登録される「普通のスクリプト」であり、ページに埋め込まれるスクリプトと同様に扱われるため、 import を直接書いてもモジュールとして扱われない。

background : ESModule は利用可能。Manifest V3 から background は service worker になり、type: "module" を指定すると import/export が使えます。

popup / options の HTML : popup.html に <script type="module"> を置けば ESModule が使える。

ということで、冒頭の Cannot use import statement outside a module は content_scripts にて import 文があると発生するエラー。

さて、content scripts についても ESModule で実装した上で import 文が出ない様に webpack でバンドルすればいいじゃんという話はあるが、それは AI が答えてくれるので筆を譲ることにする。