プラグイン作成の詳細
このページは、Riebeckite Plugin を実際に設計・実装するときの詳細ガイドです。
初めて Plugin を作る場合は、先に はじめてのプラグイン作成 を読んでください。
このページでは、その先に必要になる、
- どの拡張ポイントを使うか
- Plugin 同士の依存関係
- Lifecycle
- Content Pipeline
- Renderer / Page Type
- CSS / Browser 処理
- Cache / Diagnostics
- Package としての配布
までをまとめて扱います。
各型やフィールドの完全な定義を確認したい場合は Plugin API を参照してください。
このページの構成
1. Plugin にするべき機能
Plugin は Riebeckite に再利用可能な機能を追加する仕組みです。
たとえば、
- Markdown / HTML の解釈
- Content Transformation
- 独自形式の Renderer
- Browser Behavior
- Diagnostics
- HTTP Endpoint
- SEO
- 独立ページ
などを実装できます。
一方、すべての拡張を Plugin にするわけではありません。
Diagram source
flowchart TD
Q{"何を追加する?"}
Q -->|"Framework共通のContent Model"| Core["Core"]
Q -->|"再利用可能な機能"| Plugin["Plugin"]
Q -->|"HonoX / Viteとの接続"| Integration["Integration"]
Q -->|"Site固有Route / Layout"| App["Application"]
Q -->|"見た目だけ"| Theme["Theme"]
特に、
見た目だけ
→ Theme
Site 固有の Route / Layout
→ Application
HonoX / Vite との接続
→ Integration
Framework 全体の Content Model
→ Core
です。
「何でも Plugin にする」のではなく、その機能がどの責務に属するかを先に判断してください。
2. 最小の Plugin
Plugin は definePlugin() で定義します。
import { definePlugin } from "@riebeckite/core";
export function examplePlugin() {
return definePlugin({
name: "example",
});
}
Site では riebeckite.config.ts の plugins に追加します。
export default defineConfig({
plugins: [
examplePlugin(),
],
});
これが最小構成です。
3. Options を追加する
Plugin に設定が必要なら Factory の引数として受け取ります。
type ExampleOptions = {
enabled?: boolean;
};
export function examplePlugin(
options: ExampleOptions = {},
) {
return definePlugin({
name: "example",
options,
});
}
利用側では、
export default defineConfig({
plugins: [
examplePlugin({
enabled: true,
}),
],
});
のように指定できます。
条件付き Plugin も利用できます。
plugins: [
condition && myPlugin(),
]
false、null、undefined は Plugin Input の解決時に除外されます。
また、
enabled: false
の Plugin も実行されません。
4. 拡張ポイントを選ぶ
Plugin を実装するときは、必要な最小の拡張ポイントを選びます。
Diagram source
flowchart TD
Q{"何を実装する?"}
Q -->|"Markdown / HTML変換"| Pipeline["remark / rehype"]
Q -->|"Content処理の特定段階"| Hook["Content Hooks"]
Q -->|"記事内の特殊表示"| Renderer["renderers"]
Q -->|"独立ページ"| Page["pageTypes"]
Q -->|"Graph拡張"| Graph["extendContentGraph"]
Q -->|"URL規則"| Location["resolveContentLocations"]
Q -->|"CSS"| Asset["assets"]
Q -->|"Browser処理"| Client["clientEntries"]
Q -->|"HTTP"| Endpoint["endpoints"]
Q -->|"SEO"| SEO["seo"]
Q -->|"診断"| Diagnostics["addDiagnostics"]
現在の主な Contract は次のとおりです。
| 領域 | API |
|---|---|
| Identity | name, enabled, order, options |
| Dependency | provides, requires, optional |
| Validation | validateOptions |
| Cache | cacheVersion, context.cache |
| Lifecycle | setup, buildStart, buildEnd, dispose |
| Content Hooks | onConfigResolved, onContentLoaded, onPostParsed, onPostProcessed, onManifestCreated |
| Public Location | resolveContentLocations |
| Pipeline | remarkPlugins, rehypePlugins, extendMarkdownPipeline, extendHtmlPipeline |
| Graph | extendContentGraph |
| Diagnostics | addDiagnostics |
| 本文内の描画 | renderers |
| 独立ページ | pageTypes |
| Browser | assets, clientEntries |
| HTTP | endpoints |
| SEO | seo |
すべてを実装する必要はありません。
UI や output の拡張ポイントは複数あり、優劣の順列ではなく選択肢です。Markdown / HTML 変換、renderer、Page Type、body Slot、公開する Hono JSX component、client entry があります。どれを選ぶかは UI の提供方法 を参照してください。
27. 実装前の確認
Plugin を作り始める前に、最後に次の順番で考えると責務を分離しやすくなります。
Diagram source
flowchart TD
Start["追加したい機能"]
Plugin{"再利用可能な機能?"}
Start --> Plugin
Plugin -->|No| Other{"何を変える?"}
Plugin -->|Yes| Point{"最小のExtension Pointは?"}
Other -->|"見た目"| Theme["Theme"]
Other -->|"Site固有"| App["Application"]
Other -->|"Framework共通Model"| Core["Core"]
Other -->|"HonoX / Vite接続"| Integration["Integration"]
Point --> Implement["Pluginとして実装"]
Plugin にすると決めた後も、
その機能に本当に必要な Extension Point だけを使用する
ことが重要です。
Filesystem を再走査する前に Manifest や Content Graph が使えないか、独自 Route を追加する前に Page Type が使えないか、Client JavaScript を追加する前に SSR / Build-time だけで完結できないかを確認してください。
これによって Plugin を小さく保ち、Core、Integration、Application との不要な結合を避けられます。
関連資料
- はじめてのプラグイン作成 — 最初の Plugin を作る
- Plugin System — Plugin System 全体の考え方
- Plugin API — API Contract
- Page System — 独立ページ
- Content System — Manifest / Graph / Pipeline
- Architecture — Core / Plugin / Integration / Theme / App の責務
- Framework Reference — Public API