原生插件通过 npm 分发,而非应用市场。没有打包器、没有清单文件、也没有安全审计步骤 — 只是一个导出描述符工厂和 createPlugin 的常规 npm 包。站点运营者使用 npm install 安装它,并在 astro.config.mjs 中注册。
包结构
典型的原生插件包:
@my-org/plugin-analytics/
├── src/
│ ├── index.ts # Descriptor + createPlugin
│ ├── admin.tsx # React admin components (optional)
│ └── astro/ # Astro components for PT block rendering (optional)
│ └── index.ts
├── dist/ # build output
├── package.json
├── tsconfig.json
└── README.md
package.json
{
"name": "@my-org/plugin-analytics",
"version": "0.1.0",
"type": "module",
"main": "dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./admin": {
"types": "./dist/admin.d.ts",
"import": "./dist/admin.js"
},
"./astro": {
"types": "./dist/astro/index.d.ts",
"import": "./dist/astro/index.js"
}
},
"files": ["dist"],
"scripts": {
"build": "tsdown src/index.ts src/admin.tsx --format esm --dts --clean",
"prepublishOnly": "pnpm build"
},
"peerDependencies": {
"emdash": "*",
"react": "^18.0.0"
}
}
| 导出 | 需要的条件… | 构建目标 |
|---|---|---|
"." | 始终需要 | Server |
"./admin" | React 管理页面或小部件 | Browser |
"./astro" | Portable Text 渲染组件 | Server (SSR) |
如果你的插件不需要 ./admin 和 ./astro 导出,可以跳过它们。
构建配置
原生插件以 ES 模块形式发布。大多数作者使用 tsdown(或 tsup)配合 TypeScript。将 react、emdash 和 @emdash-cms/admin 外部化,使它们不会被打包到输出中:
export default {
entry: {
index: "src/index.ts",
admin: "src/admin.tsx",
},
format: "esm",
dts: true,
external: ["react", "react-dom", "emdash", "@emdash-cms/admin"],
};
如果你发布用于 Portable Text 渲染的 Astro 组件,这些组件不需要打包 — Astro 直接使用 .astro 源文件。在 files 下列出 astro/ 目录,以便它们被包含在 npm 压缩包中。
版本管理
使用语义化版本。升级主版本号是向运营者发出的信号,表示他们在升级时可能需要进行更改。definePlugin() 的形状和插件上下文 API 是稳定的,但如果你更改插件的钩子行为、能力要求或设置模式,且会影响现有安装,那就是一个破坏性变更。
能力是插件表面契约的一部分。在非主版本发布中添加能力意味着现有运营者升级时会静默授予新能力 — 这对于沙盒插件来说没问题,因为同意对话框会重新提示,但原生插件没有同意流程。将能力添加视为原生插件的主版本升级,或在发布说明中非常明显地记录它们。
README 和文档
一个好的插件 README 应包含:
- 插件的功能,用一句话说明。
- 如何安装(
npm install ...以及带有 import 的astro.config.mjs代码片段)。 - 它声明了哪些能力以及用于什么目的。
- 任何必需的 Astro 模板更改(例如用于
page:metadata的<EmDashHead />,用于page:fragments的<EmDashBodyEnd />)。 - 设置及每个设置控制的内容。
- 主版本之间的迁移说明。
发布到 npm
npm version patch # or minor/major
npm publish --access public
对于作用域包,首次发布时需要 --access public(npm 默认将作用域包设为私有)。
针对宿主站点的本地开发
在迭代插件时,将其链接到测试站点,而不是每次更改都重新发布:
# In the plugin package
pnpm build --watch
# In the test site
pnpm add file:../plugins/my-plugin
# or with workspaces:
pnpm add @my-org/plugin-analytics --workspace
然后在测试站点的 astro.config.mjs 中注册插件并运行开发服务器。钩子处理程序会在 pnpm build 完成后的下一次请求时运行。
应用市场?不行。
原生插件无法发布到 EmDash 应用市场。应用市场仅支持沙盒插件:每个发布的插件都会经过 emdash plugin bundle(验证后端代码是自包含的、不导入 Node.js 内置模块、且保持在大小限制内)、进行安全审计,并在安装时在沙盒运行时中运行。
如果你想要应用市场的分发渠道,但你的插件目前使用仅限原生的特性,请考虑是否真的需要它们 — 许多插件可以放弃 page:fragments 或从 settingsSchema 转换为 Block Kit 设置页面,从而变为可沙盒化。请参阅选择插件格式了解权衡。