Distribuire plugin nativi

In questa pagina

I plugin nativi sono pacchetti npm installati nel progetto host e registrati in astro.config.mjs. Il pacchetto richiede un entry point server compilato per il suo descrittore e per createPlugin(). Se include anche componenti React o Astro, esportali come entry point sorgente separati, in modo che l’host possa compilarli per l’ambiente corretto.

Layout del pacchetto

Il layout seguente separa il runtime del server dal sorgente per il browser e per 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/ viene generata. Mantieni src/admin/ e src/astro/ nel tarball pubblicato, perché la build Vite e Astro dell’host deve elaborare quegli entry point.

Export del pacchetto

Il package.json seguente compila l’entry point server e pubblica tutti e tre gli entry point:

{
	"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 dipendenze peer riservate all’amministrazione quando il plugin non ha un’interfaccia React attendibile. Rimuovi ./astro, src/astro e il peer astro quando non ha un renderer Portable Text. Aggiungi una dipendenza peer per ogni libreria di proprietà dell’host importata da un entry point sorgente esportato; questo impedisce che una seconda istanza di React, Kumo, Lingui o React Query entri nel bundle di amministrazione.

Gli entry point hanno consumatori diversi:

ExportNecessario quandoConsumatore
.SempreLa configurazione di Astro importa la factory del descrittore; EmDash importa a runtime il createPlugin() con nome.
./adminadminEntry è impostatoLa build per il browser dell’host importa le mappe dei componenti React.
./astrocomponentsEntry è impostatoLa build Astro dell’host importa blockComponents.

Gli specificatori di modulo nel descrittore 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 descrittore e la versione di definePlugin(). La versione mostrata all’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 del 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 l’ID del plugin e il nome del pacchetto npm:

id: "plugin-activity"; // Recommended: valid in plugin route URLs
id: "@example/plugin-activity"; // Accepted by definePlugin(), but not one URL segment

entrypoint: "@example/plugin-activity"; // The npm package may stay scoped

Le versioni devono iniziare con una sequenza semantica major.minor.patch. Usa una versione semantica completa sia per il descrittore sia per il runtime:

version: "1.0.0"; // Valid
version: "1.2.3-beta.1"; // Valid prerelease
version: "1.0"; // Invalid: missing patch version

Configurazione TypeScript

Il tsconfig.json seguente copre un plugin nativo con sorgenti React e Astro:

{
	"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 entry point sorgente prima di creare il pacchetto. Lo script build compila solo src/index.ts; l’host compila i sorgenti esportati di amministrazione e Astro quando utilizza il pacchetto.

Ispezionare il pacchetto

Prova l’esatto contenuto del tarball prima di pubblicare. I comandi seguenti presuppongono che un sito usa e getta chiamato my-emdash-site si trovi accanto alla directory del plugin.

  1. Compila il pacchetto e verifica i tipi.

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

    npm pack

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

  3. Verifica 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 descrittore nel file astro.config.mjs del sito usa e getta, seguendo Creare e registrare il pacchetto. Poi compila il sito host.

    pnpm build

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

Contenuti del README

Fornisci a un operatore informazioni sufficienti per installare e valutare il pacchetto senza leggerne il codice sorgente. Includi:

  • una descrizione di una frase e la versione di EmDash supportata
  • il comando di installazione e la registrazione completa in astro.config.mjs
  • il confine di fiducia nativo e il motivo per cui il plugin richiede l’esecuzione nativa
  • ogni capability dichiarata e ogni host consentito, con la funzionalità che li usa
  • le impostazioni e i loro valori predefiniti
  • i componenti di layout richiesti, come EmDashBodyEnd per un frammento di fine body
  • i passaggi di aggiornamento per le modifiche che richiedono un intervento dell’operatore

Non descrivere le dichiarazioni delle capability come un confine di isolamento. Controllano l’accesso alle API di ctx, ma il codice nativo può comunque usare gli import, le variabili d’ambiente e le chiamate di rete dirette disponibili al processo host.

Pubblicare su npm

Pubblica dopo che il test del tarball è stato superato:

npm publish --access public

La prima release 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 archiviati, alle modifiche richieste all’host, agli export del pacchetto o ai requisiti di fiducia del plugin come decisioni di compatibilità. Se un aggiornamento richiede una nuova capability o un nuovo host consentito, segnalalo nelle note di rilascio anche se le installazioni native non hanno una richiesta di consenso per le 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 descrittore in astro.config.mjs, come mostrato in Creare e registrare il pacchetto. Installare la sola dipendenza non attiva il plugin; l’installazione si completa modificando la configurazione di Astro e distribuendo il sito.

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 descrittore del plugin in astro.config.mjs, poi avvia il server di sviluppo dell’host. Riavvia il server dopo aver modificato i metadati del descrittore o gli export del pacchetto. Se, nella tua configurazione, una dipendenza di tipo file del gestore di pacchetti copia i file invece di collegarli, reinstallala dopo aver ricompilato; una dipendenza di workspace o pnpm link mantiene collegato il pacchetto locale durante lo sviluppo.

Confine del registry

I pacchetti nativi non possono essere pubblicati nel registry di EmDash. I plugin del registry usano il formato di pacchetto in sandbox, il flusso di rilascio firmato e il flusso di consenso all’installazione. Se il plugin non ha più bisogno di codice di amministrazione React, renderer Astro, frammenti attendibili o altre dipendenze nello stesso processo, convertilo al formato sandbox prima di pubblicarlo tramite il registry.