У меня есть служебная функция загрузки Cloudinary с использованием их SDK. Я работаю в NEXT JS 14 и действии сервера, но столкнулся с ошибкой
TypeError: Cannot read properties of undefined (reading 'node')
Когда я импортирую свою служебную функцию, я получаю ошибку, иначе нет. Вот мой импорт
import uploadToCloudinary from "@/service/uploadToCloudinary"; // works if I comment it out
import { constants } from "@/config";
import { supabase } from "@/lib";
import { isCategoryUnique, isLoggedIn } from "@/middlewares";
загрузитьToCloudinary.js
const cloudinary = require("cloudinary");
// Configure Cloudinary with your account details
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
// eslint-disable-next-line import/no-anonymous-default-export
export default async (file, folder) => {
try {
const { secure_url, public_id } = await cloudinary?.v2?.uploader?.upload(
file,
{
folder,
upload_preset: process.env.CLOUDINARY_PRESET,
}
);
return {
success: true,
data: { secure_url, public_id },
};
} catch (error) {
console.error("Error uploading file to Cloudinary:", error);
return {
success: false,
data: "Internal Server Error",
};
}
};
Вероятно, ошибка возникает из-за того, что облачная библиотека пытается получить доступ к среде Node.js, но Next.js 14 с действиями сервера работает в другой среде, называемой Edge Runtime.
Edge Runtime — это бессерверная среда, предоставляемая Vercel, в которой выполняются ваши действия сервера. Он спроектирован так, чтобы быть легким и эффективным, но у него нет доступа к некоторым API-интерфейсам Node.js и библиотекам, которые на них полагаются.
Чтобы решить эту проблему, вам нужно просто создать конечную точку с той же логикой или использовать версию облачной библиотеки, совместимую с Edge Runtime.
Решение 1 (конечная точка с той же логикой):
import uploadToCloudinary from "@/service/uploadToCloudinary";
export const config = {
api: {
bodyParser: {
sizeLimit: "10mb",
},
},
};
export default async function handler(req, res) {
if (req.method === "POST") {
try {
const file = req.body;
const folder = "your-folder-name"; // Set the desired folder name for uploaded files
const { success, data } = await uploadToCloudinary(file, folder);
if (success) {
res.status(200).json(data);
} else {
res.status(500).json({ error: data });
}
} catch (error) {
console.error("Error uploading file:", error);
res.status(500).json({ error: "Internal Server Error" });
}
} else {
res.status(405).json({ error: "Method Not Allowed" });
}
}
Решение 2 (Cloudinary библиотека, совместимая с Edge Runtime):
import { Cloudinary } from "@cloudinary/url-gen";
import { upload } from "@cloudinary/react";
// Configure Cloudinary with your account details
const cloudinary = new Cloudinary({
cloud: {
cloudName: process.env.CLOUDINARY_CLOUD_NAME,
},
url: {
secure: true,
},
});
// eslint-disable-next-line import/no-anonymous-default-export
export default async (file, folder) => {
try {
const uploadResult = await upload(file, {
folder,
upload_preset: process.env.CLOUDINARY_PRESET,
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
});
return {
success: true,
data: {
secure_url: uploadResult.secure_url,
public_id: uploadResult.public_id,
},
};
} catch (error) {
console.error("Error uploading file to Cloudinary:", error);
return {
success: false,
data: "Internal Server Error",
};
}
};
** Этот код достигает желаемого результата, но, вероятно, есть возможности для улучшения с точки зрения лучших практик и ясности кода. Поскольку я создал его с помощью ИИ, я все еще работаю над его оптимизацией*