Distribuire plugin native

In questa pagina

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:

ExportRichiesto quandoConsumatore
.SempreLa configurazione Astro importa la factory del descriptor; EmDash importa il createPlugin() con nome a runtime.
./adminadminEntry è impostatoLa build browser dell’host importa le mappe dei componenti React.
./astrocomponentsEntry è impostatoLa 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.

  1. Compila e controlla i tipi del pacchetto.

    pnpm typecheck
    pnpm build
  2. Crea il tarball npm e rivedi l’elenco di file stampato da npm.

    npm pack

    Per il pacchetto di esempio, npm crea example-plugin-activity-0.1.0.tgz.

  3. Conferma che l’output contenga dist/index.mjs, dist/index.d.mts e ogni file sorgente raggiungibile dai moduli esportati ./admin e ./astro.

  4. 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
  5. Importa e registra la factory del descriptor nel astro.config.mjs del sito usa e getta, seguendo Creare e registrare il pacchetto. Poi costruisci il sito host.

    pnpm build

    Apri ogni superficie di amministrazione del plugin e renderizza ogni blocco Portable Text contribuito. Registrare prima della build fa sì che Astro risolva gli export ./admin e ./astro del tarball; un test del pacchetto solo server non può individuare un file sorgente browser o .astro mancante.

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 EmDashBodyEnd per 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.