2021-06-04 10:06:00 +02:00
|
|
|
import loaderUtils from 'next/dist/compiled/loader-utils'
|
|
|
|
import sizeOf from 'image-size'
|
|
|
|
import { processBuffer } from '../../../next-server/server/lib/squoosh/main'
|
|
|
|
|
2021-06-10 20:51:35 +02:00
|
|
|
const BLUR_IMG_SIZE = 8
|
|
|
|
const BLUR_QUALITY = 70
|
|
|
|
const VALID_BLUR_EXT = ['jpeg', 'png', 'webp']
|
2021-06-04 10:06:00 +02:00
|
|
|
|
|
|
|
async function nextImageLoader(content) {
|
|
|
|
const context = this.rootContext
|
|
|
|
const opts = { context, content }
|
|
|
|
const interpolatedName = loaderUtils.interpolateName(
|
|
|
|
this,
|
|
|
|
'/static/image/[path][name].[hash].[ext]',
|
|
|
|
opts
|
|
|
|
)
|
|
|
|
|
|
|
|
let extension = loaderUtils.interpolateName(this, '[ext]', opts)
|
|
|
|
if (extension === 'jpg') {
|
|
|
|
extension = 'jpeg'
|
|
|
|
}
|
|
|
|
|
|
|
|
const imageSize = sizeOf(content)
|
2021-06-10 20:51:35 +02:00
|
|
|
let blurDataURL
|
|
|
|
if (VALID_BLUR_EXT.includes(extension)) {
|
|
|
|
// Shrink the image's largest dimension
|
2021-06-04 10:06:00 +02:00
|
|
|
const resizeOperationOpts =
|
|
|
|
imageSize.width >= imageSize.height
|
2021-06-10 20:51:35 +02:00
|
|
|
? { type: 'resize', width: BLUR_IMG_SIZE }
|
|
|
|
: { type: 'resize', height: BLUR_IMG_SIZE }
|
2021-06-04 10:06:00 +02:00
|
|
|
const resizedImage = await processBuffer(
|
|
|
|
content,
|
|
|
|
[resizeOperationOpts],
|
|
|
|
extension,
|
2021-06-10 20:51:35 +02:00
|
|
|
BLUR_QUALITY
|
2021-06-04 10:06:00 +02:00
|
|
|
)
|
2021-06-10 20:51:35 +02:00
|
|
|
blurDataURL = `data:image/${extension};base64,${resizedImage.toString(
|
2021-06-04 10:06:00 +02:00
|
|
|
'base64'
|
|
|
|
)}`
|
|
|
|
}
|
|
|
|
|
|
|
|
const stringifiedData = JSON.stringify({
|
|
|
|
src: '/_next' + interpolatedName,
|
|
|
|
height: imageSize.height,
|
|
|
|
width: imageSize.width,
|
2021-06-10 20:51:35 +02:00
|
|
|
blurDataURL,
|
2021-06-04 10:06:00 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
this.emitFile(interpolatedName, content, null)
|
|
|
|
|
|
|
|
return `${'export default '} ${stringifiedData};`
|
|
|
|
}
|
|
|
|
export const raw = true
|
|
|
|
export default nextImageLoader
|