rsnext/packages/next/build/webpack/loaders/next-image-loader.js

55 lines
1.5 KiB
JavaScript
Raw Normal View History

import loaderUtils from 'next/dist/compiled/loader-utils'
import sizeOf from 'image-size'
import { processBuffer } from '../../../next-server/server/lib/squoosh/main'
const BLUR_IMG_SIZE = 8
const BLUR_QUALITY = 70
const VALID_BLUR_EXT = ['jpeg', 'png', 'webp']
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)
let blurDataURL
if (VALID_BLUR_EXT.includes(extension)) {
// Shrink the image's largest dimension
const resizeOperationOpts =
imageSize.width >= imageSize.height
? { type: 'resize', width: BLUR_IMG_SIZE }
: { type: 'resize', height: BLUR_IMG_SIZE }
const resizedImage = await processBuffer(
content,
[resizeOperationOpts],
extension,
BLUR_QUALITY
)
blurDataURL = `data:image/${extension};base64,${resizedImage.toString(
'base64'
)}`
}
const stringifiedData = JSON.stringify({
src: '/_next' + interpolatedName,
height: imageSize.height,
width: imageSize.width,
blurDataURL,
})
this.emitFile(interpolatedName, content, null)
return `${'export default '} ${stringifiedData};`
}
export const raw = true
export default nextImageLoader