native プラグインの配布

このページ

native プラグインは、ホストプロジェクトにインストールし astro.config.mjs に登録する npm パッケージです。パッケージにはディスクリプタと createPlugin() 用のビルド済みサーバーエントリが必要です。React や Astro コンポーネントも同梱する場合は、ホストが正しい環境向けにコンパイルできるよう、別のソースエントリポイントとしてエクスポートしてください。

パッケージレイアウト

次のレイアウトは、サーバーランタイムをブラウザと Astro のソースから分離します。

plugin-activity/
├── src/
│   ├── index.ts
│   ├── admin/
│   │   ├── index.tsx
│   │   └── ActivityPage.tsx
│   └── astro/
│       ├── index.ts
│       └── ActivityBlock.astro
├── dist/
│   ├── index.mjs
│   └── index.d.mts
├── package.json
├── tsconfig.json
└── README.md

dist/ は生成物です。ホストの Vite と Astro のビルドがこれらのエントリポイントを処理するため、公開 tarball に src/admin/ と src/astro/ を残してください。

パッケージのエクスポート

次の package.json はサーバーエントリをビルドし、3 つのエントリポイントすべてを公開します。

{
	"name": "@example/plugin-activity",
	"version": "0.1.0",
	"type": "module",
	"main": "./dist/index.mjs",
	"exports": {
		".": {
			"types": "./dist/index.d.mts",
			"import": "./dist/index.mjs"
		},
		"./admin": "./src/admin/index.tsx",
		"./astro": "./src/astro/index.ts"
	},
	"files": ["dist", "src/admin", "src/astro"],
	"scripts": {
		"build": "tsdown src/index.ts --format esm --dts --clean",
		"dev": "tsdown src/index.ts --format esm --dts --watch",
		"typecheck": "tsc --noEmit",
		"prepublishOnly": "pnpm typecheck && pnpm build"
	},
	"peerDependencies": {
		"@cloudflare/kumo": "*",
		"@emdash-cms/admin": "*",
		"@lingui/core": "*",
		"@lingui/react": "*",
		"@tanstack/react-query": "*",
		"astro": ">=6.0.0-beta.0",
		"emdash": "*",
		"react": "^18.0.0 || ^19.0.0"
	},
	"devDependencies": {
		"@types/react": "^19.0.0",
		"tsdown": "^0.20.0",
		"typescript": "^5.9.0"
	},
	"keywords": ["emdash", "emdash-plugin"],
	"license": "MIT"
}

信頼できる React UI がない場合は ./admin、src/admin、admin 専用の peerDependencies を削除してください。Portable Text レンダラーがない場合は ./astro、src/astro、astro peer を削除してください。エクスポートされたソースエントリポイントがインポートするホスト所有ライブラリごとに peerDependency を追加し、2 つ目の React、Kumo、Lingui、React Query インスタンスが管理バンドルに入らないようにします。

エントリポイントの消費者は異なります。

エクスポート必要なとき消費者
.常にAstro 設定がディスクリプタファクトリをインポート。EmDash がランタイムで名前付き createPlugin() をインポート。
./adminadminEntry が設定されているホストのブラウザビルドが React コンポーネントマップをインポート。
./astrocomponentsEntry が設定されているホストの Astro ビルドが blockComponents をインポート。

ディスクリプタとランタイムのモジュール指定子はこれらのエクスポートと一致させる必要があります。

export function activityPlugin(): PluginDescriptor {
	return {
		id: "plugin-activity",
		version: "0.1.0",
		format: "native",
		entrypoint: "@example/plugin-activity",
		adminEntry: "@example/plugin-activity/admin",
		componentsEntry: "@example/plugin-activity/astro",
	};
}

export function createPlugin() {
	return definePlugin({
		id: "plugin-activity",
		version: "0.1.0",
		admin: {
			entry: "@example/plugin-activity/admin",
		},
	});
}

npm パッケージバージョン、ディスクリプタバージョン、definePlugin() のバージョンを同期させてください。サイト管理者に表示されるバージョンは package.json から自動ではなく、プラグイン定義から来ます。

プラグインの識別とバージョン

definePlugin() は、小文字・数字・ハイフンを含むスコープなし ID、または @scope/name 形式のスコープ付き ID を受け付けます。サイトプラグインにはスコープなしの kebab-case ID を使ってください。ID は /_emdash/api/plugins/<plugin-id>/<route> の 1 パスセグメントにもなるためです。

次の値は受け入れられる形式と、プラグイン ID と npm パッケージ名の推奨分離を示します。

id: "plugin-activity"; // 推奨: プラグインルート URL で有効
id: "@example/plugin-activity"; // definePlugin() は受け付けるが、1 URL セグメントではない

entrypoint: "@example/plugin-activity"; // npm パッケージはスコープ付きのままでよい

バージョンはセマンティックな major.minor.patch シーケンスで始まる必要があります。ディスクリプタとランタイムの両方に完全なセマンティックバージョンを使ってください。

version: "1.0.0"; // 有効
version: "1.2.3-beta.1"; // 有効なプレリリース
version: "1.0"; // 無効: パッチバージョン欠落

TypeScript 構成

native スキャフォールドは適切な tsconfig.json を作成します。スキャフォールド後に React と Astro のソースを追加する場合は、両方の JSX 環境を含めてください。

{
	"compilerOptions": {
		"target": "ES2022",
		"module": "preserve",
		"moduleResolution": "bundler",
		"strict": true,
		"declaration": true,
		"outDir": "./dist",
		"rootDir": "./src",
		"jsx": "react-jsx",
		"types": ["astro/client"]
	},
	"include": ["src/**/*"],
	"exclude": ["node_modules", "dist"]
}

パッケージ化する前にソースエントリポイントに対して pnpm typecheck を実行してください。build スクリプトは src/index.ts だけをコンパイルし、ホストはパッケージを消費するときにエクスポートされた admin と Astro ソースをコンパイルします。

パッケージを検査する

公開前に正確な tarball 内容をテストしてください。以下のコマンドは、使い捨てサイト my-emdash-site がプラグインディレクトリの横にあることを前提とします。

  1. パッケージをビルドし型チェックします。

    pnpm typecheck
    pnpm build
  2. npm tarball を作成し、npm が出力するファイル一覧を確認します。

    npm pack

    例のパッケージでは npm が example-plugin-activity-0.1.0.tgz を作成します。

  3. 出力に dist/index.mjs、dist/index.d.mts、およびエクスポートされた ./admin と ./astro モジュールから到達可能なすべてのソースファイルが含まれることを確認します。

  4. 生成した tarball を使い捨て EmDash サイトにインストールします。

    cd ../my-emdash-site
    pnpm add ../plugin-activity/example-plugin-activity-0.1.0.tgz
  5. パッケージの作成と登録 に従い、使い捨てサイトの astro.config.mjs にディスクリプタファクトリをインポートして登録します。その後ホストサイトをビルドします。

    pnpm build

    すべてのプラグイン管理サーフェスを開き、貢献された Portable Text ブロックをすべてレンダリングしてください。ビルド前に登録すると Astro が tarball の ./admin と ./astro エクスポートを解決できます。サーバーのみのパッケージテストでは、不足しているブラウザまたは .astro ソースファイルを検出できません。

README の内容

運用者がソースを読まずにパッケージをインストール・評価できる十分な情報を与えてください。次を含めてください。

  • 一文の説明とサポートする EmDash バージョン
  • インストールコマンドと完全な astro.config.mjs 登録
  • native の信頼境界と、プラグインが native 実行を必要とする理由
  • 宣言されたすべてのケイパビリティと許可ホスト、それを使う機能
  • 設定とそのデフォルト
  • EmDashBodyEnd のような必要なレイアウトコンポーネント(body-end フラグメント用)
  • 運用者のアクションが必要な変更のアップグレード手順

ケイパビリティ宣言を分離境界として説明しないでください。ctx API をゲートしますが、native コードはホストプロセスが使えるインポート、環境変数、直接のネットワーク呼び出しを引き続き使えます。

npm に公開する

tarball テストが通った後に公開します。

npm publish --access public

スコープ付きパッケージの最初の公開リリースには --access public が必要です。以降のリリースにはセマンティックバージョニングを使ってください。コンストラクタオプション、保存データ、必要なホスト変更、パッケージエクスポート、プラグインの信頼要件の変更は互換性の判断として扱ってください。アップグレードに新しいケイパビリティや許可ホストが必要な場合、native インストールにケイパビリティ同意プロンプトがなくても、リリースノートで明示してください。

npm からインストールする

運用者は公開パッケージを EmDash サイトにインストールします。

pnpm add @example/plugin-activity

次に パッケージの作成と登録 のとおり、astro.config.mjs でディスクリプタファクトリをインポートして登録します。依存関係のインストールだけではプラグインは有効になりません。Astro 設定の変更とサイトのデプロイでインストールが完了します。

ホストサイトに対して開発する

ウォッチモードでプラグインをビルドします。

pnpm dev

ホストサイトからローカルディレクトリをインストールします。

pnpm add ../plugin-activity

astro.config.mjs にプラグインのディスクリプタファクトリを登録し、ホストの開発サーバーを起動します。ディスクリプタメタデータやパッケージエクスポートを変更したらサーバーを再起動してください。パッケージマネージャのファイル依存がリンクではなくコピーする場合は、再ビルド後に再インストールしてください。ワークスペース依存や pnpm link は開発中にローカルパッケージを接続したままにします。

レジストリの境界

native パッケージは EmDash レジストリに公開できません。レジストリプラグインは sandboxed パッケージ形式、署名付きリリースワークフロー、インストール同意フローを使います。プラグインが React 管理コード、Astro レンダラー、信頼できるフラグメント、その他のインプロセス依存を必要としなくなった場合は、レジストリ経由で公開する前に sandboxed 形式に変換 してください。