Wahl eines Plugin-Formats

Auf dieser Seite

EmDash-Plugins werden in einem von zwei Formaten ausgeliefert: Sandboxed oder Native. Die Wahl beeinflusst, wie das Plugin installiert wird, welche Durchsetzung es zur Laufzeit erhält und welche Funktionen verfügbar sind.

Standardmäßig Sandboxed verwenden. Sandboxed-Plugins können im Marketplace veröffentlicht und mit einem Klick über die Admin-Oberfläche installiert werden. Native-Plugins erfordern eine Codeänderung, ein npm install und ein erneutes Deployment auf jeder Website, die sie verwenden möchte. Sandboxed ist das, was Endbenutzer wünschen.

Wählen Sie Native nur, wenn Sie eine Funktion benötigen, die die Sandbox nicht bereitstellen kann.

Auf einen Blick

SandboxedNative
format-Feld im Deskriptor"standard""native"
InstallationsmethodeEin Klick über den Admin-Marketplacenpm install + Bearbeitung von astro.config
Läuft inEiner isolierten Laufzeitumgebung, die von einem Sandbox-Runner bereitgestellt wirdDemselben Prozess wie Ihre Astro-Website
CapabilitiesDurchgesetzt von der Sandbox-BridgeIn-Process durch dieselbe Bridge durchgesetzt
RessourcenlimitsDurchgesetzt vom Runner — typischerweise CPU, Subrequests, Laufzeit, SpeicherKeine
NetzwerkzugriffNur ctx.http, beschränkt auf allowedHostsNur ctx.http, beschränkt auf allowedHosts
Direkter fetch() / process.envVom Runner blockiertMöglich (Plugin-Code teilt sich die Laufzeitumgebung)
Distribution.tar.gz-Bundle im Marketplacenpm-Paket
Admin-UIBlock Kit (JSON-beschrieben) RoutesReact-Komponenten oder Block Kit
Einstellungs-UIBlock Kit-Seite + KV-Lesevorgängeadmin.settingsSchema (Auto-Formular) oder Block Kit
Portable Text-Rendering-KomponentenNicht verfügbarcomponentsEntry stellt Astro-Komponenten bereit
Seitemetadaten-Beiträgepage:metadata-Hook — meta/property-Tags, zugelassene <link>-rels, JSON-LDpage:metadata-Hook (gleiche Oberfläche)
Seitenfragment-InjektionNicht verfügbar — nur meta/JSON-LD über page:metadatapage:fragments-Hook — Inline-Skripte, externe Skripte, reines HTML
Konstruktor-OptionenKeine — Einstellungen zur Laufzeit aus KV lesenoptions im Deskriptor

Was Sie bei der Wahl von Native aufgeben

Native-Plugins sehen aus wie eine leistungsfähigere Version derselben Sache, und das sind sie auch — aber die Kosten sind hoch:

  • Kein Marketplace. Jede Website muss Ihr npm-Paket installieren, astro.config.mjs bearbeiten und erneut deployen.
  • Keine Isolation. Ein Fehler in Ihrem Plugin kann den Host-Prozess zum Absturz bringen oder sein CPU-Budget aufbrauchen. Eine unbehandelte Ablehnung in einem Hook kann die umgebende Anfrage mit sich reißen.
  • Vertrauenslast beim Benutzer. Native-Plugins haben denselben Zugriff wie die Host-Website. Endbenutzer können sie nicht allein durch Capability-Deklarationen prüfen.

Wenn Ihr Plugin seine Aufgabe in der Sandbox erledigen kann, sollte es das auch tun.

Wann Native wählen

Es gibt drei Gründe, Native zu wählen, und alle drehen sich um Funktionen, die eine Build-Zeit-Integration mit der Host-Website erfordern:

  1. Benutzerdefinierte React-Admin-Seiten oder -Widgets. Sandboxed-Plugins beschreiben ihre Admin-UI mit Block Kit — einem JSON-Schema, das der Admin im Auftrag des Plugins rendert. Wenn Sie vollständiges React benötigen (benutzerdefinierte Hooks, Drittanbieter-Komponenten, komplexer State), benötigen Sie Native.

  2. Astro-Komponenten zum Rendern von Portable Text-Blöcken auf der öffentlichen Website. Ein Plugin kann einen benutzerdefinierten Block-Typ mit format: "standard" deklarieren, aber die Astro-Komponenten, die ihn auf der öffentlichen Website rendern, müssen zur Build-Zeit von npm geladen werden. Nur Native-Plugins können einen componentsEntry bereitstellen.

  3. Einfügen von reinem HTML, Skripten oder Stylesheets in öffentliche Seiten. Der page:fragments-Hook liefert First-Party-Code an die Browser der Besucher — außerhalb jeder Sandbox-Grenze. Er ist auf Native-Plugins beschränkt. Sandboxed-Plugins können dennoch über den page:metadata-Hook zu öffentlichen Seiten beitragen, der viele reale Anwendungsfälle abdeckt:

    • meta-Tags (name + content) — SEO-Beschreibungen, Robots-Direktiven, Twitter Cards
    • property-Tags — OpenGraph und andere eigenschaftsbasierte Meta-Daten
    • link-Tags mit einer sicherheitsgesperrten rel-Allowlist (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch und ähnliche ressourcenladende rels sind absichtlich nicht erlaubt
    • JSON-LD-Graphen

    Wenn Ihr „Seiteninjektions”-Bedarf strukturierte Daten oder SEO-Metadaten ist, bleiben Sie bei Sandboxed und verwenden Sie page:metadata. Wenn Sie tatsächlich JavaScript oder HTML in den Browser des Besuchers ausliefern müssen, ist das der Fall für Native.

Wenn Sie sich nicht sicher sind, wählen Sie Sandboxed. Sie können später immer zu Native migrieren — aber das Gegenteil ist schwieriger, weil Native-exklusive Funktionen kein Sandbox-Äquivalent haben.

Sandbox-Runner und Plattformunterstützung

Die Sandbox selbst ist erweiterbar. EmDash stellt eine sandboxRunner-Konfigurationsoption bereit, und der Runner entscheidet, wie Plugin-Code isoliert wird — es gibt nichts Cloudflare-Spezifisches im Plugin-Format selbst.

Der Runner, den die meisten Websites heute verwenden, ist sandbox() von @emdash-cms/cloudflare, der Cloudflare Workers’ Dynamic Worker Loader verwendet. Worker Loader cached das V8-Isolat pro Plugin-ID, sodass die Isolat-Kaltstartkosten nur einmal anfallen; der Runner konstruiert bei jedem Aufruf einen frischen Worker-Stub und Bridge-Bindings, da Stubs und Bindings an den I/O-Kontext der aufrufenden Anfrage gebunden sind. Runner für andere Plattformen (Node.js via workerd und potenziell Deno) sind in Entwicklung.

Wenn kein Runner konfiguriert ist oder wenn der konfigurierte Runner als nicht verfügbar auf der aktuellen Plattform meldet, werden unter sandboxed: [] aufgelistete Plugins beim Start mit einem Debug-Level-Log übersprungen.

Wenn Sie möchten, dass ein Standard-Format-Plugin auf einer Plattform ohne Sandbox-Runner läuft, verschieben Sie es von sandboxed: [] in das plugins: []-Array — es wird dann in-process ausgeführt. Capability-Deklarationen werden weiterhin respektiert (dieselbe PluginContext-Factory beschränkt ctx.content, ctx.http und Ähnliches), aber es gibt keine Isolationsgrenze, keine Ressourcenlimits, und ein fehlerhaftes oder bösartiges Plugin kann fetch() direkt aufrufen, Umgebungsvariablen lesen oder die Event-Loop blockieren. Ohne einen aktiven Sandbox-Runner behandeln Sie jedes Plugin aus Vertrauensgründen wie ein Native-Plugin.

Nächste Schritte