В настоящее время мне удалось внедрить logi c в моем Express бэкэнде для изменения размера и загрузки одного изображения в AWS S3. Сейчас я борюсь за реализацию логики c для изменения размера одного изображения до множества различных размеров, которые затем загружаются на S3.
Следующий код работает так, как должен:
exports.resizeListingPhoto = (req, res, next) => {
if (!req.file) return next();
let filename;
if (process.env.NODE_ENV === 'development') {
filename = `dev-data-local/listing-${Date.now()}.jpeg`;
} else if (process.env.NODE_ENV === 'production') {
filename = `dev-data-cloud/listing-${Date.now()}.jpeg`;
}
sharp(req.file.buffer)
.resize(800, 500)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toBuffer()
.then((data) => {
const s3FileParams = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: filename,
ContentType: 'image/jpeg',
ACL: 'public-read',
Body: data,
};
// Uploading files to the bucket
s3.upload(s3FileParams, function (err, data) {
if (err) {
throw err;
}
req.file.awsUrl = data.Location;
next();
});
})
.catch((err) => {
console.log(err);
});
};
В моем обработчике createListing у меня есть доступ к URL в req.file.awsUrl.
Текущая модифицированная версия промежуточного программного обеспечения не работает:
exports.resizeListingPhoto = catchAsync(async (req, res, next) => {
if (!req.file) return next();
const imageSizes = [
{
width: 800,
height: 600,
contentType: 'image/jpeg',
},
{
width: 700,
height: 525,
contentType: 'image/jpeg',
},
{
width: 600,
height: 450,
contentType: 'image/jpeg',
},
{
width: 500,
height: 375,
contentType: 'image/jpeg',
},
{
width: 400,
height: 300,
contentType: 'image/jpeg',
},
{
width: 300,
height: 225,
contentType: 'image/jpeg',
},
{
width: 200,
height: 150,
contentType: 'image/jpeg',
},
{
width: 100,
height: 75,
contentType: 'image/jpeg',
},
];
let filename;
req.file.aws = [];
await Promise.all(
imageSizes.map(async (item, index) => {
await sharp(req.file.buffer)
.resize(item.width, item.height)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toBuffer()
.then((data) => {
if (process.env.NODE_ENV === 'development') {
filename = `dev-data-local/listing-${Date.now()}-w${
item.width
}.jpeg`;
} else if (process.env.NODE_ENV === 'production') {
filename = `dev-data-cloud/listing-${Date.now()}-w${
item.width
}.jpeg`;
}
let s3FileParams = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: filename,
ContentType: 'image/jpeg',
ACL: 'public-read',
Body: data,
};
// Uploading files to the bucket
s3.upload(s3FileParams, (err, data) => {
if (err) {
throw err;
}
req.file.aws.push(data.Location);
console.log(req.file.aws);
});
})
.catch((err) => {
console.log(err);
});
})
);
console.log('req.file.aws', req.file.aws);
next();
});
В этом примере Все изображения разных размеров создаются и корректно загружаются в AWS S3. Внутри s3.upload URL сохраненного изображения хранится в переменной data.Location. Эту переменную я помещаю в массив req.file. aws. Когда я console.log req.file. aws (внутри s3.upload), я вижу, как массив правильно заполнен URL-адресами для каждой итерации. Но когда я console.log req.file. aws в обработчике createListing или вне функции s3.upload, массив становится пустым. Я немного застрял здесь. Надеюсь, кто-то может указать мне правильное направление.