Escolher um formato de plugin

Nesta página

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

Use sandboxed por padrão. Plugins sandboxed podem ser publicados no marketplace e instalados da interface de administração com um clique. Plugins nativos exigem uma alteração de código, um npm install e uma reimplantação em cada site que os desejar. Sandboxed é o que os usuários finais querem.

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

De relance

SandboxedNative
Campo format no descritor"standard""native"
Método de instalaçãoUm clique no 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, subrequisições, tempo de execução, memóriaNenhum
Acesso à redeApenas ctx.http, restrito a allowedHostsApenas ctx.http, restrito a allowedHosts
fetch() / process.env diretoBloqueado 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 tempo de execuçãooptions no descritor

O que você abre mão ao escolher native

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

  • Sem marketplace. Cada site precisa instalar seu pacote npm, editar astro.config.mjs e reimplantar.
  • Sem isolamento. Um bug em seu plugin pode travar o processo host ou esgotar seu orçamento de CPU. Uma rejeição não tratada em um hook pode derrubar a requisição circundante junto.
  • 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, deve fazê-lo.

Quando escolher native

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

  1. Páginas de administração ou widgets React personalizados. Plugins sandboxed descrevem sua interface de administração com Block Kit — um schema 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 native.

  2. Componentes Astro para renderizar blocos Portable Text no site público. Um plugin pode declarar um tipo de bloco personalizado com format: "standard", mas os componentes Astro que o renderizam no site público precisam 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 próprio para os 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, Twitter Cards
    • Tags property — OpenGraph e outros metadados baseados em propriedades
    • Tags link com uma lista de permissões de 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” é dados estruturados ou metadados SEO, fique em sandboxed e use page:metadata. Se você realmente precisa enviar JavaScript ou HTML para o navegador do visitante, esse é o caso para escolher native.

Se você não tiver certeza, escolha sandboxed. Você sempre pode migrar para native mais tarde — mas o contrário é mais difícil, porque recursos exclusivos de native 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 o Dynamic Worker Loader do Cloudflare Workers. O Worker Loader armazena em cache o isolado V8 por ID de plugin, então o custo de cold start do isolado é pago apenas uma vez; o runner constrói um worker stub 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 pulados na inicialização com um log de nível debug.

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

Próximo