Un plugin natif est un paquet npm qu’EmDash importe dans le même processus que le site Astro. Ce tutoriel crée un plugin qui journalise les sauvegardes de contenu, l’installe dans un site et l’enregistre dans astro.config.mjs.
Utilisez le format natif lorsque le plugin a besoin d’une fonctionnalité in-process telle que des composants d’administration React, des composants de rendu Astro ou des fragments de page de confiance. Si les hooks, routes, le storage et Block Kit couvrent la fonctionnalité, commencez par un plugin sandboxed. Choisir un format de plugin compare les formats.
Prérequis
Commencez avec un site EmDash qui utilise pnpm et peut lancer son serveur de développement. Le site doit déjà dépendre de emdash, qui fournit la commande emdash utilisée ci-dessous.
Les commandes appellent le répertoire du site my-emdash-site et créent plugin-activity à côté. Remplacez my-emdash-site par le nom du répertoire de votre site.
Créer et enregistrer le paquet
-
Générez un paquet natif à côté du site.
pnpm exec emdash plugin init --native --name @example/plugin-activity --dir ../plugin-activityLa commande retire le scope npm lorsqu’elle crée l’ID du plugin. Le nom du paquet est
@example/plugin-activity, tandis que l’ID du plugin estplugin-activity. -
Installez les dépendances du paquet.
cd ../plugin-activity pnpm install -
Remplacez le
src/index.tsgénéré par un hook de sauvegarde de contenu.import { definePlugin } from "emdash"; import type { PluginDescriptor } from "emdash"; export interface ActivityPluginOptions { logUpdates?: boolean; } export function activityPlugin( options: ActivityPluginOptions = {}, ): PluginDescriptor<ActivityPluginOptions> { return { id: "plugin-activity", version: "0.1.0", format: "native", entrypoint: "@example/plugin-activity", options, }; } export function createPlugin(options: ActivityPluginOptions = {}) { return definePlugin({ id: "plugin-activity", version: "0.1.0", capabilities: ["content:read"], hooks: { "content:afterSave": async (event, ctx) => { if (!event.isNew && options.logUpdates === false) return; ctx.log.info("Content saved", { collection: event.collection, contentId: event.content.id, isNew: event.isNew, }); }, }, }); } export default createPlugin;content:afterSaveexige la capabilitycontent:read. EmDash ignore le hook lorsque cette capability manque. -
Construisez le paquet.
pnpm build -
Installez le paquet local dans le site.
cd ../my-emdash-site pnpm add ../plugin-activity -
Enregistrez la factory du descripteur dans l’intégration EmDash.
import { defineConfig } from "astro/config"; import emdash from "emdash/astro"; import { activityPlugin } from "@example/plugin-activity"; export default defineConfig({ integrations: [ emdash({ plugins: [activityPlugin({ logUpdates: true })], }), ], });Les descripteurs natifs appartiennent à
plugins, pas àsandboxed. EmDash rejette un descripteur natif dans le tableausandboxed. -
Démarrez le site et enregistrez une entrée dans le panneau d’administration.
pnpm devLe journal du serveur inclut
Content savedavec la collection, l’ID de contenu et si l’entrée a été créée.
Frontière descripteur / runtime
L’export du paquet a deux rôles. EmDash utilise chacun à une étape différente :
- La factory du descripteur,
activityPlugin(), s’exécute pendant qu’Astro évalue sa configuration. Elle renvoie des métadonnées sérialisables au moment du build :id,version,format,entrypointetoptions. Les entrypoints React et Astro appartiennent aussi à ce descripteur. - L’export nommé
createPlugin()s’exécute lorsque EmDash s’initialise. EmDash l’importe depuisentrypoint, passe lesoptionssérialisées et attend un plugin résolu dedefinePlugin().
L’export nommé createPlugin est requis. Un export par défaut peut être utile aux consommateurs du paquet, mais le chargeur natif d’EmDash importe createPlugin par nom.
Gardez id et version identiques dans le descripteur et dans definePlugin(). Utilisez un ID de plugin sans scope et en kebab-case tel que plugin-activity ; conservez le scope npm dans le nom du paquet et dans entrypoint. Ainsi l’ID reste utilisable comme unique segment de plugin dans les URL de routes API.
Identité et versionnement du plugin liste les formes d’ID et de version acceptées.
Le comportement runtime appartient à definePlugin() :
capabilitiesetallowedHostsstoragehooksetroutes- déclarations de paramètres, page, widget et Portable Text de
admin
Le descripteur porte les entrées statiques qu’Astro doit importer ou exposer au moment du build. Les guides ciblés montrent quels champs d’administration ont besoin de déclarations descripteur et runtime correspondantes.
Handlers de routes natifs
Les handlers de routes natifs reçoivent un RouteContext. Il combine l’entrée validée et les données de requête avec le PluginContext habituel :
routes: {
status: {
permission: "plugins:read",
handler: async (ctx) => ({
pluginId: ctx.plugin.id,
callerId: ctx.user?.id ?? null,
}),
},
},
Le handler sandboxed équivalent reçoit (routeCtx, ctx) comme deux arguments. Authentification, permissions, schémas d’entrée et URL de routes suivent autrement le contrat partagé des routes API.
Enveloppez une route native dans definePluginRoute() lorsqu’elle déclare request.body ; l’helper infère
ctx.input à partir du mode du body. Une route native avec response: "raw" renvoie pluginResponse().
Importez les deux helpers depuis emdash. Le guide partagé des routes API liste les modes de body, limites, politique de réponse et valeurs par défaut de compatibilité.
Ajouter une autre surface
- Pages et widgets d’administration React couvre les paramètres, pages personnalisées, widgets du tableau de bord, panneaux d’éditeur et colonnes de liste.
- Composants de rendu Portable Text enregistre des composants Astro pour les blocs du plugin.
- Fragments de page ajoute des scripts ou du HTML de confiance aux pages publiques.
- Distribuer des plugins natifs empaquette les entrypoints de build et de source pour npm.