플러그인 생성하기
본 문서에서는
plop명령어를 사용하여 플러그인을 생성하는 방법을 설명합니다.
# cwd: root
pnpm genCLI에서 plugin 제너레이터를 선택하면 아래 항목을 순서대로 입력합니다.
1) 기본 입력값
name: 플러그인 패키지 이름 (예:settings-store)parent: 생성 위치 (기본값:plugins)platform: 플랫폼 suffixnone(공통),web,tauri,desktop,mobilewindows,macos,linux,android,ios
생성 폴더명은 아래 규칙을 따릅니다.
- 플랫폼이 없는 경우:
{dashCase(name)} - 플랫폼이 있는 경우:
{dashCase(name)}.{platform}
예: name=drpc, platform=desktop -> plugins/drpc.desktop
2) 템플릿 기능(features)
UI 패키지 (react, chakra-ui, react-icons): React 기반 UI 작성에 필요한 의존성과 기본 템플릿을 추가합니다.플러그인 설정: 설정 스키마/스토어/설정 UI 등록 템플릿을 추가합니다.Tauri Core API: Tauri 환경에서 Core API를 사용할 수 있는 템플릿을 추가합니다.
플러그인 설정을 선택하면 내부적으로 UI 패키지도 자동 활성화됩니다.
3) 생성 후 자동 실행 작업
플러그인 파일 생성 후 아래 작업이 자동으로 실행됩니다.
pnpm install
pnpm prettier -w {parent}/{folderName}
cd apps/client && pnpm add --workspace @muvel-plugins/{folderName}- 루트 의존성 설치
- 생성된 플러그인 폴더 코드 포맷팅
apps/client에 생성 플러그인을 워크스페이스 의존성으로 자동 연결
플러그인 기본 구조
plugin.ts
import { definePlugin } from "@muvel/core"
import { pluginId } from "./constants"
const plugin = definePlugin(pluginId, {
// npm package name과 동일한 kebab-case 권장
name: "my-plugin",
// 빌드 시 주입되는 플러그인 버전
version: __VERSION__,
// 실행 순서/로딩 보장을 위해 의존 플러그인 ID를 명시
dependencies: [],
// 다른 플러그인 또는 메인 앱이 사용할 API를 노출할 때 사용
api: {},
setup: async (mgr, ctx) => {
// 초기화 로직
},
dispose: async () => {
// 정리(cleanup) 로직
},
})
export default plugindefinePlugin(pluginId, config)로 플러그인 객체를 정의합니다.name은 플러그인 식별용 문자열이며 템플릿 기본값처럼kebab-case를 권장합니다.version은__VERSION__를 사용해 패키지 버전과 동기화합니다.dependencies는 런타임 의존 플러그인 ID 목록입니다. 설정/슬롯/에디터 확장 등 다른 플러그인 API를 쓸 때 반드시 추가하세요.api는 이 플러그인이 외부에 제공할 기능을 공개하는 영역입니다.setup은 플러그인 로딩 시점 초기화,dispose는 언로드 시점 자원 해제를 담당합니다.
설정 플러그인 연동 예시
템플릿에서 enableSettings를 켜면 아래 흐름이 자동으로 들어갑니다.
import { settingsPluginId } from "@muvel-plugins/settings"
import { settingsStorePluginId } from "@muvel-plugins/settings-store"
import { settingsSchemaPluginId } from "@muvel-plugins/settings-schema"
setup: async (mgr, ctx) => {
const settingsApi = mgr.use(ctx, settingsPluginId)
const storesApi = mgr.use(ctx, settingsStorePluginId)
await storesApi.register(settings)
settingsApi.register((data) => {
// 설정 탭/아이템 등록
})
}mgr.use(ctx, pluginId)로 의존 플러그인의 API를 가져옵니다.settings-store에 스키마/기본값을 등록하고,settings에서 UI 항목을 주입합니다.- 이때
plugin.ts의dependencies에 설정 관련 플러그인 ID 3개를 반드시 함께 선언해야 합니다.
플랫폼 분기
pnpm gen에서 플랫폼 suffix를 선택하면 대부분의 생성 작업은 자동으로 처리됩니다. 아래 내용은 동작 원리를 이해하기 위한 참고용입니다.
- 플러그인 패키지는
@muvel-plugins/{id}또는@muvel-plugins/{id}.{platform}형태로 존재할 수 있습니다. - 클라이언트는 실행 환경에 따라 suffix 후보를 만들고, 존재하는 패키지 중 가장 구체적인 것을 우선 선택합니다.
- 후보가 없으면 공통 패키지(
@muvel-plugins/{id})로 fallback 됩니다.
클라이언트 로더 기준 후보 우선순위 (apps/client/vite.config.ts)
- 웹 환경:
web-> 공통 - Tauri 환경:
windows/darwin/linux실행 시:{os}->desktop->tauri-> 공통android/ios실행 시:{os}->mobile->tauri-> 공통
예를 들어 drpc 플러그인이 아래처럼 존재한다면:
@muvel-plugins/drpc@muvel-plugins/drpc.tauri@muvel-plugins/drpc.desktop
데스크탑 Tauri에서는 drpc.desktop이 우선 선택되고, 없으면 drpc.tauri, 그다음 공통 버전을 사용합니다.
실무 팁
- 특별한 플랫폼 코드가 필요 없으면 공통 플러그인 하나만 유지하는 것이 가장 단순합니다.
- 플랫폼별 API(Tauri 네이티브, 모바일/데스크탑 전용 기능)를 쓸 때만 suffix 패키지를 추가하세요.
- 분기 패키지를 추가한 경우에도 공통 패키지는 타입/공통 로직 공유용으로 유지하면 관리가 편합니다.
Last updated on