EmDash 플러그인은 sandboxed 또는 native의 두 가지 형식 중 하나로 제공됩니다. 이 선택은 플러그인이 설치되는 방식, 런타임에 받는 적용 범위, 사용 가능한 기능에 영향을 미칩니다.
기본값은 샌드박스입니다. 샌드박스 플러그인은 마켓플레이스에 게시할 수 있으며 관리 UI에서 클릭 한 번으로 설치할 수 있습니다. 네이티브 플러그인은 코드 변경, 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 패키지 |
| 관리 UI | Block Kit (JSON 기술) 라우트 | React 컴포넌트, 또는 Block Kit |
| 설정 UI | 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으로 관리 UI를 설명합니다 — 관리자가 플러그인을 대신하여 렌더링하는 JSON 스키마입니다. 전체 React(사용자 정의 훅, 타사 컴포넌트, 복잡한 상태)가 필요한 경우 네이티브가 필요합니다.
-
공개 사이트에서 Portable Text 블록을 렌더링하기 위한 Astro 컴포넌트. 샌드박스 플러그인은 사용자 정의 블록 유형을 선언할 수 있지만, 공개 사이트에서 렌더링하는 Astro 컴포넌트는 빌드 시 npm에서 로드해야 합니다. 네이티브 플러그인만
componentsEntry를 제공할 수 있습니다. -
공개 페이지에 원시 HTML, 스크립트 또는 스타일시트 주입.
page:fragments훅은 방문자의 브라우저에 퍼스트 파티 코드를 전송합니다 — 샌드박스 경계 밖에서. 네이티브 플러그인으로 제한됩니다. 샌드박스 플러그인은 여전히page:metadata훅을 통해 공개 페이지에 기여할 수 있으며, 이는 많은 실제 사용 사례를 다룹니다:meta태그 (name+content) — SEO 설명, 로봇 지시문, Twitter 카드property태그 — OpenGraph 및 기타 속성 기반 메타- 보안 잠금된 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 isolate를 캐시하므로 isolate 콜드 스타트 비용은 한 번만 지불됩니다. 러너는 각 호출마다 새로운 워커 스텁과 브리지 바인딩을 구성합니다. 스텁과 바인딩이 호출 요청의 I/O 컨텍스트에 연결되어 있기 때문입니다. 다른 플랫폼(workerd를 통한 Node.js, 잠재적으로 Deno)용 러너가 개발 중입니다.
러너가 구성되지 않았거나 구성된 러너가 현재 플랫폼에서 사용할 수 없다고 보고하는 경우 sandboxed: [] 아래에 나열된 플러그인은 디버그 수준 로그와 함께 시작 시 건너뜁니다.
샌드박스 러너가 없는 플랫폼에서 샌드박스 플러그인을 실행하려면 sandboxed: []에서 plugins: [] 배열로 이동하세요 — 프로세스 내에서 실행됩니다. 기능 선언은 여전히 존중됩니다(동일한 PluginContext 팩토리가 ctx.content, ctx.http 및 친구들을 제어합니다). 하지만 격리 경계가 없고 리소스 제한이 없으며, 버그가 있거나 악의적인 플러그인은 fetch()를 직접 호출하고, 환경 변수를 읽고, 이벤트 루프를 차단할 수 있습니다. 활성 샌드박스 러너가 없으면 신뢰 목적으로 모든 플러그인을 네이티브 플러그인으로 취급하세요.