I plugin EmDash vengono forniti in uno dei due formati: sandboxed o native. La scelta influisce su come viene installato il plugin, quale applicazione ottiene a runtime e quali funzionalità sono disponibili.
Predefinito è sandboxed. I plugin sandboxed possono essere pubblicati sul marketplace e installati dall’interfaccia di amministrazione con un clic. I plugin nativi richiedono una modifica del codice, un npm install e un nuovo deploy su ogni sito che li desidera. Sandboxed è ciò che gli utenti finali desiderano.
Scegli nativo solo quando hai bisogno di una funzionalità che il sandbox non può fornire.
A colpo d’occhio
| Sandboxed | Native | |
|---|---|---|
| Forma di authoring | emdash-plugin.jsonc + src/plugin.ts | Descrittore definePlugin() |
| Metodo di installazione | Un clic dal marketplace di amministrazione | npm install + modificare astro.config |
| Viene eseguito in | Un runtime isolato fornito da un sandbox runner | Stesso processo del tuo sito Astro |
| Capacità | Applicate dal bridge del sandbox | Applicate in-process dallo stesso bridge |
| Limiti di risorse | Applicati dal runner — tipicamente CPU, subrequests, wall-time, memoria | Nessuno |
| Accesso alla rete | Solo ctx.http, limitato a allowedHosts | Solo ctx.http, limitato a allowedHosts |
fetch() / process.env diretti | Bloccati dal runner | Possibile (il codice del plugin condivide il runtime) |
| Distribuzione | Bundle .tar.gz sul marketplace | Pacchetto npm |
| Interfaccia di amministrazione | Route Block Kit (descritte in JSON) | Componenti React, o Block Kit |
| Interfaccia delle impostazioni | Pagina Block Kit + letture KV | admin.settingsSchema (form automatico) o Block Kit |
| Componenti di rendering Portable Text | Non disponibile | componentsEntry fornisce componenti Astro |
| Contributi ai metadati della pagina | Hook page:metadata — tag meta/property, rels <link> consentiti, JSON-LD | Hook page:metadata (stessa superficie) |
| Iniezione di frammenti di pagina | Non disponibile — solo meta/JSON-LD tramite page:metadata | Hook page:fragments — script inline, script esterni, HTML grezzo |
| Opzioni del costruttore | Nessuna — leggere le impostazioni da KV a runtime | options sul descrittore |
Cosa rinunci scegliendo nativo
I plugin nativi sembrano una versione più potente della stessa cosa, e lo sono — ma il costo è elevato:
- Nessun marketplace. Ogni sito deve installare il tuo pacchetto npm, modificare
astro.config.mjse ridistribuire. - Nessun isolamento. Un bug nel tuo plugin può mandare in crash il processo host o bruciare il suo budget CPU. Un rifiuto non gestito in un hook può far cadere la richiesta circostante con esso.
- Onere di fiducia sull’utente. I plugin nativi hanno lo stesso accesso del sito host. Gli utenti finali non possono verificarli solo tramite dichiarazioni di capacità.
Se il tuo plugin può svolgere il suo lavoro nel sandbox, dovrebbe farlo.
Quando scegliere nativo
Ci sono tre ragioni per scegliere nativo, e riguardano tutte funzionalità che necessitano di integrazione al momento della build con il sito host:
-
Pagine o widget di amministrazione React personalizzati. I plugin sandboxed descrivono la loro interfaccia di amministrazione con Block Kit — uno schema JSON che l’amministratore renderizza per conto del plugin. Se hai bisogno di React completo (hook personalizzati, componenti di terze parti, stato complesso), hai bisogno di nativo.
-
Componenti Astro per il rendering di blocchi Portable Text sul sito pubblico. Un plugin sandboxed può dichiarare un tipo di blocco personalizzato, ma i componenti Astro che lo renderizzano sul sito pubblico devono essere caricati al momento della build da npm. Solo i plugin nativi possono fornire un
componentsEntry. -
Iniettare HTML grezzo, script o fogli di stile in pagine pubbliche. L’hook
page:fragmentsinvia codice first-party ai browser dei visitatori — al di fuori di qualsiasi limite sandbox. È limitato ai plugin nativi. I plugin sandboxed possono comunque contribuire alle pagine pubbliche tramite l’hookpage:metadata, che copre molti casi d’uso reali:- Tag
meta(name+content) — descrizioni SEO, direttive robots, card Twitter - Tag
property— OpenGraph e altri meta basati su proprietà - Tag
linkcon una lista consentita rel bloccata per sicurezza (canonical,alternate,author,license,nlweb,site.standard.document) —stylesheet,prefetche rels simili di caricamento risorse non sono deliberatamente consentiti - Grafi JSON-LD
Se la tua necessità di “iniezione di pagina” riguarda dati strutturati o metadati SEO, rimani sandboxed e usa
page:metadata. Se hai effettivamente bisogno di inviare JavaScript o HTML al browser del visitatore, è il caso di scegliere nativo. - Tag
Se non sei sicuro, scegli sandboxed. Puoi sempre migrare a nativo più tardi — ma il contrario è più difficile, perché le funzionalità native esclusive non hanno un equivalente sandbox.
Sandbox runner e supporto della piattaforma
Il sandbox stesso è estensibile. EmDash espone un’opzione di configurazione sandboxRunner e il runner decide come viene isolato il codice del plugin — non c’è nulla di specifico di Cloudflare nel formato del plugin stesso.
Il runner che la maggior parte dei siti usa oggi è sandbox() da @emdash-cms/cloudflare, che usa Dynamic Worker Loader di Cloudflare Workers. Worker Loader memorizza nella cache l’isolato V8 per id plugin, quindi il costo di avvio a freddo dell’isolato viene pagato solo una volta; il runner costruisce uno stub di worker fresco e binding del bridge ad ogni invocazione, poiché gli stub e i binding sono legati al contesto I/O della richiesta chiamante. Runner per altre piattaforme (Node.js tramite workerd, e potenzialmente Deno) sono in sviluppo.
Se nessun runner è configurato, o se il runner configurato segnala come non disponibile sulla piattaforma corrente, i plugin elencati sotto sandboxed: [] vengono saltati all’avvio con un log di livello debug.
Se desideri che un plugin sandboxed venga eseguito su una piattaforma senza un sandbox runner, spostalo da sandboxed: [] nell’array plugins: [] — verrà eseguito in-process. Le dichiarazioni di capacità sono comunque rispettate (la stessa factory PluginContext controlla ctx.content, ctx.http e amici), ma non c’è limite di isolamento, nessun limite di risorse, e un plugin difettoso o malevolo può chiamare fetch() direttamente, leggere variabili d’ambiente o bloccare il ciclo degli eventi. Senza un sandbox runner attivo, tratta ogni plugin come un plugin nativo ai fini della fiducia.