选择插件格式

本页内容

EmDash 插件以两种格式之一交付:沙盒式原生。这个选择会影响插件的安装方式、运行时获得的强制执行以及可用的功能。

默认使用沙盒式。 沙盒式插件可以发布到市场并从管理界面一键安装。原生插件需要修改代码、执行 npm install 并在每个想要使用它们的站点上重新部署。沙盒式是最终用户想要的。

仅在需要沙盒无法提供的功能时才选择原生。

概览

沙盒式原生
描述符上的 format 字段"standard""native"
安装方法从管理市场一键安装npm install + 编辑 astro.config
运行环境由沙盒运行器提供的隔离运行时与您的 Astro 站点相同的进程
功能由沙盒桥接强制执行由相同桥接在进程内强制执行
资源限制由运行器强制执行 — 通常是 CPU、子请求、执行时间、内存
网络访问ctx.http,限制为 allowedHostsctx.http,限制为 allowedHosts
直接 fetch() / process.env被运行器阻止可能(插件代码共享运行时)
分发方式市场上的 .tar.gznpm 包
管理界面Block Kit(JSON 描述)路由React 组件或 Block Kit
设置界面Block Kit 页面 + KV 读取admin.settingsSchema(自动表单)或 Block Kit
Portable Text 渲染组件不可用componentsEntry 提供 Astro 组件
页面元数据贡献page:metadata 钩子 — meta/property 标签、白名单 <link> rels、JSON-LDpage:metadata 钩子(相同界面)
页面片段注入不可用 — 仅通过 page:metadata 注入 meta/JSON-LDpage:fragments 钩子 — 内联脚本、外部脚本、原始 HTML
构造函数选项无 — 在运行时从 KV 读取设置描述符上的 options

选择原生会失去什么

原生插件看起来像同一事物的更强大版本,确实如此 — 但代价很高:

  • 没有市场。 每个站点都必须安装您的 npm 包、编辑 astro.config.mjs 并重新部署。
  • 没有隔离。 插件中的错误可能会导致主机进程崩溃或耗尽其 CPU 预算。钩子中未处理的拒绝可能会连同周围的请求一起倒下。
  • 用户的信任负担。 原生插件具有与主机站点相同的访问权限。最终用户无法仅通过功能声明来审计它们。

如果您的插件可以在沙盒中完成工作,就应该这样做。

何时选择原生

选择原生有三个原因,它们都与需要与主机站点进行构建时集成的功能有关:

  1. 自定义 React 管理页面或小部件。 沙盒式插件使用 Block Kit 描述其管理界面 — 这是管理员代表插件渲染的 JSON 架构。如果您需要完整的 React(自定义钩子、第三方组件、复杂状态),则需要原生。

  2. 用于在公共站点上渲染 Portable Text 块的 Astro 组件。 插件可以使用 format: "standard" 声明自定义块类型,但在公共站点上渲染它的 Astro 组件必须在构建时从 npm 加载。只有原生插件可以提供 componentsEntry

  3. 将原始 HTML、脚本或样式表注入公共页面。 page:fragments 钩子将第一方代码发送到访问者的浏览器 — 在任何沙盒边界之外。它仅限于原生插件。沙盒式插件仍然可以通过 page:metadata 钩子为公共页面做出贡献,它涵盖了许多实际用例:

    • meta 标签(name + content)— SEO 描述、robots 指令、Twitter Cards
    • property 标签 — OpenGraph 和其他基于属性的元数据
    • 具有安全锁定 rel 白名单的 link 标签(canonicalalternateauthorlicensenlwebsite.standard.document)— stylesheetprefetch 和类似的资源加载 rels 被故意不允许
    • JSON-LD 图

    如果您的”页面注入”需求是结构化数据或 SEO 元数据,请保持沙盒式并使用 page:metadata。如果您确实需要将 JavaScript 或 HTML 发送到访问者的浏览器,那就是选择原生的情况。

如果您不确定,请选择沙盒式。您始终可以稍后迁移到原生 — 但相反则更困难,因为原生专有功能没有沙盒等效物。

沙盒运行器和平台支持

沙盒本身是可插拔的。EmDash 公开了一个 sandboxRunner 配置选项,运行器决定如何隔离插件代码 — 插件格式本身没有任何 Cloudflare 特定的内容。

今天大多数站点使用的运行器是来自 @emdash-cms/cloudflaresandbox(),它使用 Cloudflare Workers 的 Dynamic Worker Loader。Worker Loader 按插件 ID 缓存 V8 隔离,因此隔离冷启动成本只需支付一次;运行器在每次调用时构造一个新的 worker 存根和桥接绑定,因为存根和绑定与调用请求的 I/O 上下文绑定。其他平台(通过 workerd 的 Node.js 以及可能的 Deno)的运行器正在开发中。

如果未配置运行器,或者如果配置的运行器报告在当前平台上不可用,则在启动时跳过 sandboxed: [] 下列出的插件,并记录调试级别日志。

如果您希望标准格式插件在没有沙盒运行器的平台上运行,请将其从 sandboxed: [] 移动到 plugins: [] 数组 — 它将在进程中执行。功能声明仍然受到尊重(相同的 PluginContext 工厂限制 ctx.contentctx.http 等),但没有隔离边界,没有资源限制,有错误或恶意的插件可以直接调用 fetch()、读取环境变量或阻止事件循环。如果没有活动的沙盒运行器,出于信任目的,请将每个插件视为原生插件。

下一步