EmDash 外掛程式以兩種格式之一提供:sandboxed(沙箱)或 native(原生)。這個選擇影響外掛程式的安裝方式、執行時期的執行方式以及可用的功能。
預設選擇沙箱。 沙箱外掛程式可以發布到市集,並透過管理介面一鍵安裝。原生外掛程式需要程式碼變更、npm install 以及在每個想要使用它們的網站上重新部署。沙箱是終端使用者想要的。
只有在需要沙箱無法提供的功能時才選擇原生。
快速對比
| Sandboxed | Native | |
|---|---|---|
| 撰寫形式 | emdash-plugin.jsonc + src/plugin.ts | definePlugin() 描述符 |
| 安裝方法 | 從管理市集一鍵安裝 | npm install + 編輯 astro.config |
| 執行環境 | 由沙箱執行器提供的隔離執行時期 | 與 Astro 網站相同的處理程序 |
| 功能 | 由沙箱橋強制執行 | 由同一橋在處理程序內強制執行 |
| 資源限制 | 由執行器強制執行 — 通常是 CPU、子請求、牆上時間、記憶體 | 無 |
| 網路存取 | 僅 ctx.http,限制為 allowedHosts | 僅 ctx.http,限制為 allowedHosts |
直接 fetch() / process.env | 被執行器阻止 | 可能(外掛程式程式碼共享執行時期) |
| 發布 | 市集上的 .tar.gz 套件 | npm 套件 |
| 管理介面 | Block Kit(JSON 描述)路由 | React 元件,或 Block Kit |
| 設定介面 | Block Kit 頁面 + KV 讀取 | admin.settingsSchema(自動表單)或 Block Kit |
| Portable Text 渲染元件 | 不可用 | componentsEntry 提供 Astro 元件 |
| 頁面中繼資料貢獻 | page:metadata 鉤子 — meta/property 標籤、允許清單的 <link> rels、JSON-LD | page:metadata 鉤子(相同表面) |
| 頁面片段注入 | 不可用 — 僅透過 page:metadata 的 meta/JSON-LD | page:fragments 鉤子 — 內聯指令碼、外部指令碼、原始 HTML |
| 建構函式選項 | 無 — 在執行時期從 KV 讀取設定 | 描述符上的 options |
選擇原生會失去什麼
原生外掛程式看起來像是同一事物的更強大版本,確實如此 — 但成本很高:
- 沒有市集。 每個網站都必須安裝你的 npm 套件,編輯
astro.config.mjs,並重新部署。 - 沒有隔離。 外掛程式中的錯誤可能會使主機處理程序當機或耗盡其 CPU 預算。鉤子中未處理的拒絕可能會連同周圍的請求一起當機。
- 使用者的信任負擔。 原生外掛程式擁有與主機網站相同的存取權限。最終使用者無法僅透過功能宣告來稽核它們。
如果你的外掛程式可以在沙箱中完成其工作,它就應該這樣做。
何時選擇原生
選擇原生有三個原因,它們都是關於需要與主機網站進行建置時期整合的功能:
-
自訂 React 管理頁面或小工具。 沙箱外掛程式使用 Block Kit 描述其管理介面 — 這是一個 JSON 模式,管理員代表外掛程式渲染它。如果你需要完整的 React(自訂鉤子、第三方元件、複雜狀態),你需要原生。
-
用於在公共網站上渲染 Portable Text 區塊的 Astro 元件。 沙箱外掛程式可以宣告自訂區塊類型,但在公共網站上渲染它的 Astro 元件必須在建置時期從 npm 載入。只有原生外掛程式可以提供
componentsEntry。 -
將原始 HTML、指令碼或樣式表注入公共頁面。
page:fragments鉤子將第一方程式碼傳送到訪客的瀏覽器 — 在任何沙箱邊界之外。它僅限於原生外掛程式。沙箱外掛程式仍然可以透過page:metadata鉤子為公共頁面做出貢獻,它涵蓋了許多實際使用案例:meta標籤(name+content) — SEO 描述、robots 指令、Twitter 卡片property標籤 — OpenGraph 和其他基於屬性的 meta- 帶有安全鎖定的 rel 允許清單的
link標籤(canonical、alternate、author、license、nlweb、site.standard.document) —stylesheet、prefetch和類似的資源載入 rels 被故意禁止 - JSON-LD 圖
如果你的「頁面注入」需求是結構化資料或 SEO 中繼資料,保持沙箱並使用
page:metadata。如果你確實需要向訪客的瀏覽器傳送 JavaScript 或 HTML,那就是選擇原生的情況。
如果你不確定,選擇沙箱。你總是可以稍後遷移到原生 — 但反過來更難,因為原生專用功能沒有沙箱等效物。
沙箱執行器和平台支援
沙箱本身是可插拔的。EmDash 公開了一個 sandboxRunner 設定選項,執行器決定如何隔離外掛程式程式碼 — 外掛程式格式本身沒有任何 Cloudflare 特定的內容。
今天大多數網站使用的執行器是來自 @emdash-cms/cloudflare 的 sandbox(),它使用 Cloudflare Workers 的 Dynamic Worker Loader。Worker Loader 按外掛程式 ID 快取 V8 隔離,因此隔離冷啟動成本只支付一次;執行器在每次呼叫時建構一個新的 worker stub 和橋繫結,因為 stub 和繫結與呼叫請求的 I/O 內容繫結。其他平台的執行器(透過 workerd 的 Node.js,以及潛在的 Deno)正在開發中。
如果沒有設定執行器,或者如果設定的執行器報告在目前平台上不可用,則在啟動時跳過 sandboxed: [] 下列出的外掛程式,並記錄偵錯層級日誌。
如果你想讓沙箱外掛程式在沒有沙箱執行器的平台上執行,將它從 sandboxed: [] 移動到 plugins: [] 陣列 — 它將在處理程序內執行。功能宣告仍然得到遵守(相同的 PluginContext 工廠控制 ctx.content、ctx.http 和其他),但沒有隔離邊界,沒有資源限制,有錯誤或惡意的外掛程式可以直接呼叫 fetch()、讀取環境變數或阻塞事件迴圈。在沒有活動的沙箱執行器的情況下,出於信任目的將每個外掛程式視為原生外掛程式。