Un plugin nativo es un paquete npm que EmDash importa en el mismo proceso que el sitio Astro. Este tutorial crea un plugin que registra los guardados de contenido, lo instala en un sitio y lo registra en astro.config.mjs.
Usa el formato nativo cuando el plugin necesite una función in-process como componentes de administración React, componentes de renderizado Astro o fragmentos de página de confianza. Si hooks, rutas, storage y Block Kit cubren la función, empieza con un plugin sandboxed. Elegir un formato de plugin compara los formatos.
Requisitos previos
Empieza con un sitio EmDash que use pnpm y pueda ejecutar su servidor de desarrollo. El sitio ya debe depender de emdash, que proporciona el comando emdash usado abajo.
Los comandos llaman al directorio del sitio my-emdash-site y crean plugin-activity a su lado. Sustituye my-emdash-site por el nombre del directorio de tu sitio.
Crear y registrar el paquete
-
Genera un paquete nativo junto al sitio.
pnpm exec emdash plugin init --native --name @example/plugin-activity --dir ../plugin-activityEl comando elimina el scope de npm cuando crea el ID del plugin. El nombre del paquete es
@example/plugin-activity, mientras que el ID del plugin esplugin-activity. -
Instala las dependencias del paquete.
cd ../plugin-activity pnpm install -
Sustituye el
src/index.tsgenerado por un hook de guardado de contenido.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:afterSaverequiere la capabilitycontent:read. EmDash omite el hook cuando falta esa capability. -
Construye el paquete.
pnpm build -
Instala el paquete local en el sitio.
cd ../my-emdash-site pnpm add ../plugin-activity -
Registra la factory del descriptor en la integración 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 })], }), ], });Los descriptores nativos pertenecen a
plugins, no asandboxed. EmDash rechaza un descriptor nativo en el arraysandboxed. -
Arranca el sitio y guarda una entrada en el panel de administración.
pnpm devEl registro del servidor incluye
Content savedcon la colección, el ID de contenido y si la entrada se creó.
Límite entre descriptor y runtime
La exportación del paquete tiene dos trabajos. EmDash usa cada uno en una etapa distinta:
- La factory del descriptor,
activityPlugin(), se ejecuta mientras Astro evalúa su configuración. Devuelve metadatos serializables de tiempo de build:id,version,format,entrypointyoptions. Los entrypoints de React y Astro también pertenecen a este descriptor. - La exportación con nombre
createPlugin()se ejecuta cuando EmDash se inicializa. EmDash la importa desdeentrypoint, pasa lasoptionsserializadas y espera un plugin resuelto dedefinePlugin().
La exportación con nombre createPlugin es obligatoria. Una exportación por defecto puede ser útil para los consumidores del paquete, pero el cargador nativo de EmDash importa createPlugin por nombre.
Mantén id y version idénticos en el descriptor y en definePlugin(). Usa un ID de plugin sin scope y en kebab-case como plugin-activity; conserva el scope de npm en el nombre del paquete y en entrypoint. Así el ID sigue siendo usable como el único segmento de plugin en las URL de rutas de API.
Identidad y versionado del plugin enumera las formas de ID y versión aceptadas.
El comportamiento en runtime pertenece a definePlugin():
capabilitiesyallowedHostsstoragehooksyroutes- declaraciones de ajustes, página, widget y Portable Text de
admin
El descriptor lleva las entradas estáticas que Astro debe importar o exponer en tiempo de build. Las guías enfocadas muestran qué campos de administración necesitan declaraciones coincidentes de descriptor y runtime.
Handlers de rutas nativas
Los handlers de rutas nativas reciben un RouteContext. Combina la entrada validada y los datos de la petición con el PluginContext habitual:
routes: {
status: {
permission: "plugins:read",
handler: async (ctx) => ({
pluginId: ctx.plugin.id,
callerId: ctx.user?.id ?? null,
}),
},
},
El handler sandboxed equivalente recibe (routeCtx, ctx) como dos argumentos. Autenticación, permisos, esquemas de entrada y URL de rutas siguen por lo demás el contrato compartido de rutas API.
Envuelve una ruta nativa en definePluginRoute() cuando declare request.body; el helper infiere
ctx.input a partir del modo del body. Una ruta nativa con response: "raw" devuelve pluginResponse().
Importa ambos helpers desde emdash. La guía compartida de rutas API enumera los modos de body, límites, política de respuesta y valores predeterminados de compatibilidad.
Añadir otra superficie
- Páginas y widgets de administración React cubre ajustes, páginas personalizadas, widgets del dashboard, paneles del editor y columnas de lista.
- Componentes de renderizado Portable Text registra componentes Astro para bloques del plugin.
- Fragmentos de página añade scripts o HTML de confianza a páginas públicas.
- Distribuir plugins nativos empaqueta los entrypoints de build y fuente para npm.