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
| Sandboxed | Native | |
|---|---|---|
Campo format no descritor | "standard" | "native" |
| Método de instalação | Um clique no marketplace de administração | npm install + editar astro.config |
| Executa em | Um runtime isolado fornecido por um sandbox runner | Mesmo processo que seu site Astro |
| Capacidades | Aplicadas pela ponte do sandbox | Aplicadas em processo pela mesma ponte |
| Limites de recursos | Aplicados pelo runner — tipicamente CPU, subrequisições, tempo de execução, memória | Nenhum |
| Acesso à rede | Apenas ctx.http, restrito a allowedHosts | Apenas ctx.http, restrito a allowedHosts |
fetch() / process.env direto | Bloqueado pelo runner | Possível (código do plugin compartilha o runtime) |
| Distribuição | Bundle .tar.gz no marketplace | Pacote npm |
| Interface de administração | Rotas Block Kit (descritas em JSON) | Componentes React ou Block Kit |
| Interface de configurações | Página Block Kit + leituras KV | admin.settingsSchema (formulário automático) ou Block Kit |
| Componentes de renderização Portable Text | Não disponível | componentsEntry fornece componentes Astro |
| Contribuições de metadados de página | Hook page:metadata — tags meta/property, rels <link> permitidos, JSON-LD | Hook page:metadata (mesma superfície) |
| Injeção de fragmentos de página | Não disponível — apenas meta/JSON-LD via page:metadata | Hook page:fragments — scripts inline, scripts externos, HTML bruto |
| Opções do construtor | Nenhuma — ler configurações do KV em tempo de execução | options 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.mjse 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:
-
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.
-
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 umcomponentsEntry. -
Injetar HTML bruto, scripts ou folhas de estilo em páginas públicas. O hook
page:fragmentsenvia 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 hookpage: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
linkcom uma lista de permissões de rel bloqueada por segurança (canonical,alternate,author,license,nlweb,site.standard.document) —stylesheet,prefetche 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. - Tags
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.