選擇外掛格式

本頁內容

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()、讀取環境變數或阻塞事件迴圈。在沒有作用中沙箱執行器時,出於信任目的,將每個外掛視為原生外掛。

下一步