I plugin native sono pacchetti npm installati nel progetto host e registrati in astro.config.mjs. Il pacchetto necessita di un entry server compilato per il suo descriptor e createPlugin(). Se spedisce anche componenti React o Astro, esportali come entrypoint sorgente separati così che l’host possa compilarli per l’ambiente corretto.
Layout del pacchetto
Il layout seguente separa il runtime del server dal codice sorgente del browser e di Astro:
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/ è generato. Mantieni src/admin/ e src/astro/ nel tarball pubblicato perché la build Vite e Astro dell’host deve elaborare quegli entrypoint.
Export del pacchetto
Il seguente package.json costruisce l’entry server e pubblica tutti e tre gli entrypoint:
{
"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"
}
Rimuovi ./admin, src/admin e le peer dependency solo admin quando il plugin non ha UI React di fiducia. Rimuovi ./astro, src/astro e il peer astro quando non ha un renderer Portable Text. Aggiungi una peer dependency per ogni libreria di proprietà dell’host importata da un entrypoint sorgente esportato; questo evita che una seconda istanza di React, Kumo, Lingui o React Query entri nel bundle di amministrazione.
Gli entrypoint hanno consumatori diversi:
| Export | Richiesto quando | Consumatore |
|---|---|---|
. | Sempre | La configurazione Astro importa la factory del descriptor; EmDash importa il createPlugin() con nome a runtime. |
./admin | adminEntry è impostato | La build browser dell’host importa le mappe dei componenti React. |
./astro | componentsEntry è impostato | La build Astro dell’host importa blockComponents. |
Gli specificatori di modulo nel descriptor e nel runtime devono corrispondere a questi export:
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",
},
});
}
Mantieni sincronizzate la versione del pacchetto npm, la versione del descriptor e la versione di definePlugin(). La versione mostrata a un amministratore del sito proviene dalla definizione del plugin, non automaticamente da package.json.
Identità e versione del plugin
definePlugin() accetta un ID senza scope contenente lettere minuscole, cifre e trattini, oppure un ID con scope nella forma @scope/name. Usa un ID senza scope in kebab-case per un plugin di sito perché l’ID occupa anche un segmento di percorso in /_emdash/api/plugins/<plugin-id>/<route>.
I valori seguenti mostrano le forme accettate e la separazione consigliata tra ID del plugin e nome del pacchetto npm:
id: "plugin-activity"; // Consigliato: valido nelle URL delle route del plugin
id: "@example/plugin-activity"; // Accettato da definePlugin(), ma non un segmento URL
entrypoint: "@example/plugin-activity"; // Il pacchetto npm può restare con scope
Le versioni devono iniziare con una sequenza semantica major.minor.patch. Usa una versione semantica completa per il descriptor e il runtime:
version: "1.0.0"; // Valida
version: "1.2.3-beta.1"; // Prerelease valida
version: "1.0"; // Non valida: manca la versione di patch
Configurazione TypeScript
Lo scaffold native crea un tsconfig.json adatto. Se il plugin aggiunge sorgente React e Astro dopo lo scaffolding, includi entrambi gli ambienti JSX:
{
"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"]
}
Esegui pnpm typecheck sugli entrypoint sorgente prima di impacchettare. Lo script build compila solo src/index.ts; l’host compila la sorgente admin e Astro esportata quando consuma il pacchetto.
Ispezionare il pacchetto
Testa il contenuto esatto del tarball prima di pubblicare. I comandi seguenti assumono che un sito usa e getta chiamato my-emdash-site sia accanto alla directory del plugin.
-
Compila e controlla i tipi del pacchetto.
pnpm typecheck pnpm build -
Crea il tarball npm e rivedi l’elenco di file stampato da npm.
npm packPer il pacchetto di esempio, npm crea
example-plugin-activity-0.1.0.tgz. -
Conferma che l’output contenga
dist/index.mjs,dist/index.d.mtse ogni file sorgente raggiungibile dai moduli esportati./admine./astro. -
Installa il tarball prodotto nel sito EmDash usa e getta.
cd ../my-emdash-site pnpm add ../plugin-activity/example-plugin-activity-0.1.0.tgz -
Importa e registra la factory del descriptor nel
astro.config.mjsdel sito usa e getta, seguendo Creare e registrare il pacchetto. Poi costruisci il sito host.pnpm buildApri ogni superficie di amministrazione del plugin e renderizza ogni blocco Portable Text contribuito. Registrare prima della build fa sì che Astro risolva gli export
./admine./astrodel tarball; un test del pacchetto solo server non può individuare un file sorgente browser o.astromancante.
Contenuti del README
Dai a un operatore abbastanza informazioni per installare e valutare il pacchetto senza leggere il suo codice sorgente. Includi:
- una descrizione in una frase e la versione EmDash supportata
- il comando di installazione e la registrazione completa in
astro.config.mjs - il confine di fiducia native e perché il plugin necessita di esecuzione native
- ogni capability dichiarata e host consentito, con la funzione che lo usa
- impostazioni e i loro default
- componenti di layout richiesti, come
EmDashBodyEndper un frammento body-end - passaggi di upgrade per modifiche che richiedono azione dell’operatore
Non descrivere le dichiarazioni di capability come un confine di isolamento. Limitano le API di ctx, ma il codice native può ancora usare import, variabili d’ambiente e chiamate di rete dirette disponibili al processo host.
Pubblicare su npm
Pubblica dopo che il test del tarball è passato:
npm publish --access public
La prima pubblicazione pubblica di un pacchetto con scope richiede --access public. Usa il versionamento semantico per le release successive. Tratta le modifiche alle opzioni del costruttore, ai dati memorizzati, alle modifiche host richieste, agli export del pacchetto o ai requisiti di fiducia del plugin come decisioni di compatibilità. Se un upgrade richiede una nuova capability o un host consentito, segnalalo nelle note di release anche se le installazioni native non hanno un prompt di consenso alle capability.
Installare da npm
Un operatore installa il pacchetto pubblicato nel sito EmDash:
pnpm add @example/plugin-activity
Poi importa e registra la sua factory del descriptor in astro.config.mjs come mostrato in Creare e registrare il pacchetto. Installare la dipendenza da sola non attiva il plugin; modificare la configurazione Astro e distribuire il sito completa l’installazione.
Sviluppare contro un sito host
Compila il plugin in modalità watch:
pnpm dev
Installa la directory locale dal sito host:
pnpm add ../plugin-activity
Registra la factory del descriptor del plugin in astro.config.mjs, poi avvia il server di sviluppo dell’host. Riavvia il server dopo aver modificato i metadati del descriptor o gli export del pacchetto. Se una dipendenza file del package manager copia i file invece di collegarli nella tua configurazione, reinstallala dopo la ricostruzione; una dipendenza workspace o pnpm link mantiene il pacchetto locale connesso durante lo sviluppo.
Confine del registry
I pacchetti native non possono essere pubblicati nel registry EmDash. I plugin del registry usano il formato di pacchetto sandboxed, il flusso di release firmato e il flusso di consenso all’installazione. Se il plugin non ha più bisogno di codice di amministrazione React, renderer Astro, frammenti di fiducia o un’altra dipendenza in-process, convertilo al formato sandboxed prima di pubblicare tramite il registry.