Choisir un format de plugin

Sur cette page

Les plugins EmDash sont livrés dans l’un des deux formats : sandboxed ou native. Le choix affecte la manière dont le plugin est installé, l’application qu’il obtient au moment de l’exécution et les fonctionnalités disponibles.

Par défaut, sandboxed. Les plugins sandboxés peuvent être publiés sur le marketplace et installés depuis l’interface d’administration en un clic. Les plugins natifs nécessitent une modification du code, un npm install et un redéploiement sur chaque site qui les souhaite. Sandboxed est ce que les utilisateurs finaux veulent.

Choisissez natif uniquement lorsque vous avez besoin d’une fonctionnalité que le sandbox ne peut pas fournir.

En un coup d’œil

SandboxedNative
Forme d’authoringemdash-plugin.jsonc + src/plugin.tsDescripteur definePlugin()
Méthode d’installationUn clic depuis le marketplace d’administrationnpm install + éditer astro.config
S’exécute dansUn runtime isolé fourni par un sandbox runnerLe même processus que votre site Astro
CapacitésAppliquées par le pont du sandboxAppliquées en processus par le même pont
Limites de ressourcesAppliquées par le runner — typiquement CPU, subrequests, wall-time, mémoireAucune
Accès réseauctx.http uniquement, restreint à allowedHostsctx.http uniquement, restreint à allowedHosts
fetch() / process.env directsBloqués par le runnerPossible (le code du plugin partage le runtime)
DistributionBundle .tar.gz sur le marketplacePaquet npm
Interface d’administrationRoutes Block Kit (décrites en JSON)Composants React, ou Block Kit
Interface de paramètresPage Block Kit + lectures KVadmin.settingsSchema (formulaire automatique) ou Block Kit
Composants de rendu Portable TextNon disponiblecomponentsEntry fournit des composants Astro
Contributions de métadonnées de pageHook page:metadata — balises meta/property, rels <link> autorisés, JSON-LDHook page:metadata (même surface)
Injection de fragments de pageNon disponible — uniquement meta/JSON-LD via page:metadataHook page:fragments — scripts inline, scripts externes, HTML brut
Options du constructeurAucune — lire les paramètres depuis KV au runtimeoptions sur le descripteur

Ce que vous abandonnez en choisissant natif

Les plugins natifs ressemblent à une version plus puissante de la même chose, et ils le sont — mais le coût est élevé :

  • Pas de marketplace. Chaque site doit installer votre paquet npm, éditer astro.config.mjs et redéployer.
  • Pas d’isolation. Un bug dans votre plugin peut planter le processus hôte ou brûler son budget CPU. Un rejet non géré dans un hook peut faire tomber la requête environnante avec lui.
  • Charge de confiance sur l’utilisateur. Les plugins natifs ont le même accès que le site hôte. Les utilisateurs finaux ne peuvent pas les auditer uniquement par des déclarations de capacités.

Si votre plugin peut faire son travail dans le sandbox, il devrait le faire.

Quand choisir natif

Il y a trois raisons de choisir natif, et elles concernent toutes des fonctionnalités qui nécessitent une intégration au moment de la compilation avec le site hôte :

  1. Pages ou widgets d’administration React personnalisés. Les plugins sandboxés décrivent leur interface d’administration avec Block Kit — un schéma JSON que l’administrateur rend au nom du plugin. Si vous avez besoin de React complet (hooks personnalisés, composants tiers, état complexe), vous avez besoin de natif.

  2. Composants Astro pour le rendu de blocs Portable Text sur le site public. Un plugin sandboxé peut déclarer un type de bloc personnalisé, mais les composants Astro qui le rendent sur le site public doivent être chargés au moment de la compilation depuis npm. Seuls les plugins natifs peuvent fournir un componentsEntry.

  3. Injecter du HTML brut, des scripts ou des feuilles de style dans des pages publiques. Le hook page:fragments envoie du code first-party aux navigateurs des visiteurs — en dehors de toute limite de sandbox. Il est restreint aux plugins natifs. Les plugins sandboxés peuvent toujours contribuer aux pages publiques via le hook page:metadata, qui couvre de nombreux cas d’utilisation réels :

    • Balises meta (name + content) — descriptions SEO, directives robots, cartes Twitter
    • Balises property — OpenGraph et autres méta basés sur les propriétés
    • Balises link avec une liste blanche rel verrouillée par sécurité (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch et des rels similaires de chargement de ressources ne sont délibérément pas autorisés
    • Graphes JSON-LD

    Si votre besoin “d’injection de page” concerne des données structurées ou des métadonnées SEO, restez sandboxé et utilisez page:metadata. Si vous devez réellement envoyer du JavaScript ou du HTML au navigateur du visiteur, c’est le cas pour choisir natif.

Si vous n’êtes pas sûr, choisissez sandboxed. Vous pouvez toujours migrer vers natif plus tard — mais l’inverse est plus difficile, car les fonctionnalités natives uniquement n’ont pas d’équivalent sandbox.

Sandbox runners et support de plateforme

Le sandbox lui-même est extensible. EmDash expose une option de configuration sandboxRunner et le runner décide comment le code du plugin est isolé — il n’y a rien de spécifique à Cloudflare dans le format du plugin lui-même.

Le runner que la plupart des sites utilisent aujourd’hui est sandbox() de @emdash-cms/cloudflare, qui utilise Dynamic Worker Loader de Cloudflare Workers. Worker Loader met en cache l’isolat V8 par id de plugin, de sorte que le coût de démarrage à froid de l’isolat n’est payé qu’une seule fois ; le runner construit un stub de worker frais et des bindings de pont à chaque invocation, car les stubs et les bindings sont liés au contexte I/O de la requête appelante. Des runners pour d’autres plateformes (Node.js via workerd, et potentiellement Deno) sont en développement.

Si aucun runner n’est configuré, ou si le runner configuré signale comme non disponible sur la plateforme actuelle, les plugins listés sous sandboxed: [] sont ignorés au démarrage avec un log de niveau de débogage.

Si vous souhaitez qu’un plugin sandboxé s’exécute sur une plateforme sans sandbox runner, déplacez-le de sandboxed: [] dans le tableau plugins: [] — il s’exécutera en processus. Les déclarations de capacités sont toujours respectées (la même factory PluginContext contrôle ctx.content, ctx.http et amis), mais il n’y a pas de limite d’isolation, pas de limites de ressources, et un plugin bogué ou malveillant peut appeler fetch() directement, lire des variables d’environnement ou bloquer la boucle d’événements. Sans un sandbox runner actif, traitez chaque plugin comme un plugin natif à des fins de confiance.

Suivant