Los plugins nativos son paquetes de npm que se instalan en el proyecto host y se registran en astro.config.mjs. El paquete necesita un punto de entrada de servidor compilado para su descriptor y para createPlugin(). Si además incluye componentes de React o de Astro, expórtalos como puntos de entrada de código fuente independientes para que el host pueda compilarlos para el entorno correcto.
Diseño del paquete
El siguiente diseño separa el runtime del servidor del código fuente del navegador y de 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/ se genera. Mantén src/admin/ y src/astro/ en el tarball publicado, porque la compilación de Vite y de Astro del host debe procesar esos puntos de entrada.
Exportaciones del paquete
El siguiente package.json compila el punto de entrada del servidor y publica los tres puntos de entrada:
{
"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"
}
Elimina ./admin, src/admin y las dependencias peer exclusivas de administración cuando el plugin no tenga una interfaz de React de confianza. Elimina ./astro, src/astro y el peer astro cuando no tenga un renderizador de Portable Text. Añade una dependencia peer por cada biblioteca propiedad del host que importe un punto de entrada de código fuente exportado; así evitas que una segunda instancia de React, Kumo, Lingui o React Query entre en el bundle de administración.
Los puntos de entrada tienen consumidores distintos:
| Exportación | Necesaria cuando | Consumidor |
|---|---|---|
. | Siempre | La configuración de Astro importa la factoría del descriptor; EmDash importa en runtime el createPlugin() con nombre. |
./admin | adminEntry está definido | La compilación de navegador del host importa los mapas de componentes de React. |
./astro | componentsEntry está definido | La compilación de Astro del host importa blockComponents. |
Los especificadores de módulo del descriptor y del runtime deben coincidir con estas exportaciones:
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",
},
});
}
Mantén sincronizadas la versión del paquete de npm, la versión del descriptor y la versión de definePlugin(). La versión que ve el administrador del sitio procede de la definición del plugin, no automáticamente de package.json.
Identidad y versión del plugin
definePlugin() acepta un ID sin ámbito, que contenga letras minúsculas, dígitos y guiones, o un ID con ámbito con la forma @scope/name. Usa un ID sin ámbito en kebab-case para un plugin de sitio, porque el ID también ocupa un segmento de ruta en /_emdash/api/plugins/<plugin-id>/<route>.
Los siguientes valores muestran las formas aceptadas y la separación recomendada entre el ID del plugin y el nombre del paquete de 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
Las versiones deben comenzar con una secuencia semántica major.minor.patch. Usa una versión semántica completa tanto en el descriptor como en el runtime:
version: "1.0.0"; // Valid
version: "1.2.3-beta.1"; // Valid prerelease
version: "1.0"; // Invalid: missing patch version
Configuración de TypeScript
El siguiente tsconfig.json cubre un plugin nativo con código fuente de React y de 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"]
}
Ejecuta pnpm typecheck sobre los puntos de entrada de código fuente antes de empaquetar. El script build compila solo src/index.ts; el host compila el código fuente exportado de administración y de Astro cuando consume el paquete.
Inspeccionar el paquete
Prueba el contenido exacto del tarball antes de publicar. Los comandos siguientes suponen que un sitio desechable llamado my-emdash-site se encuentra junto al directorio del plugin.
-
Compila el paquete y comprueba los tipos.
pnpm typecheck pnpm build -
Crea el tarball de npm y revisa la lista de archivos que imprime npm.
npm packPara el paquete de ejemplo, npm crea
example-plugin-activity-0.1.0.tgz. -
Confirma que la salida contiene
dist/index.mjs,dist/index.d.mtsy todos los archivos de código fuente accesibles desde los módulos exportados./adminy./astro. -
Instala el tarball generado en el sitio de EmDash desechable.
cd ../my-emdash-site pnpm add ../plugin-activity/example-plugin-activity-0.1.0.tgz -
Importa y registra la factoría del descriptor en el
astro.config.mjsdel sitio desechable, siguiendo Crear y registrar el paquete. Después, compila el sitio host.pnpm buildAbre todas las superficies de administración del plugin y renderiza todos los bloques de Portable Text aportados. Registrar el plugin antes de compilar hace que Astro resuelva las exportaciones
./adminy./astrodel tarball; una prueba del paquete solo en el servidor no puede detectar un archivo de código fuente de navegador o.astroque falte.
Contenidos del README
Dale a un operador información suficiente para instalar y evaluar el paquete sin leer su código fuente. Incluye:
- una descripción de una frase y la versión de EmDash compatible
- el comando de instalación y el registro completo en
astro.config.mjs - el límite de confianza nativo y por qué el plugin necesita ejecución nativa
- cada capability declarada y cada host permitido, con la función que los usa
- los ajustes y sus valores por defecto
- los componentes de diseño necesarios, como
EmDashBodyEndpara un fragmento al final del body - los pasos de actualización para los cambios que requieren una acción del operador
No describas las declaraciones de capabilities como un límite de aislamiento. Controlan el acceso a las API de ctx, pero el código nativo todavía puede usar las importaciones, las variables de entorno y las llamadas de red directas disponibles para el proceso del host.
Publicar en npm
Publica después de que la prueba del tarball haya pasado:
npm publish --access public
La primera publicación pública de un paquete con ámbito necesita --access public. Usa el versionado semántico en las publicaciones posteriores. Trata los cambios en las opciones del constructor, los datos almacenados, los cambios necesarios en el host, las exportaciones del paquete o los requisitos de confianza del plugin como decisiones de compatibilidad. Si una actualización requiere una nueva capability o un nuevo host permitido, indícalo en las notas de la versión aunque las instalaciones nativas no tengan un aviso de consentimiento de capabilities.
Instalar desde npm
Un operador instala el paquete publicado en el sitio de EmDash:
pnpm add @example/plugin-activity
Después, importa y registra su factoría de descriptor en astro.config.mjs como se muestra en Crear y registrar el paquete. Instalar la dependencia por sí sola no activa el plugin; la instalación se completa al cambiar la configuración de Astro y desplegar el sitio.
Desarrollar contra un sitio host
Compila el plugin en modo watch:
pnpm dev
Instala el directorio local desde el sitio host:
pnpm add ../plugin-activity
Registra la factoría de descriptor del plugin en astro.config.mjs y luego inicia el servidor de desarrollo del host. Reinicia el servidor después de cambiar los metadatos del descriptor o las exportaciones del paquete. Si en tu configuración una dependencia de archivo del gestor de paquetes copia los archivos en lugar de enlazarlos, vuelve a instalarla después de recompilar; una dependencia de workspace o pnpm link mantiene conectado el paquete local durante el desarrollo.
Límite del registro
Los paquetes nativos no se pueden publicar en el registro de EmDash. Los plugins del registro usan el formato de paquete en sandbox, el flujo de publicación firmado y el flujo de consentimiento de instalación. Si el plugin ya no necesita código de administración de React, renderizadores de Astro, fragmentos de confianza ni otra dependencia en el mismo proceso, conviértelo al formato en sandbox antes de publicarlo a través del registro.