native 플러그인은 EmDash가 Astro 사이트와 같은 프로세스에 가져오는 npm 패키지입니다. 이 튜토리얼은 콘텐츠 저장을 기록하는 플러그인을 만들고, 사이트에 설치하며, astro.config.mjs에 등록합니다.
플러그인에 React 관리 컴포넌트, Astro 렌더링 컴포넌트, 신뢰할 수 있는 페이지 프래그먼트 같은 인프로세스 기능이 필요할 때 native 형식을 사용하세요. 훅, 라우트, 스토리지, Block Kit으로 기능을 커버할 수 있으면 sandboxed 플러그인부터 시작하세요. 플러그인 형식 선택이 형식을 비교합니다.
사전 요구 사항
pnpm을 쓰고 개발 서버를 실행할 수 있는 EmDash 사이트에서 시작하세요. 사이트는 이미 emdash에 의존해야 하며, 그것이 아래에서 쓰는 emdash 명령을 제공합니다.
명령은 사이트 디렉터리를 my-emdash-site라고 부르고 옆에 plugin-activity를 만듭니다. my-emdash-site를 사이트 디렉터리 이름으로 바꾸세요.
패키지 만들고 등록하기
-
사이트 옆에 native 패키지를 스캐폴드합니다.
pnpm exec emdash plugin init --native --name @example/plugin-activity --dir ../plugin-activity명령은 플러그인 ID를 만들 때 npm 스코프를 제거합니다. 패키지 이름은
@example/plugin-activity이고, 플러그인 ID는plugin-activity입니다. -
패키지 의존성을 설치합니다.
cd ../plugin-activity pnpm install -
생성된
src/index.ts를 콘텐츠 저장 훅으로 바꿉니다.import { definePlugin } from "emdash"; import type { PluginDescriptor } from "emdash"; export interface ActivityPluginOptions { logUpdates?: boolean; } export function activityPlugin( options: ActivityPluginOptions = {}, ): PluginDescriptor<ActivityPluginOptions> { return { id: "plugin-activity", version: "0.1.0", format: "native", entrypoint: "@example/plugin-activity", options, }; } export function createPlugin(options: ActivityPluginOptions = {}) { return definePlugin({ id: "plugin-activity", version: "0.1.0", capabilities: ["content:read"], hooks: { "content:afterSave": async (event, ctx) => { if (!event.isNew && options.logUpdates === false) return; ctx.log.info("Content saved", { collection: event.collection, contentId: event.content.id, isNew: event.isNew, }); }, }, }); } export default createPlugin;content:afterSave에는content:read기능이 필요합니다. 그 기능이 없으면 EmDash는 훅을 건너뜁니다. -
패키지를 빌드합니다.
pnpm build -
로컬 패키지를 사이트에 설치합니다.
cd ../my-emdash-site pnpm add ../plugin-activity -
디스크립터 팩토리를 EmDash 통합에 등록합니다.
import { defineConfig } from "astro/config"; import emdash from "emdash/astro"; import { activityPlugin } from "@example/plugin-activity"; export default defineConfig({ integrations: [ emdash({ plugins: [activityPlugin({ logUpdates: true })], }), ], });native 디스크립터는
plugins에 두고sandboxed에는 두지 않습니다. EmDash는sandboxed배열의 native 디스크립터를 거부합니다. -
사이트를 시작하고 관리 패널에서 항목을 저장합니다.
pnpm dev서버 로그에 컬렉션, 콘텐츠 ID, 항목 생성 여부가 포함된
Content saved가 나옵니다.
디스크립터와 런타임 경계
패키지 내보내기에는 두 가지 역할이 있습니다. EmDash는 각각을 다른 단계에서 사용합니다.
- 디스크립터 팩토리
activityPlugin()은 Astro가 구성을 평가하는 동안 실행됩니다. 직렬화 가능한 빌드 타임 메타데이터id,version,format,entrypoint,options를 반환합니다. React와 Astro 엔트리포인트도 이 디스크립터에 속합니다. - 이름 있는
createPlugin()내보내기는 EmDash가 초기화될 때 실행됩니다. EmDash는 이를entrypoint에서 가져오고, 직렬화된options를 전달하며,definePlugin()의 해석된 플러그인을 기대합니다.
이름 있는 createPlugin 내보내기는 필수입니다. 기본 내보내기는 패키지 소비자에게 유용할 수 있지만, EmDash의 native 로더는 createPlugin을 이름으로 가져옵니다.
id와 version은 디스크립터와 definePlugin()에서 동일하게 유지하세요. plugin-activity 같은 스코프 없는 kebab-case 플러그인 ID를 쓰고, npm 스코프는 패키지 이름과 entrypoint에 남기세요. 그러면 ID를 API 라우트 URL의 단일 플러그인 세그먼트로 쓸 수 있습니다.
플러그인 신원과 버전에 허용되는 ID와 버전 형태가 있습니다.
런타임 동작은 definePlugin()에 둡니다.
capabilities와allowedHostsstoragehooks와routesadmin설정, 페이지, 위젯, Portable Text 선언
디스크립터는 Astro가 빌드 타임에 가져오거나 노출해야 하는 정적 항목을 담습니다. 초점 가이드는 어떤 관리 필드에 일치하는 디스크립터와 런타임 선언이 필요한지 보여줍니다.
native 라우트 핸들러
native 라우트 핸들러는 하나의 RouteContext를 받습니다. 검증된 입력과 요청 데이터를 일반 PluginContext와 결합합니다.
routes: {
status: {
permission: "plugins:read",
handler: async (ctx) => ({
pluginId: ctx.plugin.id,
callerId: ctx.user?.id ?? null,
}),
},
},
동등한 sandboxed 핸들러는 (routeCtx, ctx)를 두 인자로 받습니다. 인증, 권한, 입력 스키마, 라우트 URL은 그 외에는 공유 API 라우트 계약을 따릅니다.
request.body를 선언하는 native 라우트는 definePluginRoute()로 감싸세요. 헬퍼는 바디 모드에서
ctx.input을 추론합니다. response: "raw"인 native 라우트는 pluginResponse()를 반환합니다.
두 헬퍼 모두 emdash에서 가져오세요. 공유 API 라우트 가이드에 바디 모드, 한도, 응답 정책, 호환성 기본값이 있습니다.
다른 표면 추가하기
- React 관리 페이지와 위젯은 설정, 사용자 정의 페이지, 대시보드 위젯, 편집기 패널, 목록 열을 다룹니다.
- Portable Text 렌더링 컴포넌트는 플러그인 블록용 Astro 컴포넌트를 등록합니다.
- 페이지 프래그먼트는 공개 페이지에 신뢰할 수 있는 스크립트나 HTML을 추가합니다.
- native 플러그인 배포는 npm용 빌드와 소스 엔트리포인트를 패키징합니다.