Elegir un formato de plugin

En esta página

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

SandboxNativo
Forma de creaciónemdash-plugin.jsonc + src/plugin.tsDescriptor definePlugin()
Método de instalaciónUn clic desde el registro de administraciónnpm install + editar astro.config
Se ejecuta enUn runtime aislado proporcionado por un runner de sandboxEl mismo proceso que su sitio Astro
APIs ctx controladas por capacidadesAplicadas por el puente de sandboxControladas por PluginContext, pero no es un límite de seguridad
Límites de recursosLímites del runner para CPU, subrequests y tiempo de reloj; techo de memoria de la plataformaSin límites por plugin
Acceso a redctx.http, restringido al acceso declaradoctx.http sigue declaraciones; el código nativo también puede llamar a fetch()
fetch() / process.env directoBloqueado por el runnerPosible (el código del plugin comparte el runtime)
DistribuciónLanzamiento firmado en el registro de pluginsPaquete npm
Interfaz de administraciónRutas Block Kit (descritas en JSON)Componentes React, o Block Kit
Interfaz de configuraciónPágina Block Kit + ctx.settingsadmin.settingsSchema (formulario automático) o Block Kit
Componentes de renderizado de Portable TextNo disponiblecomponentsEntry proporciona componentes Astro
Contribuciones de metadatos de páginaHook page:metadata — etiquetas meta/property, rels <link> en lista permitida, JSON-LDHook page:metadata (misma superficie)
Inyección de fragmentos de páginaNo disponible — solo meta/JSON-LD vía page:metadataHook page:fragments — scripts inline, scripts externos, HTML sin procesar
Opciones del constructorNinguna — leer configuración de KV en tiempo de ejecuciónoptions 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.mjs y 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:

  1. 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.

  2. 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.

  3. Inyectar HTML sin procesar, scripts o hojas de estilo en páginas públicas. El hook page:fragments enví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 hook page: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 link con una lista permitida de rel bloqueada por seguridad (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch y 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.

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.

Siguiente