I am building a website that can identify a seiko-watch based on an image, using tfjs-node on the backend. I built a custom node package for it to use, which works great tfjs-image-node. The frontend takes an image and sends it to the backend as data64, the backend then uploads the image to cloudinary and takes that url and uses tfjs-image-node to get the prediction.
Everything works great in production, and even when it is built, and I preview it - but as soon as I deploy the app on vercel, I get an Error: Cannot find module 'jimp'. Jimp is used in the tfjs-image-node package, and is set as a dependency, not a devDependency.
Code
Seiko Identifier api/identify
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const image = body.image;
if (image.length === 0)
return NextResponse.json(
{ message: "ERR_MISSING_IMAGE" },
{ status: 400 }
);
const img = await cloudinary.uploader.upload(
image,
(error: any, result: any) => {
if (error) {
return NextResponse.json(error, { status: 500 });
}
return NextResponse.json(result);
}
);
const result: IResult[] | Error = await classifyImage(modelURL, img.url, "regular");
if (result instanceof Array) {
return NextResponse.json(result[0], { status: 200 });
} else {
return NextResponse.json({}, { status: 500 });
}
} catch (error) {
return NextResponse.json(error, { status: 500 });
}
}
TFJS-image-node
if (!MODEL_DIR_PATH || !IMAGE_FILE_PATH) {
return new Error("MISSING_PARAMETER");
}
let labels: string[];
if (!METADATA) {
const res = await fetch(`${MODEL_DIR_PATH}/metadata.json`);
if (res.status !== 200) {
return new Error("METADATA_NOT_FOUND" + res);
} else {
const json = await res.json();
labels = json["labels"];
}
} else {
labels = METADATA["labels"];
}
const model = await tf.loadLayersModel(`${MODEL_DIR_PATH}/model.json`);
const image = await Jimp.read(IMAGE_FILE_PATH);
image.cover(224, 224, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE);
const NUM_OF_CHANNELS = 3;
let values = new Float32Array(224 * 224 * NUM_OF_CHANNELS);
let i = 0;
image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x: number, y: number) => {
const pixel = Jimp.intToRGBA(image.getPixelColor(x, y));
pixel.r = pixel.r / 127.0 - 1;
pixel.g = pixel.g / 127.0 - 1;
pixel.b = pixel.b / 127.0 - 1;
pixel.a = pixel.a / 127.0 - 1;
values[i * NUM_OF_CHANNELS + 0] = pixel.r;
values[i * NUM_OF_CHANNELS + 1] = pixel.g;
values[i * NUM_OF_CHANNELS + 2] = pixel.b;
i++;
});
const outShape = [224, 224, NUM_OF_CHANNELS];
let img_tensor = tf.tensor3d(values, outShape, "float32");
img_tensor = img_tensor.expandDims(0);
const predictions = await model.predict(img_tensor).dataSync();
let result: ResultType[] = [];
for (let i = 0; i < predictions.length; i++) {
const label = labels[i];
const probability = predictions[i];
result.push({ label: label, probability: probability });
}
return result.sort((a, b) => Number(b.probability) - Number(a.probability));
Expected
Actual
Error: Cannot find module 'jimp'
Require stack:
- /var/task/.next/server/app/api/identify/route.js
- /var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js
- /var/task/___next_launcher.cjs
at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
at /var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:11:25599
at Module._load (node:internal/modules/cjs/loader:901:27)
at r.<computed>.e._load (/var/task/___vc/__launcher/__launcher.js:14:2516)
at Module.require (node:internal/modules/cjs/loader:1115:19)
at w.require (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:11:25815)
at require (node:internal/modules/helpers:130:18)
at 92622 (/var/task/.next/server/app/api/identify/route.js:1:3312)
at t (/var/task/.next/server/webpack-runtime.js:1:143)
at r (/var/task/.next/server/app/api/identify/route.js:38:271137) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/var/task/.next/server/app/api/identify/route.js',
'/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js',
'/var/task/___next_launcher.cjs'
],
page: '/api/identify'
}
What I've tried
I have tried installing jimp as a dependency to the main project - didn't work. I have tried updating, uninstalling, reinstalling, and rebuilding the tfjs-image-node package - didn't work.
I am running out of ideas as to what could cause this issue.
All my code:
App:
https://github.com/kevinanielsen/seiko-identifier/
TFJS-Image-Node package:
https://github.com/kevinanielsen/tfjs-image-node/