Los plugins de EmDash utilizan uno de dos formatos: sandbox o nativo. Elija el formato antes de escribir el plugin porque la forma de creación, la ruta de instalación y el límite de confianza difieren.
Elija un plugin en sandbox a menos que el plugin necesite una integración exclusivamente nativa. Los plugins en sandbox se pueden publicar en el registro e instalar desde la interfaz de administración. Un plugin nativo es un paquete npm que un operador de sitio instala en el proyecto y agrega a astro.config.mjs antes de volver a desplegar.
De un vistazo
| Sandbox | Nativo | |
|---|---|---|
| Forma de creación | emdash-plugin.jsonc + src/plugin.ts | Descriptor definePlugin() |
| Método de instalación | Un clic desde el registro de administración | npm install + editar astro.config |
| Se ejecuta en | Un runtime aislado proporcionado por un runner de sandbox | El mismo proceso que su sitio Astro |
APIs ctx controladas por capacidades | Aplicadas por el puente de sandbox | Controladas por PluginContext, pero no es un límite de seguridad |
| Límites de recursos | Límites del runner para CPU, subrequests y tiempo de reloj; techo de memoria de la plataforma | Sin límites por plugin |
| Acceso a red | ctx.http, restringido al acceso declarado | ctx.http sigue declaraciones; el código nativo también puede llamar a fetch() |
fetch() / process.env directo | Bloqueado por el runner | Posible (el código del plugin comparte el runtime) |
| Distribución | Lanzamiento firmado en el registro de plugins | Paquete npm |
| Interfaz de administración | Rutas Block Kit (descritas en JSON) | Componentes React, o Block Kit |
| Interfaz de configuración | Página Block Kit + ctx.settings | admin.settingsSchema (formulario automático) o Block Kit |
| Componentes de renderizado de Portable Text | No disponible | componentsEntry proporciona componentes Astro |
| Contribuciones de metadatos de página | Hook page:metadata — etiquetas meta/property, rels <link> en lista permitida, JSON-LD | Hook page:metadata (misma superficie) |
| Inyección de fragmentos de página | No disponible — solo meta/JSON-LD vía page:metadata | Hook page:fragments — scripts inline, scripts externos, HTML sin procesar |
| Opciones del constructor | Ninguna — leer configuración de KV en tiempo de ejecución | options en el descriptor |
Costos de un plugin nativo
Los plugins nativos tienen un modelo de instalación y confianza diferente:
- Instalación a nivel de proyecto. Cada sitio tiene que instalar su paquete npm, editar
astro.config.mjsy volver a desplegar. - Sin aislamiento. Un error en su plugin puede bloquear el proceso del host o agotar su presupuesto de CPU. Un rechazo no manejado en un hook puede derribar la solicitud circundante con él.
- Carga de confianza en el usuario. Los plugins nativos tienen el mismo acceso que el sitio host. Las declaraciones de capacidades por sí solas no pueden mostrar todo lo que su código puede hacer.
Si su plugin puede hacer su trabajo en el sandbox, debería hacerlo.
Cuándo ir nativo
Elija nativo para características que necesitan integración en tiempo de compilación con el sitio host:
-
Páginas o widgets de administración React personalizados. Los plugins en sandbox describen su interfaz de administración con Block Kit — un esquema JSON que el administrador renderiza en nombre del plugin. Si necesita React completo (hooks personalizados, componentes de terceros, estado complejo), necesita nativo.
-
Tipos de bloques de Portable Text personalizados. Su configuración de edición y componentes de renderizado Astro se cargan desde el paquete npm instalado. Solo los plugins nativos pueden proporcionar esa superficie en tiempo de compilación.
-
Inyectar HTML sin procesar, scripts o hojas de estilo en páginas públicas. El hook
page:fragmentsenvía código de primera parte a los navegadores de los visitantes — fuera de cualquier límite de sandbox. Está restringido a plugins nativos. Los plugins en sandbox aún pueden contribuir a páginas públicas a través del hookpage:metadata, que cubre muchos casos de uso reales:- Etiquetas
meta(name+content) — descripciones SEO, directivas de robots, tarjetas de Twitter - Etiquetas
property— OpenGraph y otros meta basados en propiedades - Etiquetas
linkcon una lista permitida de rel bloqueada por seguridad (canonical,alternate,author,license,nlweb,site.standard.document) —stylesheet,prefetchy rels similares que cargan recursos no están permitidos deliberadamente - Grafos JSON-LD
Si su necesidad de “inyección de página” son datos estructurados o metadatos SEO, manténgase en sandbox y use
page:metadata. Si realmente necesita enviar JavaScript o HTML al navegador del visitante, ese es el caso para ir nativo. - Etiquetas
Si ninguna de estas características se aplica, use el formato sandbox.
Runners de sandbox y soporte de plataforma
El sandbox en sí es pluggable. EmDash expone una opción de configuración sandboxRunner y el runner decide cómo se aísla el código del plugin — no hay nada específico de Cloudflare en el formato del plugin en sí.
Dos runners se envían con EmDash: sandbox() de @emdash-cms/cloudflare, que ejecuta cada plugin como un Dynamic Worker a través del Worker Loader de Cloudflare, y @emdash-cms/sandbox-workerd/sandbox, que ejecuta plugins en un proceso hijo workerd en Node.js. Plugin Sandbox cubre la configuración de cada runner, los límites de recursos que aplica y las diferencias entre los dos.
Si no se configura ningún runner, los plugins listados bajo sandboxed: [] no se cargan. Si el runner configurado no está disponible en la plataforma actual, tampoco se cargan, y EmDash registra una advertencia al inicio.
Si desea que un plugin en sandbox se ejecute en una plataforma sin un runner de sandbox, muévalo de sandboxed: [] al array plugins: [] — se ejecutará en proceso. Las declaraciones de capacidades todavía se respetan (la misma fábrica PluginContext controla ctx.content, ctx.http y amigos), pero no hay límite de aislamiento, no hay límites de recursos, y un plugin con errores o malicioso puede llamar a fetch() directamente, leer variables de entorno o bloquear el bucle de eventos. Sin un runner de sandbox activo, trate cada plugin como un plugin nativo con fines de confianza.