Ihr erstes natives Plugin

Auf dieser Seite

Ein natives Plugin ist ein npm-Paket, das EmDash in denselben Prozess wie die Astro-Site importiert. Dieses Tutorial erstellt ein Plugin, das Inhaltspeicherungen protokolliert, installiert es in einer Site und registriert es in astro.config.mjs.

Verwenden Sie das native Format, wenn das Plugin ein In-Process-Feature braucht, etwa React-Admin-Komponenten, Astro-Rendering-Komponenten oder vertrauenswürdige Seitenfragmente. Wenn Hooks, Routen, Storage und Block Kit das Feature abdecken, beginnen Sie mit einem sandboxed Plugin. Plugin-Format wählen vergleicht die Formate.

Voraussetzungen

Beginnen Sie mit einer EmDash-Site, die pnpm nutzt und ihren Entwicklungsserver starten kann. Die Site muss bereits von emdash abhängen, das den unten verwendeten Befehl emdash bereitstellt.

Die Befehle nennen das Site-Verzeichnis my-emdash-site und erstellen plugin-activity daneben. Ersetzen Sie my-emdash-site durch den Verzeichnisnamen Ihrer Site.

Paket erstellen und registrieren

  1. Scaffolden Sie ein natives Paket neben der Site.

    pnpm exec emdash plugin init --native --name @example/plugin-activity --dir ../plugin-activity

    Der Befehl entfernt den npm-Scope, wenn er die Plugin-ID erstellt. Der Paketname ist @example/plugin-activity, die Plugin-ID ist plugin-activity.

  2. Installieren Sie die Paketabhängigkeiten.

    cd ../plugin-activity
    pnpm install
  3. Ersetzen Sie die generierte src/index.ts durch einen Content-Save-Hook.

    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:afterSave erfordert die Capability content:read. EmDash überspringt den Hook, wenn diese Capability fehlt.

  4. Bauen Sie das Paket.

    pnpm build
  5. Installieren Sie das lokale Paket in der Site.

    cd ../my-emdash-site
    pnpm add ../plugin-activity
  6. Registrieren Sie die Descriptor-Factory in der EmDash-Integration.

    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 })],
            }),
        ],
    });

    Native Descriptoren gehören in plugins, nicht in sandboxed. EmDash lehnt einen nativen Descriptor im Array sandboxed ab.

  7. Starten Sie die Site und speichern Sie einen Eintrag im Admin-Panel.

    pnpm dev

    Das Serverprotokoll enthält Content saved mit Collection, Content-ID und ob der Eintrag erstellt wurde.

Descriptor- und Runtime-Grenze

Der Paketexport hat zwei Aufgaben. EmDash nutzt jede in einer anderen Phase:

  • Die Descriptor-Factory activityPlugin() läuft, während Astro seine Konfiguration auswertet. Sie gibt serialisierbare Build-Zeit-Metadaten zurück: id, version, format, entrypoint und options. React- und Astro-Entrypoints gehören ebenfalls auf diesen Descriptor.
  • Der benannte Export createPlugin() läuft, wenn EmDash initialisiert. EmDash importiert ihn aus entrypoint, übergibt die serialisierten options und erwartet ein aufgelöstes Plugin von definePlugin().

Der benannte Export createPlugin ist erforderlich. Ein Default-Export kann für Paketnutzer nützlich sein, aber EmDashs nativer Loader importiert createPlugin namentlich.

Halten Sie id und version im Descriptor und in definePlugin() identisch. Verwenden Sie eine unscopierte, kebab-case Plugin-ID wie plugin-activity; behalten Sie den npm-Scope im Paketnamen und in entrypoint. So bleibt die ID als einziges Plugin-Segment in API-Routen-URLs nutzbar.

Plugin-Identität und Versionierung listet die akzeptierten ID- und Versionsformen.

Runtime-Verhalten gehört in definePlugin():

  • capabilities und allowedHosts
  • storage
  • hooks und routes
  • admin-Einstellungen, Seite, Widget und Portable-Text-Deklarationen

Der Descriptor trägt die statischen Einträge, die Astro zur Build-Zeit importieren oder exponieren muss. Die fokussierten Guides zeigen, welche Admin-Felder passende Descriptor- und Runtime-Deklarationen brauchen.

Native Routen-Handler

Native Routen-Handler erhalten ein RouteContext. Es kombiniert validierte Eingabe und Anfragedaten mit dem regulären PluginContext:

routes: {
	status: {
		permission: "plugins:read",
		handler: async (ctx) => ({
			pluginId: ctx.plugin.id,
			callerId: ctx.user?.id ?? null,
		}),
	},
},

Der äquivalente sandboxed Handler erhält (routeCtx, ctx) als zwei Argumente. Authentifizierung, Berechtigungen, Eingabeschemata und Routen-URLs folgen ansonsten dem gemeinsamen Vertrag der API-Routen.

Wickeln Sie eine native Route in definePluginRoute(), wenn sie request.body deklariert; der Helper leitet ctx.input aus dem Body-Modus ab. Eine native Route mit response: "raw" gibt pluginResponse() zurück. Importieren Sie beide Helper aus emdash. Der gemeinsame API-Routen-Guide listet Body-Modi, Limits, Antwortrichtlinie und Kompatibilitätsdefaults.

Eine weitere Oberfläche hinzufügen