🔧

plaiceholderライブラリ(getPlaiceholder関数)の仕様変更について

2023/08/12に公開2

背景

「作って学ぶ Next.js/React Webサイト構築」を進めていて、「9.1 アイキャッチ画像 eyecatchの代替画像とブラー画像を用意する」でライブラリ系のエラーが出たので、メモする。
https://ebisu.com/next-react-website/

エラーの内容

publicフォルダに配置した、画像が読み込めないとのエラー

この時はNext.jsでpublicが読み込めないエラーだと思っていた。

原因

それまでは画像を読み込めていたので、9.1で追加した

const { base64 } = await getPlaiceholder(eyecatch.url)
 eyecatch.blurDataURL = base64

ここでエラーが出ていたようだ。

getPlaiceholder()の第一引数の方がBuffer型になっている。引数にはフォルダのパス(string型)を渡していたので、これが原因のように見える。

npmからインストールしたplaiceholderのバージョンを確認すると、

// 書籍のサンプルコードでのバージョン
"plaiceholder": "^2.4.0",
"sharp": "^0.30.7"

// 私がインストールしたバージョン
"plaiceholder": "^3.0.0",
"sharp": "^0.32.4"

plaiceholderのメージャーバージョンが2.4.0から3.0.0になった時の仕様変更が怪しいと考える。

https://github.com/joe-bell/plaiceholder/releases/tag/v3.0.0

GitHubから3.0.0のリリースノートを確認した所、

  • File paths or external URLs are no longer supported – getPlaiceholder now expects a Buffer(see the migration guide for examples)

と記載があり、つまりはgetPlaiceholder()はファイルのパスや外部のURLをサポートしなくなった。代わりに、この関数はBufferを期待しているとのこと。

今まではsharpをインストール前提としてたけど、それだと依存関係が強くsharpが使えない環境だともれなく使えないから変更したらしい。

修正

Upgrading to 3.0 | Plaiceholder

公式で移行手順があったので、参考にする。

libフォルダ配下にgetImageBuffer.jsを作成

import path from "node:path";
import fs from "node:fs/promises";

export async function getImageBuffer(src) {
  // ローカルの画像の場合はパスにpublicを付与
  if (src.startsWith('http')) {
    const res = await fetch(src)
    return await Buffer.from(await res.arrayBuffer())
  } else {
    return await fs.readFile(path.join("./public", src));
  }
};

getPlaiceholder()を使用する箇所で画像をBuffer化してから使用するように変更

import { getImageBuffer } from 'lib/getImageBuffer'

const imageBuffer = await getImageBuffer(eyecatch.url)
const { base64 } = await getPlaiceholder(imageBuffer)
eyecatch.blurDataURL = base64

これで動くようなった。

まとめ

  • エラーが起きたら、まずは原因のスコープを小さくする
  • ライブラリが起因の場合はバージョンを確認
  • Githubからリリースノートを見る
  • 型がないと関数のエラーを発見しにくい

Discussion

貝時計 KaiTokei貝時計 KaiTokei

ちょうど同じ場所で詰まり、情報を探していたところでありました。
ありがとうございます!!
仕様変更には注意せねばですね。

かどっちかどっち

参考になったようで良かったです!
OSSを使用する場合はバージョンアップによる破壊的な変更も多いので、注意です⚠️