ネイティブプラグインの配布

このページ

ネイティブプラグインは、ホストプロジェクトにインストールされ、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、および管理画面専用の peer 依存関係を削除してください。Portable Text レンダラーがない場合は、./astro、src/astro、および astro の peer を削除してください。エクスポートするソースエントリポイントがインポートする、ホストが所有するライブラリごとに peer 依存関係を追加してください。これにより、管理画面のバンドルに 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 のいずれかを受け付けます。この ID は /_emdash/api/plugins/<plugin-id>/<route> の 1 つのパスセグメントにもなるため、サイト用プラグインにはスコープなしの kebab-case の ID を使用してください。

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

id: "plugin-activity"; // Recommended: valid in plugin route URLs
id: "@example/plugin-activity"; // Accepted by definePlugin(), but not one URL segment

entrypoint: "@example/plugin-activity"; // The npm package may stay scoped

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

version: "1.0.0"; // Valid
version: "1.2.3-beta.1"; // Valid prerelease
version: "1.0"; // Invalid: missing patch version

TypeScript 構成

次の tsconfig.json は、React と Astro のソースを含むネイティブプラグインに対応しています。

{
	"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 だけです。エクスポートされた管理画面と 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 の内容

運用担当者が、ソースを読まなくてもパッケージをインストールして評価できるだけの情報を提供してください。次の内容を含めます。

  • 1 文での説明と、サポートする EmDash のバージョン
  • インストールコマンドと、astro.config.mjs への完全な登録方法
  • ネイティブの信頼境界と、プラグインがネイティブ実行を必要とする理由
  • 宣言したすべての capability と許可するホスト、およびそれを使う機能
  • 設定とそのデフォルト値
  • body-end フラグメント用の EmDashBodyEnd など、必要なレイアウトコンポーネント
  • 運用担当者の対応が必要な変更に関するアップグレード手順

capability の宣言を分離境界として説明しないでください。capability の宣言は ctx API を制限するだけで、ネイティブコードは、ホストプロセスで利用できるインポート、環境変数、直接のネットワーク呼び出しを引き続き使用できます。

npm に公開する

tarball のテストに合格したら、公開します。

npm publish --access public

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

npm からインストールする

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

pnpm add @example/plugin-activity

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

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

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

pnpm dev

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

pnpm add ../plugin-activity

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

レジストリの境界

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