EmDashプラグインは、sandboxed(サンドボックス化)またはnative(ネイティブ)の2つの形式のいずれかで提供されます。この選択は、プラグインのインストール方法、実行時の適用範囲、利用可能な機能に影響します。
デフォルトはサンドボックス化です。 サンドボックス化されたプラグインは、マーケットプレイスに公開でき、管理UIからワンクリックでインストールできます。ネイティブプラグインは、コード変更、npm install、そしてプラグインを使用したいすべてのサイトでの再デプロイが必要です。サンドボックス化は、エンドユーザーが求めるものです。
サンドボックスが提供できない機能が必要な場合にのみ、ネイティブを選択してください。
一目でわかる比較
| Sandboxed | Native | |
|---|---|---|
| 作成形式 | emdash-plugin.jsonc + src/plugin.ts | definePlugin()記述子 |
| インストール方法 | 管理マーケットプレイスからワンクリック | npm install + astro.configの編集 |
| 実行環境 | サンドボックスランナーによって提供される分離されたランタイム | Astroサイトと同じプロセス |
| 機能 | サンドボックスブリッジによって適用 | 同じブリッジによってインプロセスで適用 |
| リソース制限 | ランナーによって適用 — 通常はCPU、サブリクエスト、ウォールタイム、メモリ | なし |
| ネットワークアクセス | ctx.httpのみ、allowedHostsに制限 | ctx.httpのみ、allowedHostsに制限 |
直接のfetch() / process.env | ランナーによってブロック | 可能(プラグインコードはランタイムを共有) |
| 配布 | マーケットプレイス上の.tar.gzバンドル | npmパッケージ |
| 管理UI | Block Kit(JSON記述)ルート | Reactコンポーネント、またはBlock Kit |
| 設定UI | Block Kitページ + KV読み取り | admin.settingsSchema(自動フォーム)またはBlock Kit |
| Portable Textレンダリングコンポーネント | 利用不可 | componentsEntryがAstroコンポーネントを提供 |
| ページメタデータへの貢献 | page:metadataフック — meta/propertyタグ、許可リストの<link>rels、JSON-LD | page:metadataフック(同じサーフェス) |
| ページフラグメントの注入 | 利用不可 — page:metadata経由のmeta/JSON-LDのみ | page:fragmentsフック — インラインスクリプト、外部スクリプト、生のHTML |
| コンストラクタオプション | なし — ランタイム時にKVから設定を読み取る | 記述子のoptions |
ネイティブを選ぶことで失うもの
ネイティブプラグインは、同じものの、より強力なバージョンのように見えます。実際にそうですが、コストは高くつきます:
- マーケットプレイスなし。 すべてのサイトがnpmパッケージをインストールし、
astro.config.mjsを編集し、再デプロイする必要があります。 - 分離なし。 プラグインのバグは、ホストプロセスをクラッシュさせたり、CPUバジェットを消費したりする可能性があります。フック内の未処理の拒否は、周囲のリクエストを巻き込む可能性があります。
- ユーザーへの信頼の負担。 ネイティブプラグインは、ホストサイトと同じアクセス権を持ちます。エンドユーザーは、機能宣言だけではそれらを監査できません。
プラグインがサンドボックス内でその仕事を実行できるなら、そうすべきです。
ネイティブを選ぶべき場合
ネイティブを選択する理由は3つあり、それらはすべて、ホストサイトとのビルド時統合が必要な機能に関するものです:
-
カスタムReact管理ページまたはウィジェット。 サンドボックス化されたプラグインは、Block Kitを使用して管理UIを記述します — これは、管理者がプラグインに代わってレンダリングするJSONスキーマです。完全なReact(カスタムフック、サードパーティコンポーネント、複雑な状態)が必要な場合は、ネイティブが必要です。
-
公開サイトでPortable TextブロックをレンダリングするためのAstroコンポーネント。 サンドボックス化されたプラグインはカスタムブロックタイプを宣言できますが、公開サイトでそれをレンダリングするAstroコンポーネントは、ビルド時にnpmからロードする必要があります。ネイティブプラグインのみが
componentsEntryを提供できます。 -
公開ページに生のHTML、スクリプト、またはスタイルシートを注入する。
page:fragmentsフックは、訪問者のブラウザにファーストパーティコードを送信します — サンドボックス境界の外です。ネイティブプラグインに制限されています。サンドボックス化されたプラグインは、依然としてpage:metadataフックを通じて公開ページに貢献できます。これは、多くの実際のユースケースをカバーします:metaタグ(name+content) — SEO説明、ロボット指示、Twitterカードpropertyタグ — OpenGraphおよびその他のプロパティベースのメタ- セキュリティロックされたrel許可リストを持つ
linkタグ(canonical、alternate、author、license、nlweb、site.standard.document) —stylesheet、prefetch、および類似のリソースロードrelsは意図的に許可されていません - JSON-LDグラフ
「ページ注入」の必要性が構造化データまたはSEOメタデータである場合は、サンドボックス化されたままにして
page:metadataを使用してください。実際に訪問者のブラウザにJavaScriptまたはHTMLを送信する必要がある場合、それがネイティブを選択するケースです。
不確かな場合は、サンドボックス化を選択してください。後でネイティブに移行することは常に可能ですが、逆は難しくなります。ネイティブ専用機能にはサンドボックスに相当するものがないためです。
サンドボックスランナーとプラットフォームサポート
サンドボックス自体はプラガブルです。EmDashはsandboxRunner設定オプションを公開し、ランナーはプラグインコードがどのように分離されるかを決定します — プラグイン形式自体にCloudflare固有のものは何もありません。
今日ほとんどのサイトが使用しているランナーは、@emdash-cms/cloudflareのsandbox()で、Cloudflare WorkersのDynamic Worker Loaderを使用しています。Worker Loaderは、プラグインIDごとにV8アイソレートをキャッシュするため、アイソレートのコールドスタートコストは1回だけ支払われます。ランナーは、各呼び出しで新しいワーカースタブとブリッジバインディングを構築します。これは、スタブとバインディングが呼び出し元リクエストのI/Oコンテキストに関連付けられているためです。他のプラットフォーム(workerd経由のNode.js、および潜在的にDeno)のランナーは開発中です。
ランナーが設定されていない場合、または設定されたランナーが現在のプラットフォームで利用不可と報告した場合、sandboxed: []の下にリストされたプラグインは、起動時にデバッグレベルのログでスキップされます。
サンドボックスランナーのないプラットフォームでサンドボックス化されたプラグインを実行したい場合は、sandboxed: []からplugins: []配列に移動してください — インプロセスで実行されます。機能宣言は引き続き尊重されます(同じPluginContextファクトリがctx.content、ctx.http、および仲間をゲートします)が、分離境界はなく、リソース制限もなく、バグのある、または悪意のあるプラグインはfetch()を直接呼び出し、環境変数を読み取り、またはイベントループをブロックできます。アクティブなサンドボックスランナーがない場合、信頼の目的でネイティブプラグインとしてすべてのプラグインを扱ってください。