Native Plugins sind npm-Pakete, die im Host-Projekt installiert und in astro.config.mjs registriert werden. Das Paket braucht einen gebauten Server-Entry für seinen Descriptor und createPlugin(). Wenn es auch React- oder Astro-Komponenten ausliefert, exportieren Sie diese als separate Source-Entrypoints, damit der Host sie für die richtige Umgebung kompilieren kann.
Paketlayout
Das folgende Layout trennt die Server-Runtime von Browser- und Astro-Source:
plugin-activity/
├── src/
│ ├── index.ts
│ ├── admin/
│ │ ├── index.tsx
│ │ └── ActivityPage.tsx
│ └── astro/
│ ├── index.ts
│ └── ActivityBlock.astro
├── dist/
│ ├── index.mjs
│ └── index.d.mts
├── package.json
├── tsconfig.json
└── README.md
dist/ wird generiert. Behalten Sie src/admin/ und src/astro/ im veröffentlichten Tarball, weil der Vite- und Astro-Build des Hosts diese Entrypoints verarbeiten muss.
Paketexporte
Die folgende package.json baut den Server-Entry und veröffentlicht alle drei Entrypoints:
{
"name": "@example/plugin-activity",
"version": "0.1.0",
"type": "module",
"main": "./dist/index.mjs",
"exports": {
".": {
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs"
},
"./admin": "./src/admin/index.tsx",
"./astro": "./src/astro/index.ts"
},
"files": ["dist", "src/admin", "src/astro"],
"scripts": {
"build": "tsdown src/index.ts --format esm --dts --clean",
"dev": "tsdown src/index.ts --format esm --dts --watch",
"typecheck": "tsc --noEmit",
"prepublishOnly": "pnpm typecheck && pnpm build"
},
"peerDependencies": {
"@cloudflare/kumo": "*",
"@emdash-cms/admin": "*",
"@lingui/core": "*",
"@lingui/react": "*",
"@tanstack/react-query": "*",
"astro": ">=6.0.0-beta.0",
"emdash": "*",
"react": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@types/react": "^19.0.0",
"tsdown": "^0.20.0",
"typescript": "^5.9.0"
},
"keywords": ["emdash", "emdash-plugin"],
"license": "MIT"
}
Entfernen Sie ./admin, src/admin und die admin-only Peer-Dependencies, wenn das Plugin keine vertrauenswürdige React-UI hat. Entfernen Sie ./astro, src/astro und den astro-Peer, wenn es keinen Portable-Text-Renderer hat. Fügen Sie eine Peer-Dependency für jede host-eigene Bibliothek hinzu, die ein exportierter Source-Entrypoint importiert; das verhindert, dass eine zweite React-, Kumo-, Lingui- oder React-Query-Instanz in das Admin-Bundle gelangt.
Die Entrypoints haben unterschiedliche Konsumenten:
| Export | Erforderlich wenn | Konsument |
|---|---|---|
. | Immer | Die Astro-Konfiguration importiert die Descriptor-Factory; EmDash importiert das benannte createPlugin() zur Laufzeit. |
./admin | adminEntry ist gesetzt | Der Browser-Build des Hosts importiert die React-Komponenten-Maps. |
./astro | componentsEntry ist gesetzt | Der Astro-Build des Hosts importiert blockComponents. |
Die Modul-Specifier im Descriptor und in der Runtime müssen diesen Exporten entsprechen:
export function activityPlugin(): PluginDescriptor {
return {
id: "plugin-activity",
version: "0.1.0",
format: "native",
entrypoint: "@example/plugin-activity",
adminEntry: "@example/plugin-activity/admin",
componentsEntry: "@example/plugin-activity/astro",
};
}
export function createPlugin() {
return definePlugin({
id: "plugin-activity",
version: "0.1.0",
admin: {
entry: "@example/plugin-activity/admin",
},
});
}
Halten Sie die npm-Paketversion, die Descriptor-Version und die definePlugin()-Version synchron. Die einem Site-Administrator angezeigte Version kommt aus der Plugin-Definition, nicht automatisch aus package.json.
Plugin-Identität und Version
definePlugin() akzeptiert entweder eine unscopierte ID mit Kleinbuchstaben, Ziffern und Bindestrichen oder eine scopierte ID in der Form @scope/name. Verwenden Sie für ein Site-Plugin eine unscopierte kebab-case-ID, weil die ID auch ein Pfadsegment in /_emdash/api/plugins/<plugin-id>/<route> belegt.
Die folgenden Werte zeigen die akzeptierten Formen und die empfohlene Trennung zwischen Plugin-ID und npm-Paketname:
id: "plugin-activity"; // Empfohlen: gültig in Plugin-Routen-URLs
id: "@example/plugin-activity"; // Von definePlugin() akzeptiert, aber nicht ein URL-Segment
entrypoint: "@example/plugin-activity"; // Das npm-Paket darf scopiert bleiben
Versionen müssen mit einer semantischen major.minor.patch-Sequenz beginnen. Verwenden Sie eine vollständige semantische Version für Descriptor und Runtime:
version: "1.0.0"; // Gültig
version: "1.2.3-beta.1"; // Gültige Prerelease
version: "1.0"; // Ungültig: fehlende Patch-Version
TypeScript-Konfiguration
Der native Scaffold erzeugt eine passende tsconfig.json. Wenn das Plugin nach dem Scaffolden React- und Astro-Source hinzufügt, schließen Sie beide JSX-Umgebungen ein:
{
"compilerOptions": {
"target": "ES2022",
"module": "preserve",
"moduleResolution": "bundler",
"strict": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react-jsx",
"types": ["astro/client"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Führen Sie pnpm typecheck gegen die Source-Entrypoints aus, bevor Sie paketieren. Das build-Skript kompiliert nur src/index.ts; der Host kompiliert die exportierte Admin- und Astro-Source, wenn er das Paket konsumiert.
Das Paket prüfen
Testen Sie den genauen Tarball-Inhalt vor dem Veröffentlichen. Die Befehle unten gehen davon aus, dass eine Wegwerf-Site namens my-emdash-site neben dem Plugin-Verzeichnis liegt.
-
Bauen und typechecken Sie das Paket.
pnpm typecheck pnpm build -
Erstellen Sie den npm-Tarball und prüfen Sie die von npm gedruckte Dateiliste.
npm packFür das Beispielpaket erzeugt npm
example-plugin-activity-0.1.0.tgz. -
Bestätigen Sie, dass die Ausgabe
dist/index.mjs,dist/index.d.mtsund jede Source-Datei enthält, die von den exportierten Modulen./adminund./astroerreichbar ist. -
Installieren Sie den erzeugten Tarball in der Wegwerf-EmDash-Site.
cd ../my-emdash-site pnpm add ../plugin-activity/example-plugin-activity-0.1.0.tgz -
Importieren und registrieren Sie die Descriptor-Factory in der
astro.config.mjsder Wegwerf-Site gemäß Paket erstellen und registrieren. Bauen Sie dann die Host-Site.pnpm buildÖffnen Sie jede Plugin-Admin-Oberfläche und rendern Sie jeden beigetragenen Portable-Text-Block. Das Registrieren vor dem Build lässt Astro die
./admin- und./astro-Exporte des Tarballs auflösen; ein server-only Pakettest kann eine fehlende Browser- oder.astro-Source-Datei nicht fangen.
README-Inhalte
Geben Sie einem Betreiber genug Informationen, um das Paket zu installieren und zu bewerten, ohne seinen Quellcode zu lesen. Enthalten Sie:
- eine Ein-Satz-Beschreibung und die unterstützte EmDash-Version
- den Installationsbefehl und die vollständige
astro.config.mjs-Registrierung - die native Vertrauensgrenze und warum das Plugin native Ausführung braucht
- jede deklarierte Capability und jeden erlaubten Host, mit dem Feature, das sie nutzt
- Einstellungen und ihre Defaults
- erforderliche Layout-Komponenten, etwa
EmDashBodyEndfür ein body-end-Fragment - Upgrade-Schritte für Änderungen, die eine Betreiberaktion erfordern
Beschreiben Sie Capability-Deklarationen nicht als Isolationsgrenze. Sie gated ctx-APIs, aber nativer Code kann weiterhin Imports, Umgebungsvariablen und direkte Netzwerkaufrufe nutzen, die dem Host-Prozess zur Verfügung stehen.
Bei npm veröffentlichen
Veröffentlichen Sie, nachdem der Tarball-Test bestanden hat:
npm publish --access public
Die erste öffentliche Veröffentlichung eines scopierten Pakets braucht --access public. Verwenden Sie semantische Versionierung für spätere Releases. Behandeln Sie Änderungen an Constructor-Optionen, gespeicherten Daten, erforderlichen Host-Änderungen, Paketexporten oder den Vertrauensanforderungen des Plugins als Kompatibilitätsentscheidungen. Wenn ein Upgrade eine neue Capability oder einen erlaubten Host braucht, erwähnen Sie das in den Release Notes, auch wenn native Installationen keinen Capability-Consent-Prompt haben.
Von npm installieren
Ein Betreiber installiert das veröffentlichte Paket in der EmDash-Site:
pnpm add @example/plugin-activity
Importieren und registrieren Sie dann seine Descriptor-Factory in astro.config.mjs wie in Paket erstellen und registrieren gezeigt. Die Abhängigkeit allein zu installieren aktiviert das Plugin nicht; das Ändern der Astro-Konfiguration und das Deployen der Site schließen die Installation ab.
Gegen eine Host-Site entwickeln
Bauen Sie das Plugin im Watch-Modus:
pnpm dev
Installieren Sie das lokale Verzeichnis von der Host-Site:
pnpm add ../plugin-activity
Registrieren Sie die Descriptor-Factory des Plugins in astro.config.mjs und starten Sie dann den Host-Entwicklungsserver. Starten Sie den Server neu, nachdem Sie Descriptor-Metadaten oder Paketexporte geändert haben. Wenn eine Paketmanager-Dateiabhängigkeit in Ihrem Setup Dateien kopiert statt zu verlinken, installieren Sie sie nach dem Rebuild neu; eine Workspace-Abhängigkeit oder pnpm link hält das lokale Paket während der Entwicklung verbunden.
Registry-Grenze
Native Pakete können nicht in der EmDash-Registry veröffentlicht werden. Registry-Plugins nutzen das sandboxed Paketformat, den signierten Release-Workflow und den Installations-Consent-Flow. Wenn das Plugin keine React-Admin-Code, Astro-Renderer, vertrauenswürdige Fragmente oder eine andere In-Process-Abhängigkeit mehr braucht, konvertieren Sie es in das sandboxed Format, bevor Sie über die Registry veröffentlichen.