Open1

Vitest(without Vite)でバンドラのbinary importに対応する

P_nutsKP_nutsK

経緯

画像処理をするモジュールのスナップショットテストがしたくてVitestを導入した。
その際、依存している画像(フレームなど)をBinaryとして読み込めるようesbuildのBinaryをローダーに使用していた。

import frame from "./frame.png"
// example
const image = await loadImage(frame);

しかし、Vitestが依存しているViteは画像ファイルをファイルパスとして読み込むように作られていたため、バイナリを期待しているのにファイルパスが渡されると言ったことが起きた。

- Uint8Array
+ "/src/frame.png"

解決策

正規表現にマッチしたファイルをUint8Arrayとして読み込むViteプラグインを自作する。

binaryloader.ts
import { readFileSync } from "node:fs";

export function binaryLoader(matches: RegExp[]) {
	return {
		name: "binary-loader",
		transform(_, id) {
			if (matches.some(regex => regex.test(id))) {
				const data = readFileSync(id);
				const base64 = data.toString("base64");
				return `export default new Uint8Array(Buffer.from('${base64}',"base64"));`;
			} else {
				return null;
			}
		},
	}
}
vitest.config.ts
import { defineConfig } from "vitest/config";
import { binaryLoader } from "./binaryloader";

export default defineConfig({
	plugins: [binaryLoader([/^.*\.png$/])],
});