업로드 이미지 WebP 최적화 1차 적용

This commit is contained in:
2026-03-31 17:33:52 +09:00
parent ebe7a4408f
commit d760c7331a
7 changed files with 694 additions and 66 deletions

View File

@@ -0,0 +1,76 @@
const fs = require('fs/promises')
const path = require('path')
const sharp = require('sharp')
const { nanoid } = require('nanoid')
const UPLOAD_ROOT = path.join(__dirname, '..', '..', 'uploads')
function ensureImageMimeType(file) {
return typeof file?.mimetype === 'string' && file.mimetype.startsWith('image/')
}
function createMemoryUpload(multer, { fileSize = 6 * 1024 * 1024, maxCount } = {}) {
return multer({
storage: multer.memoryStorage(),
limits: {
fileSize,
...(typeof maxCount === 'number' ? { files: maxCount } : {}),
},
fileFilter: (req, file, cb) => {
if (ensureImageMimeType(file)) return cb(null, true)
cb(new Error('image_file_required'))
},
})
}
async function writeOptimizedImage({
file,
directory,
width,
height,
fit = 'inside',
quality = 82,
}) {
if (!file?.buffer?.length) {
const error = new Error('file_required')
error.code = 'file_required'
throw error
}
if (!ensureImageMimeType(file)) {
const error = new Error('image_file_required')
error.code = 'image_file_required'
throw error
}
const { data, info } = await sharp(file.buffer, { failOn: 'none' })
.rotate()
.resize({
width,
height,
fit,
withoutEnlargement: true,
})
.webp({ quality })
.toBuffer({ resolveWithObject: true })
const filename = String(Date.now()) + '-' + nanoid() + '.webp'
const absoluteDir = path.join(UPLOAD_ROOT, directory)
const absolutePath = path.join(absoluteDir, filename)
await fs.mkdir(absoluteDir, { recursive: true })
await fs.writeFile(absolutePath, data)
return {
src: '/uploads/' + directory + '/' + filename,
size: data.length,
originalSize: file.size || file.buffer.length,
width: info.width || 0,
height: info.height || 0,
}
}
module.exports = {
createMemoryUpload,
ensureImageMimeType,
writeOptimizedImage,
}