FlutterWebをManifestV3のChrome拡張機能として突っ込んだらハチャメチャにエラー吐いた
外から何か取りに行く要素を全部ローカルに寄せてFlutterの起動設定をいじったら治ったので、やったことメモ。
症状
- popupを開くと真っ黒
- ConsoleにCSPエラー/外部リソース取得失敗
原因
ハマったのは下記。
-
index.htmlにインラインscript/styleが残っていてMV3のCSP で即死 - FlutterがServiceWorkerを登録しようとしてpopup側で止まる
- CanvasKitが
gstaticからcanvaskit.wasmを落とそうとしてブロック -
sql.js使ってるとsql-wasm.wasmの参照が外部だと同じく死ぬ
要するに拡張機能は外部からコード引っ張るのに厳しいっぽい
対処:インライン排除 + ローカル同梱 + 起動設定の上書き
1. sql.js と sql-wasm.wasm をローカルに置く
Web 側のDBを sql.js で逃がしてる構成だと、CDN参照が残ってるだけでアウトになりかねない
ので、拡張機能の中に以下をそのまま入れる。
sql.jssql-wasm.wasm
initSqlJs の locateFile を使って、WASM の参照先がローカルになるようにしておく(配置は要調整)
2. index.html のインラインを消す
flutterbuildwebの成果物、環境によってはindex.htmlにインライン<style>とか<script>が混ざっててMV3で死ぬため、
下記修正を実施
- インライン
<style>→style.cssに分離 - 初期化スクリプト(sql.js系など)→
init_sql.jsに分離 -
index.htmlは<link>と<script src>だけにする
ここまでで一旦の即死回避
3. manifest.jsonの SPを調整
WASMを動かすために、拡張機能ページのCSPを変更。
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; style-src 'self' 'unsafe-inline';"
}
style-src 'unsafe-inline'は Flutter 側の都合で必要になるケースがあるため記述
4. flutter_bootstrap.jsでServiceWorkerを無効化
Flutterがflutter_service_worker.jsを登録しに行く際、popupだとエラーになって描画が止まることがある。
build/web/flutter_bootstrap.js を開いてSW設定を切りましょう。
// 変更前
_flutter.loader.load({
serviceWorkerSettings: {
serviceWorkerVersion: "..."
}
});
// 変更後
_flutter.loader.load({
serviceWorkerSettings: null
});
5. CanvasKitをローカル固定
Flutterはデフォルトで gstaticから canvaskit.wasmを取りに行くので、拡張機能だとここでお亡くなりに。
でも flutterbuild webの時点でbuild/web/canvaskit/は出てるので、それを同梱した上で参照先だけ固定することで解決。
_flutter.loader.load({
serviceWorkerSettings: null,
config: {
canvasKitBaseUrl: "canvaskit/"
}
});
まとめ
-
インライン
script/styleは全部外に出す -
wasm 系(sql.js / CanvasKit)は全部ローカルに置く
-
flutter_bootstrap.jsを触ってserviceWorkerSettings: null-
canvasKitBaseUrl: "canvaskit/"を入れる
とりあえずこれで動くはずなのでぜひ