コンテンツにスキップ
JP

プラグインシステムの仕組み

更新日

Visualizer のプラグインは、単一のコードとして動作するわけではありません。各プラグインは、別々の環境で動作して相互に通信する 2 つの部分に分かれています。この構成により、コードが実行される場所ごとに、できることとできないことが決まります。

プラグインが読み込まれると、Visualizer はコードを次の 2 つの環境で実行します。

  • Visualizer のデータとプラグインAPIに直接アクセスできる WebAssembly 環境
  • すべての UI 描画を担当し、標準のブラウザ API を利用できる iframe 環境

どちらか一方だけですべてを実行することはできません。WebAssembly 側は Visualizer のデータを読み取って操作できますが、HTML の描画や多くのブラウザ API の利用はできません。iframe 側は HTML の描画やブラウザ API の利用ができますが、Visualizer のデータへ直接アクセスできません。2 つの環境が互いを補完します。

両者は、異なる実行コンテキスト間で安全に通信するための標準的なブラウザ機能である postMessage を使って通信します。UI が Visualizer のデータを必要とするときは、WebAssembly 側にデータを要求します。WebAssembly 側はデータを取得し、iframe 側へ送信します。

WebAssembly 側はプラグインのエントリーポイントです。プラグインが読み込まれたときに最初に実行され、Visualizer と同じスレッドで同期的に動作します。

できること:

  • Visualizer のシーンデータへアクセスする。
  • プラグインAPIを呼び出す。
  • レイヤのプロパティの更新など、Visualizer のシーンを部分的に変更する。
  • シーンのイベントを購読する。
  • postMessage を使って iframe 側とデータを送受信する。

できないこと:

  • HTML や UI を直接描画する。UI の描画は iframe 側で行う必要があります。
  • 多くのブラウザ API を利用する。利用できるのは console.log など一部に限られます。
  • 外部サーバーへ HTTP リクエストを送信する。

iframe 側は、プラグインの視覚的な要素をすべて処理します。通常のウェブページと同じように動作し、ブラウザ API を利用できます。

できること:

  • 通常のウェブページと同じように HTML を描画する。
  • DOM API、Canvas、fetch などのブラウザ API を利用する。
  • サーバーのレスポンスヘッダーに Access-Control-Allow-Origin: * が含まれている場合、外部サーバーへ HTTP リクエストを送信する。
  • postMessage を使って WebAssembly 側とデータを送受信する。

できないこと:

  • Visualizer のデータへ直接アクセスしたり変更したりする。postMessage を通じて WebAssembly 側へ要求する必要があります。
  • Visualizer のバックエンドと直接通信する。
  • レスポンスヘッダーに Access-Control-Allow-Origin: * が含まれていないサーバーへ HTTP リクエストを送信する。iframe は null オリジンでサンドボックス化されています。
  • 同じサンドボックス上の理由により、ローカルストレージを利用する。
  • 親ページから明示的な権限を必要とするブラウザ API を利用する。たとえば、Clipboard API はサンドボックス化された iframe ではデフォルトで利用できません。
機能WebAssembly 側iframe 側
サンドボックス化
エントリーポイント(最初に実行)
プラグインAPIへのアクセス
HTML の描画
ブラウザ API の利用
postMessage による通信

postMessage のシリアライズ: postMessage で送信できるのは、JSON としてシリアライズ可能なデータだけです。ArrayBufferBlob などのオブジェクトは直接送信できません。バイナリーデータは、送信前に base64 文字列へエンコードしてください。

プラグインのサイズ: プラグインは 10 MB 以下の .zip ファイルとしてパッケージ化する必要があります。

静的アセット: 画像、HTML、CSS などの JavaScript 以外のファイルは、プラグイン内に含めることができません。JavaScript に文字列として埋め込むか、一般公開されたサーバーに配置して URL で参照してください。

ローカルストレージ: ローカルストレージは両方の環境で利用できません。データを永続化するには、プラグインAPIが提供するストレージ API または外部サーバーを使用してください。