Escolhendo um formato de plugin

Nesta página

Os plugins EmDash são fornecidos em um dos dois formatos: sandboxed ou native. A escolha afeta como o plugin é instalado, que aplicação ele recebe em tempo de execução e quais recursos estão disponíveis.

O padrão é sandboxed. Plugins sandboxed podem ser publicados no marketplace e instalados da interface de administração com um clique. Plugins nativos requerem uma mudança de código, um npm install e um novo deploy em cada site que os deseja. Sandboxed é o que os usuários finais querem.

Escolha nativo apenas quando você precisar de um recurso que o sandbox não pode fornecer.

De relance

SandboxedNative
Forma de autoriaemdash-plugin.jsonc + src/plugin.tsDescritor definePlugin()
Método de instalaçãoUm clique do marketplace de administraçãonpm install + editar astro.config
Executa emUm runtime isolado fornecido por um sandbox runnerMesmo processo que seu site Astro
CapacidadesAplicadas pela ponte do sandboxAplicadas em processo pela mesma ponte
Limites de recursosAplicados pelo runner — tipicamente CPU, subrequests, wall-time, memóriaNenhum
Acesso à redeApenas ctx.http, restrito a allowedHostsApenas ctx.http, restrito a allowedHosts
fetch() / process.env diretosBloqueados pelo runnerPossível (código do plugin compartilha o runtime)
DistribuiçãoBundle .tar.gz no marketplacePacote npm
Interface de administraçãoRotas Block Kit (descritas em JSON)Componentes React, ou Block Kit
Interface de configuraçõesPágina Block Kit + leituras KVadmin.settingsSchema (formulário automático) ou Block Kit
Componentes de renderização Portable TextNão disponívelcomponentsEntry fornece componentes Astro
Contribuições de metadados de páginaHook page:metadata — tags meta/property, rels <link> permitidos, JSON-LDHook page:metadata (mesma superfície)
Injeção de fragmentos de páginaNão disponível — apenas meta/JSON-LD via page:metadataHook page:fragments — scripts inline, scripts externos, HTML bruto
Opções do construtorNenhuma — ler configurações do KV em runtimeoptions no descritor

O que você perde ao escolher nativo

Plugins nativos parecem uma versão mais poderosa da mesma coisa, e eles são — mas o custo é alto:

  • Sem marketplace. Cada site tem que instalar seu pacote npm, editar astro.config.mjs e reimplantar.
  • Sem isolamento. Um bug no seu plugin pode travar o processo host ou queimar seu orçamento de CPU. Uma rejeição não tratada em um hook pode derrubar a requisição ao redor com ela.
  • Carga de confiança no usuário. Plugins nativos têm o mesmo acesso que o site host. Usuários finais não podem auditá-los apenas através de declarações de capacidades.

Se seu plugin pode fazer seu trabalho no sandbox, ele deveria fazê-lo.

Quando escolher nativo

Existem três razões para escolher nativo, e todas são sobre recursos que precisam de integração em tempo de compilação com o site host:

  1. Páginas ou widgets de administração React personalizados. Plugins sandboxed descrevem sua interface de administração com Block Kit — um esquema JSON que o administrador renderiza em nome do plugin. Se você precisa de React completo (hooks personalizados, componentes de terceiros, estado complexo), você precisa de nativo.

  2. Componentes Astro para renderizar blocos Portable Text no site público. Um plugin sandboxed pode declarar um tipo de bloco personalizado, mas os componentes Astro que o renderizam no site público devem ser carregados em tempo de compilação do npm. Apenas plugins nativos podem fornecer um componentsEntry.

  3. Injetar HTML bruto, scripts ou folhas de estilo em páginas públicas. O hook page:fragments envia código first-party aos navegadores dos visitantes — fora de qualquer limite de sandbox. É restrito a plugins nativos. Plugins sandboxed ainda podem contribuir para páginas públicas através do hook page:metadata, que cobre muitos casos de uso reais:

    • Tags meta (name + content) — descrições SEO, diretivas de robôs, cards do Twitter
    • Tags property — OpenGraph e outros meta baseados em propriedades
    • Tags link com uma lista de permissões rel bloqueada por segurança (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch e rels similares de carregamento de recursos não são deliberadamente permitidos
    • Grafos JSON-LD

    Se sua necessidade de “injeção de página” for dados estruturados ou metadados SEO, fique sandboxed e use page:metadata. Se você realmente precisa enviar JavaScript ou HTML para o navegador do visitante, esse é o caso para escolher nativo.

Se você não tem certeza, escolha sandboxed. Você sempre pode migrar para nativo mais tarde — mas o reverso é mais difícil, porque recursos exclusivos de nativo não têm equivalente em sandbox.

Sandbox runners e suporte de plataforma

O sandbox em si é plugável. EmDash expõe uma opção de configuração sandboxRunner e o runner decide como o código do plugin é isolado — não há nada específico do Cloudflare no formato do plugin em si.

O runner que a maioria dos sites usa hoje é sandbox() de @emdash-cms/cloudflare, que usa Dynamic Worker Loader do Cloudflare Workers. O Worker Loader armazena em cache o isolado V8 por id de plugin, então o custo de inicialização a frio do isolado é pago apenas uma vez; o runner constrói um stub de worker fresco e bindings de ponte em cada invocação, já que stubs e bindings estão vinculados ao contexto de I/O da requisição chamadora. Runners para outras plataformas (Node.js via workerd, e potencialmente Deno) estão em desenvolvimento.

Se nenhum runner estiver configurado, ou se o runner configurado reportar como indisponível na plataforma atual, plugins listados sob sandboxed: [] são ignorados na inicialização com um log de nível de debug.

Se você quiser que um plugin sandboxed execute em uma plataforma sem um sandbox runner, mova-o de sandboxed: [] para o array plugins: [] — ele executará em processo. Declarações de capacidades ainda são respeitadas (a mesma factory PluginContext controla ctx.content, ctx.http e amigos), mas não há limite de isolamento, sem limites de recursos, e um plugin com bug ou malicioso pode chamar fetch() diretamente, ler variáveis de ambiente ou bloquear o loop de eventos. Sem um sandbox runner ativo, trate cada plugin como um plugin nativo para fins de confiança.

Próximo