选择插件格式

本页内容

EmDash 插件使用两种格式之一:sandboxed(沙箱)或 native(原生)。请在编写插件之前选择格式,因为编写形态、安装路径与信任边界不同。

除非插件需要仅原生可用的集成,否则请选择沙箱插件。沙箱插件可发布到注册表并从管理 UI 安装。原生插件是站点运营者在项目中安装、并在重新部署前加入 astro.config.mjs 的 npm 包。

一览

SandboxedNative
Authoring shapeemdash-plugin.jsonc + src/plugin.tsdefinePlugin() descriptor
Install methodOne-click from the admin registrynpm install + edit astro.config
Runs inAn isolated runtime provided by a sandbox runnerSame process as your Astro site
Capability-gated ctx APIsEnforced by the sandbox bridgeGated by PluginContext, but not a security boundary
Resource limitsRunner limits for CPU, subrequests, and wall time; platform memory ceilingNo per-plugin limits
Network accessctx.http, restricted to declared accessctx.http follows declarations; native code can also call fetch()
Direct fetch() / process.envBlocked by the runnerPossible (plugin code shares the runtime)
DistributionSigned release in the plugin registrynpm package
Admin UIBlock Kit (JSON-described) routesReact components, or Block Kit
Settings UIBlock Kit page + ctx.settingsadmin.settingsSchema (auto-form) or Block Kit
Portable Text rendering componentsNot availablecomponentsEntry provides Astro components
Page metadata contributionspage:metadata hook — meta/property tags, allowlisted <link> rels, JSON-LDpage:metadata hook (same surface)
Page fragment injectionNot available — meta/JSON-LD only via page:metadatapage:fragments hook — inline scripts, external scripts, raw HTML
Constructor optionsNone — read settings from KV at runtimeoptions on the descriptor

原生插件的代价

原生插件有不同的安装与信任模型:

  • 项目级安装。 每个站点都必须安装你的 npm 包、编辑 astro.config.mjs 并重新部署。
  • 无隔离。 插件中的 bug 可能使宿主进程崩溃或耗尽其 CPU 预算。钩子中未处理的 rejection 可能拖垮周围的请求。
  • 用户侧的信任负担。 原生插件拥有与宿主站点相同的访问权限。仅靠能力声明无法展示其代码能做的一切。

如果插件能在沙箱中完成工作,就应该这样做。

何时选择原生

为需要与宿主站点进行构建时集成的功能选择原生:

  1. 自定义 React 管理页面或小组件。 沙箱插件用 Block Kit——管理端代表插件渲染的 JSON schema——描述其管理 UI。若你需要完整 React(自定义 hooks、第三方组件、复杂状态),就需要原生。

  2. 自定义 Portable Text 块类型。 其编辑配置与 Astro 渲染组件从已安装的 npm 包加载。只有原生插件能提供该构建时表面。

  3. 向公开页面注入原始 HTML、脚本或样式表。 page:fragments 钩子向访客浏览器投递第一方代码——在任何沙箱边界之外。它仅限原生插件。沙箱插件仍可通过 page:metadata 钩子向公开页面贡献,该钩子覆盖许多真实用例:

    • meta 标签(name + content)— SEO 描述、robots 指令、Twitter cards
    • property 标签 — OpenGraph 及其他基于 property 的 meta
    • 带安全锁定 rel 允许列表的 link 标签(canonical、alternate、author、license、nlweb、site.standard.document)— stylesheet、prefetch 及类似资源加载 rel 被有意禁止
    • JSON-LD 图

    若你的「页面注入」需求是结构化数据或 SEO 元数据,请留在沙箱并使用 page:metadata。若你确实需要向访客浏览器投递 JavaScript 或 HTML,那就是选择原生的情形。

若以上功能都不适用,请使用沙箱格式。

沙箱运行器与平台支持

沙箱本身是可插拔的。EmDash 暴露 sandboxRunner 配置选项,由运行器决定如何隔离插件代码——插件格式本身没有 Cloudflare 特有内容。

EmDash 附带两个运行器:来自 @emdash-cms/cloudflare 的 sandbox(),通过 Cloudflare 的 Worker Loader 将每个插件作为 Dynamic Worker 运行;以及 @emdash-cms/sandbox-workerd/sandbox,在 Node.js 上的 workerd 子进程中运行插件。Plugin Sandbox 涵盖每个运行器的设置、其强制的资源限制,以及两者的差异。

若未配置运行器,列在 sandboxed: [] 下的插件不会被加载。若配置的运行器在当前平台上不可用,它们也不会被加载,EmDash 会在启动时记录警告。

若希望沙箱插件在没有沙箱运行器的平台上运行,请将其从 sandboxed: [] 移到 plugins: [] 数组——它将在进程内执行。能力声明仍会被遵守(同一 PluginContext 工厂对 ctx.content、ctx.http 等设门),但没有隔离边界、没有资源限制,有缺陷或恶意的插件可直接调用 fetch()、读取环境变量或阻塞事件循环。在没有活动沙箱运行器时,出于信任目的,将每个插件视为原生插件。

下一步