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, use sandboxed. Los plugins sandboxed se pueden publicar en el marketplace e instalarse desde la interfaz de administración con un solo clic. Los plugins nativos requieren un cambio de código, un npm install y un redespliegue en cada sitio que los quiera usar. Sandboxed es lo que los usuarios finales desean.

Elija native solo cuando necesite una característica que el sandbox no pueda proporcionar.

De un vistazo

SandboxedNative
Campo format en el descriptor"standard""native"
Método de instalaciónUn clic desde el marketplace de administraciónnpm install + editar astro.config
Se ejecuta enUn runtime 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, tiempo de ejecución, memoriaNinguno
Acceso a redSolo ctx.http, restringido a allowedHostsSolo ctx.http, restringido a allowedHosts
fetch() / process.env directoBloqueado por el runnerPosible (el código del plugin comparte el runtime)
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 (formulario automático) o Block Kit
Componentes de renderizado 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 configuración de KV en tiempo de ejecuciónoptions en el descriptor

Lo que se sacrifica al elegir native

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 su paquete npm, editar astro.config.mjs y redesplegar.
  • Sin aislamiento. Un error en su plugin puede bloquear el proceso host o consumir 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 su plugin puede hacer su trabajo en el sandbox, debería hacerlo.

Cuándo elegir native

Hay tres razones para elegir native, y todas se tratan de características que necesitan integración en tiempo de compilación con el sitio host:

  1. Páginas de administración o widgets 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 necesita React completo (hooks personalizados, componentes de terceros, estado complejo), necesita native.

  2. Componentes Astro para renderizar bloques Portable Text en el sitio público. Un plugin puede declarar un tipo de bloque personalizado con format: "standard", 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 del 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, Twitter Cards
    • Etiquetas property — OpenGraph y otros metadatos 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 de carga de recursos no están permitidos deliberadamente
    • Grafos JSON-LD

    Si su necesidad de “inyección de página” es datos estructurados o metadatos SEO, manténgase en sandboxed y use page:metadata. Si realmente necesita enviar JavaScript o HTML al navegador del visitante, ese es el caso para elegir native.

Si no está seguro, elija sandboxed. Siempre puede migrar a native más adelante — pero lo contrario es más difícil, porque las características exclusivas de native no tienen equivalente en sandbox.

Sandbox runners 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í.

El runner que la mayoría de los sitios usan hoy es sandbox() de @emdash-cms/cloudflare, que usa el Dynamic Worker Loader de Cloudflare Workers. Worker Loader cachea el aislamiento V8 por ID de plugin, por lo que el costo de arranque en frío del aislamiento solo se paga una vez; el runner construye un worker stub 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 hay un runner configurado, o si el runner configurado informa que no está disponible en la plataforma actual, los plugins listados bajo sandboxed: [] se omiten al inicio con un log de nivel debug.

Si desea que un plugin de formato estándar se ejecute en una plataforma sin un sandbox runner, muévalo de sandboxed: [] al array plugins: [] — se ejecutará en proceso. Las declaraciones de capacidades aún se respetan (la misma fábrica PluginContext restringe ctx.content, ctx.http y similares), 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 event loop. Sin un sandbox runner activo, trate cada plugin como un plugin nativo a efectos de confianza.

Siguiente