directus-extension-webp-convert
v0.1.0
Published
Simple Directus hook extension that converts uploaded images to WEBP on upload (admin UI / REST API / MCP).
Maintainers
Readme
directus-extension-webp-convert
アップロードされた画像を WEBP に変換するだけのシンプルな Directus フック拡張です。
管理画面のドラッグ&ドロップ・REST API・Directus MCP など、サーバ側のすべての
アップロード経路で自動的に動作します(FilesService.uploadOne の共通フック)。
- 目標: 画像を WEBP 化して容量を下げる(品質 + 最大辺だけのシンプル設計)
- 非目標: 「○○KB 以下を保証」のような目標サイズ制御(あえて持たない)
- Directus 11.x 対応。実機(11.16.0)でアップロード→WEBP変換を検証済み。
- ランタイム依存なし(変換は Directus 同梱 Sharp を
AssetsService経由で使用)。 ただし配布は extensions-sdk でのビルドが必須(11.16 はdist+ manifest のsourceを要求)。
動作
action('files.upload')が全アップロードで発火- 画像 (jpeg/png/tiff/gif) のみ対象。webp や svg 等は対象外
AssetsService.getAsset()でformat=webp, quality, width/height=最大辺, fit=inside変換- 変換後が原本より大きければ原本を残す(
WEBP_SKIP_IF_LARGER) FilesService.uploadOne(stream, meta, sameKey)で原本を WEBP に置換- 再アップロードで再発火するため
payload.optimizedで二重処理を防止 - 変換不能(後述の制限超過など)はエラーを握りつぶし、原本をそのまま残す
全アップロード経路をカバー(MCP含む)
| 経路 | 対応 |
|---|---|
| 管理画面ドラッグ&ドロップ | ✅ |
| REST POST /files / /files/import | ✅ |
| Directus MCP のファイルアップロード | ✅ |
| 外部アプリ(Next.js/GAS 等)からの API | ✅ |
環境変数(この拡張)
| 変数 | 既定 | 説明 |
|---|---|---|
| WEBP_QUALITY | 80 | WEBP 品質 (1-100) |
| WEBP_MAX_DIMENSION | 2000 | 出力の最大辺(px)。これを超える画像は縮小 |
| WEBP_SKIP_IF_LARGER | true | 変換後が原本より大きい場合は変換しない |
★ ホスト側 Directus の必須要件(重要・実機検証で判明)
変換は Directus のオンザフライ変換基盤(AssetsService)を使うため、ホストの設定に依存します。
storage_asset_transformをnoneにしない(既定allでOK)。noneだと変換が一切できません。ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION(既定 6000)以上の辺を持つ原本は変換されません。 Directus が "Illegal asset transformation" を投げるため、本拡張は原本を残してスキップします。 一眼など 6000px を超える写真を扱う場合は、ホスト env で大きめに設定してください(例:ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION=12000)。
ビルド
npm install
npm run build # dist/index.js を生成(extensions-sdk)インストール
A) Marketplace(管理画面)
本拡張は services(AssetsService/FilesService)を使う非サンドボックス拡張です。
- npm 公開(このディレクトリで。
prepublishOnlyでビルドされます):npm publish --access public - Directus 側 env に
MARKETPLACE_TRUST=allを追加(非サンドボックス拡張の導入許可) - 管理画面 Settings → Marketplace で
webp-convertを検索 → インストール - 上記の
WEBP_*env と、必要ならASSETS_TRANSFORM_IMAGE_MAX_DIMENSIONを追加して再起動
B) ボリューム/カスタムイメージ
npm run build で生成した dist/ を含めた状態で
/directus/extensions/directus-extension-webp-convert に配置(docker volume か、COPY するカスタムイメージ)。
manifest の path は dist/index.js を指すため、dist が無いとロードされません。
実機検証
BASE=https://<your-directus>
TOKEN=<admin-token>
# 6000px 以下の画像をアップロード(macOS なら sips で縮小可)
RESP=$(curl -s -X POST -H "Authorization: Bearer $TOKEN" -F "file=@/tmp/test.jpg" "$BASE/files")
ID=$(echo "$RESP" | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["id"])')
sleep 5
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/files/$ID" \
| python3 -c 'import sys,json;d=json.load(sys.stdin)["data"];print(d["type"], d["filesize"])'
# 期待: image/webp と縮小された filesizeローカル検証実績(Directus 11.16.0 / sqlite / 本拡張マウント): 3000×2000 JPEG(1.48MB) → image/webp 270KB / 2000×1333 に変換成功。
ライセンス
MIT
