Distribuer des plugins natifs

Sur cette page

Les plugins natifs sont des paquets npm installés dans le projet hôte et enregistrés dans astro.config.mjs. Le paquet a besoin d’un point d’entrée serveur construit pour son descripteur et pour createPlugin(). S’il fournit aussi des composants React ou Astro, exportez-les comme points d’entrée source distincts afin que l’hôte puisse les compiler pour le bon environnement.

Disposition du paquet

La disposition suivante sépare le runtime serveur du code source navigateur et 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/ est généré. Conservez src/admin/ et src/astro/ dans le tarball publié, car la construction Vite et Astro de l’hôte doit traiter ces points d’entrée.

Exports du paquet

Le package.json suivant construit le point d’entrée serveur et publie les trois points d’entrée :

{
	"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"
}

Supprimez ./admin, src/admin et les dépendances peer réservées à l’administration lorsque le plugin n’a pas d’interface React de confiance. Supprimez ./astro, src/astro et le peer astro lorsqu’il n’a pas de moteur de rendu Portable Text. Ajoutez une dépendance peer pour chaque bibliothèque appartenant à l’hôte qu’importe un point d’entrée source exporté ; cela empêche une seconde instance de React, Kumo, Lingui ou React Query d’entrer dans le bundle d’administration.

Les points d’entrée ont des consommateurs différents :

ExportRequis lorsqueConsommateur
.ToujoursLa configuration Astro importe la fabrique de descripteur ; EmDash importe le createPlugin() nommé à l’exécution.
./adminadminEntry est définiLa construction navigateur de l’hôte importe les tables de composants React.
./astrocomponentsEntry est définiLa construction Astro de l’hôte importe blockComponents.

Les spécificateurs de module du descripteur et du runtime doivent correspondre à ces exports :

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

Gardez synchronisées la version du paquet npm, la version du descripteur et la version de definePlugin(). La version affichée à l’administrateur du site provient de la définition du plugin, et non automatiquement de package.json.

Identité et version du plugin

definePlugin() accepte soit un ID sans portée contenant des lettres minuscules, des chiffres et des tirets, soit un ID avec portée de la forme @scope/name. Utilisez un ID sans portée, en kebab-case, pour un plugin de site, car l’ID occupe aussi un segment de chemin dans /_emdash/api/plugins/<plugin-id>/<route>.

Les valeurs suivantes montrent les formes acceptées et la séparation recommandée entre l’ID du plugin et le nom du paquet 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

Les versions doivent commencer par une séquence sémantique major.minor.patch. Utilisez une version sémantique complète pour le descripteur comme pour le runtime :

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

Configuration TypeScript

Le tsconfig.json suivant couvre un plugin natif avec du code source React et 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"]
}

Exécutez pnpm typecheck sur les points d’entrée source avant d’empaqueter. Le script build ne compile que src/index.ts ; l’hôte compile le code source d’administration et Astro exporté lorsqu’il consomme le paquet.

Inspecter le paquet

Testez le contenu exact du tarball avant de publier. Les commandes ci-dessous supposent qu’un site jetable nommé my-emdash-site se trouve à côté du répertoire du plugin.

  1. Construisez le paquet et vérifiez les types.

    pnpm typecheck
    pnpm build
  2. Créez le tarball npm et examinez la liste des fichiers affichée par npm.

    npm pack

    Pour le paquet d’exemple, npm crée example-plugin-activity-0.1.0.tgz.

  3. Vérifiez que la sortie contient dist/index.mjs, dist/index.d.mts et tous les fichiers source accessibles depuis les modules exportés ./admin et ./astro.

  4. Installez le tarball produit dans le site EmDash jetable.

    cd ../my-emdash-site
    pnpm add ../plugin-activity/example-plugin-activity-0.1.0.tgz
  5. Importez et enregistrez la fabrique de descripteur dans le astro.config.mjs du site jetable, en suivant Créer et enregistrer le paquet. Construisez ensuite le site hôte.

    pnpm build

    Ouvrez chaque surface d’administration du plugin et affichez chaque bloc Portable Text fourni. Enregistrer le plugin avant la construction amène Astro à résoudre les exports ./admin et ./astro du tarball ; un test du paquet limité au serveur ne peut pas détecter un fichier source navigateur ou .astro manquant.

Contenu du README

Donnez à un opérateur assez d’informations pour installer et évaluer le paquet sans lire son code source. Incluez :

  • une description en une phrase et la version d’EmDash prise en charge
  • la commande d’installation et l’enregistrement complet dans astro.config.mjs
  • la frontière de confiance native et la raison pour laquelle le plugin a besoin d’une exécution native
  • chaque capability déclarée et chaque hôte autorisé, avec la fonctionnalité qui l’utilise
  • les paramètres et leurs valeurs par défaut
  • les composants de mise en page requis, tels que EmDashBodyEnd pour un fragment de fin de body
  • les étapes de mise à niveau pour les changements qui nécessitent une action de l’opérateur

Ne décrivez pas les déclarations de capabilities comme une frontière d’isolation. Elles contrôlent l’accès aux API de ctx, mais le code natif peut toujours utiliser les imports, les variables d’environnement et les appels réseau directs disponibles pour le processus hôte.

Publier sur npm

Publiez une fois le test du tarball réussi :

npm publish --access public

La première publication publique d’un paquet avec portée nécessite --access public. Utilisez le versionnage sémantique pour les versions suivantes. Traitez les changements concernant les options du constructeur, les données stockées, les changements requis côté hôte, les exports du paquet ou les exigences de confiance du plugin comme des décisions de compatibilité. Si une mise à niveau exige une nouvelle capability ou un nouvel hôte autorisé, signalez-le dans les notes de version, même si les installations natives n’ont pas d’invite de consentement aux capabilities.

Installer depuis npm

Un opérateur installe le paquet publié dans le site EmDash :

pnpm add @example/plugin-activity

Importez ensuite sa fabrique de descripteur et enregistrez-la dans astro.config.mjs, comme indiqué dans Créer et enregistrer le paquet. L’installation de la dépendance ne suffit pas à activer le plugin ; c’est la modification de la configuration Astro et le déploiement du site qui terminent l’installation.

Développer contre un site hôte

Construisez le plugin en mode watch :

pnpm dev

Installez le répertoire local depuis le site hôte :

pnpm add ../plugin-activity

Enregistrez la fabrique de descripteur du plugin dans astro.config.mjs, puis démarrez le serveur de développement de l’hôte. Redémarrez le serveur après avoir modifié les métadonnées du descripteur ou les exports du paquet. Si, dans votre configuration, une dépendance de type fichier du gestionnaire de paquets copie les fichiers au lieu de les lier, réinstallez-la après la reconstruction ; une dépendance de workspace ou pnpm link maintient le paquet local connecté pendant le développement.

Frontière du registre

Les paquets natifs ne peuvent pas être publiés dans le registre EmDash. Les plugins du registre utilisent le format de paquet en sandbox, le flux de publication signé et le flux de consentement à l’installation. Si le plugin n’a plus besoin de code d’administration React, de moteurs de rendu Astro, de fragments de confiance ni d’une autre dépendance dans le même processus, convertissez-le au format sandbox avant de le publier via le registre.