Elegir un formato de plugin

En esta página

Los plugins de EmDash se distribuyen en uno de dos formatos: sandboxed o native. La elección afecta cómo se instala el plugin, qué aplicación obtiene en tiempo de ejecución y qué características están disponibles.

Por defecto, sandboxed. Los plugins sandboxed pueden publicarse en el marketplace e instalarse desde la interfaz de administración con un clic. Los plugins nativos requieren un cambio de código, un npm install y un redespliegue en cada sitio que los quiera. Sandboxed es lo que los usuarios finales desean.

Elija nativo solo cuando necesite una característica que el sandbox no puede proporcionar.

De un vistazo

SandboxedNative
Forma de autoríaemdash-plugin.jsonc + src/plugin.tsDescriptor definePlugin()
Método de instalaciónUn clic desde el marketplace de administraciónnpm install + editar astro.config
Se ejecuta enUn tiempo de ejecución aislado proporcionado por un sandbox runnerEl mismo proceso que su sitio Astro
CapacidadesAplicadas por el puente del sandboxAplicadas en proceso por el mismo puente
Límites de recursosAplicados por el runner — típicamente CPU, subrequests, wall-time, memoriaNinguno
Acceso a redSolo ctx.http, restringido a allowedHostsSolo ctx.http, restringido a allowedHosts
fetch() / process.env directosBloqueados por el runnerPosible (el código del plugin comparte el tiempo de ejecución)
DistribuciónBundle .tar.gz en el marketplacePaquete npm
Interfaz de administraciónRutas Block Kit (descritas en JSON)Componentes React, o Block Kit
Interfaz de configuraciónPágina Block Kit + lecturas KVadmin.settingsSchema (auto-formulario) 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> permitidos, 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 crudo
Opciones del constructorNinguna — leer configuraciones de KV en tiempo de ejecuciónoptions en el descriptor

Lo que renuncias al elegir nativo

Los plugins nativos parecen una versión más poderosa de lo mismo, y lo son — pero el costo es alto:

  • Sin marketplace. Cada sitio tiene que instalar tu paquete npm, editar astro.config.mjs y redesplegar.
  • Sin aislamiento. Un error en tu plugin puede bloquear el proceso host o quemar 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. Los usuarios finales no pueden auditarlos solo a través de declaraciones de capacidades.

Si tu plugin puede hacer su trabajo en el sandbox, debería hacerlo.

Cuándo elegir nativo

Hay tres razones para elegir nativo, y todas se refieren a 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 sandboxed describen su interfaz de administración con Block Kit — un esquema JSON que el administrador renderiza en nombre del plugin. Si necesitas React completo (hooks personalizados, componentes de terceros, estado complejo), necesitas nativo.

  2. Componentes Astro para renderizar bloques de Portable Text en el sitio público. Un plugin sandboxed puede declarar un tipo de bloque personalizado, pero los componentes Astro que lo renderizan en el sitio público deben cargarse en tiempo de compilación desde npm. Solo los plugins nativos pueden proporcionar un componentsEntry.

  3. Inyectar HTML crudo, 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 sandboxed 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 de permitidos rel bloqueada por seguridad (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch y rels similares de carga de recursos no están permitidos deliberadamente
    • Grafos JSON-LD

    Si tu necesidad de “inyección de página” son datos estructurados o metadatos SEO, mantente sandboxed y usa page:metadata. Si realmente necesitas enviar JavaScript o HTML al navegador del visitante, ese es el caso para elegir nativo.

Si no estás seguro, elige sandboxed. Siempre puedes migrar a nativo más tarde — pero al revés es más difícil, porque las características exclusivas de nativo no tienen equivalente en sandbox.

Sandbox runners y soporte de plataforma

El sandbox en sí es extensible. 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í.

El runner que la mayoría de los sitios usan hoy es sandbox() de @emdash-cms/cloudflare, que usa Dynamic Worker Loader de Cloudflare Workers. Worker Loader cachea el aislado V8 por id de plugin, por lo que el costo de arranque en frío del aislado solo se paga una vez; el runner construye un stub de worker fresco y bindings de puente en cada invocación, ya que los stubs y bindings están vinculados al contexto de I/O de la solicitud que llama. Los runners para otras plataformas (Node.js vía workerd, y potencialmente Deno) están en desarrollo.

Si no se configura ningún runner, o si el runner configurado reporta como no disponible en la plataforma actual, los plugins listados bajo sandboxed: [] se omiten en el inicio con un log de nivel de depuración.

Si deseas que un plugin sandboxed se ejecute en una plataforma sin un sandbox runner, muévelo de sandboxed: [] al array plugins: [] — se ejecutará en proceso. Las declaraciones de capacidades aún se respetan (la misma factory PluginContext controla ctx.content, ctx.http y amigos), pero no hay límite de aislamiento, no hay límites de recursos, y un plugin defectuoso o malicioso puede llamar a fetch() directamente, leer variables de entorno o bloquear el bucle de eventos. Sin un sandbox runner activo, trata cada plugin como un plugin nativo con fines de confianza.

Siguiente