Un plugin native è un pacchetto npm che EmDash importa nello stesso processo del sito Astro. Questo tutorial crea un plugin che registra i salvataggi di contenuto, lo installa in un sito e lo registra in astro.config.mjs.
Usa il formato native quando il plugin ha bisogno di una funzione in-process come componenti di amministrazione React, componenti di rendering Astro o frammenti di pagina di fiducia. Se hook, route, storage e Block Kit coprono la funzione, inizia con un plugin sandboxed. Scegliere un formato di plugin confronta i formati.
Prerequisiti
Inizia con un sito EmDash che usa pnpm e può avviare il suo server di sviluppo. Il sito deve già dipendere da emdash, che fornisce il comando emdash usato sotto.
I comandi chiamano la directory del sito my-emdash-site e creano plugin-activity accanto. Sostituisci my-emdash-site con il nome della directory del tuo sito.
Creare e registrare il pacchetto
-
Genera un pacchetto native accanto al sito.
pnpm exec emdash plugin init --native --name @example/plugin-activity --dir ../plugin-activityIl comando rimuove lo scope npm quando crea l’ID del plugin. Il nome del pacchetto è
@example/plugin-activity, mentre l’ID del plugin èplugin-activity. -
Installa le dipendenze del pacchetto.
cd ../plugin-activity pnpm install -
Sostituisci il
src/index.tsgenerato con un hook di salvataggio contenuti.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:afterSaverichiede la capabilitycontent:read. EmDash salta l’hook quando quella capability manca. -
Compila il pacchetto.
pnpm build -
Installa il pacchetto locale nel sito.
cd ../my-emdash-site pnpm add ../plugin-activity -
Registra la factory del descriptor nell’integrazione 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 })], }), ], });I descriptor native appartengono a
plugins, non asandboxed. EmDash rifiuta un descriptor native nell’arraysandboxed. -
Avvia il sito e salva una voce nel pannello di amministrazione.
pnpm devIl log del server include
Content savedcon la collection, l’ID del contenuto e se la voce è stata creata.
Confine descriptor / runtime
L’export del pacchetto ha due compiti. EmDash usa ciascuno in una fase diversa:
- La factory del descriptor,
activityPlugin(), viene eseguita mentre Astro valuta la sua configurazione. Restituisce metadati serializzabili di build-time:id,version,format,entrypointeoptions. Anche gli entrypoint React e Astro appartengono a questo descriptor. - L’export con nome
createPlugin()viene eseguito quando EmDash si inizializza. EmDash lo importa daentrypoint, passa leoptionsserializzate e si aspetta un plugin risolto dadefinePlugin().
L’export con nome createPlugin è obbligatorio. Un export di default può essere utile ai consumatori del pacchetto, ma il loader native di EmDash importa createPlugin per nome.
Mantieni id e version identici nel descriptor e in definePlugin(). Usa un ID plugin senza scope e in kebab-case come plugin-activity; conserva lo scope npm nel nome del pacchetto e in entrypoint. Così l’ID resta utilizzabile come unico segmento di plugin nelle URL delle route API.
Identità e versionamento del plugin elenca le forme di ID e versione accettate.
Il comportamento runtime appartiene a definePlugin():
capabilitieseallowedHostsstoragehookseroutes- dichiarazioni di impostazioni, pagina, widget e Portable Text di
admin
Il descriptor porta le voci statiche che Astro deve importare o esporre in build-time. Le guide mirate mostrano quali campi di amministrazione richiedono dichiarazioni descriptor e runtime corrispondenti.
Handler di route native
Gli handler di route native ricevono un RouteContext. Combina l’input convalido e i dati della richiesta con il PluginContext abituale:
routes: {
status: {
permission: "plugins:read",
handler: async (ctx) => ({
pluginId: ctx.plugin.id,
callerId: ctx.user?.id ?? null,
}),
},
},
L’handler sandboxed equivalente riceve (routeCtx, ctx) come due argomenti. Autenticazione, permessi, schemi di input e URL delle route seguono altrimenti il contratto condiviso delle route API.
Avvolgi una route native in definePluginRoute() quando dichiara request.body; l’helper inferisce
ctx.input dalla modalità del body. Una route native con response: "raw" restituisce pluginResponse().
Importa entrambi gli helper da emdash. La guida condivisa delle route API elenca le modalità del body, i limiti, la policy di risposta e i default di compatibilità.
Aggiungere un’altra superficie
- Pagine e widget di amministrazione React copre impostazioni, pagine personalizzate, widget della dashboard, pannelli dell’editor e colonne di elenco.
- Componenti di rendering Portable Text registra componenti Astro per i blocchi del plugin.
- Frammenti di pagina aggiunge script o HTML di fiducia alle pagine pubbliche.
- Distribuire plugin native impacchetta gli entrypoint di build e sorgente per npm.