例えばサーバーレスな環境で、非同期的に画像のメタデータを取得してごにょごにょしたいこと、ありませんか?わたしはあります。 今回は、Cloudflare Workers を使って、画像のメタデータを取得してみようと思います。
まず最初に思いつくのが、Node.js 用画像処理パッケージである sharp を使うことだと思いますが、sharp は Cloudflare Workers では以下のようにエラーが出てデプロイできません:
$ wrangler deploy > @natsuneko-laboratory/xxx@ deploy D:\ghq\github.com\mika-f\teyvat\packages\xxx > wrangler deploy --minify --config ./wrangler.jsonc ⛅️ wrangler 4.5.0 (update available 4.24.0) ------------------------------------------------------ Total Upload: 2669.57 KiB / gzip: 989.25 KiB X [ERROR] A request to the Cloudflare API (/accounts/xxx/workers/scripts/xxx/versions) failed. Uncaught Error: [unenv] process.report.getReport is not implemented yet! at createNotImplementedError (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/unenv@2.0.0-rc.15/node_modules/unenv/dist/runtime/_internal/utils.mjs:25:9) in createNotImplementedError at null.<anonymous> (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/unenv@2.0.0-rc.15/node_modules/unenv/dist/runtime/_internal/utils.mjs:30:9) in fn at getReport (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/detect-libc@2.0.3/node_modules/detect-libc/lib/process.js:15:31) in getReport at familyFromReport (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/detect-libc@2.0.3/node_modules/detect-libc/lib/detect-libc.js:62:18) in familyFromReport at familySync (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/detect-libc@2.0.3/node_modules/detect-libc/lib/detect-libc.js:147:16) in familySync at null.<anonymous> (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/detect-libc@2.0.3/node_modules/detect-libc/lib/detect-libc.js:167:48) in isNonGlibcLinuxSync at runtimeLibc (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/sharp@0.34.1/node_modules/sharp/lib/libvips.js:40:38) in runtimeLibc at runtimePlatformArch (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/sharp@0.34.1/node_modules/sharp/lib/libvips.js:42:57) in runtimePlatformArch at null.<anonymous> (file:///D:/ghq/github.com/mika-f/teyvat/node_modules/.pnpm/sharp@0.34.1/node_modules/sharp/lib/sharp.js:11:25) at null.<anonymous> (index.js:1:542) [code: 10021] If you think this is a bug, please open an issue at: https://github.com/cloudflare/workers-sdk/issues/new/choose ELIFECYCLE Command failed with exit code 1.
これは、sharp が使っている Node.js の API がエッジランタイムに対応していないことが原因です。 今回、画像の処理というよりは、メタデータさえ取得できれば良いので、より軽量なパッケージを使うことで解決します。 そして、いろいろ試してみて快適に動いたのが、exifr というパッケージでした。
例えば、以下のようにすることで EXIF や XMP を簡単に取得することができます:
import exifr from "exifr"; // ... const buffer = Buffer.from(await fetch("https://example.com/some/image.png").then(w => w.arrayBuffer())); const metadata = await exifr.parse(buffer, { xmp: true }); console.log(metadata); /* * Location: ボドゲ喫茶かっこう 毎週火曜日21:00~0:00" * LocationAccessLevel: Anyone * ... **/
簡単ですね。Buffer さえ渡せば、かなり高速にパースしてくれます。 あとはこれをごにょごにょするだけでやりたいことができます。めでたしめでたし。 ということで、Cloudflare Workers でも画像のメタデータを取得したい場合の解決策でした。