Created
March 25, 2024 09:11
-
-
Save yikZero/55f1189546cd34768682c3f8543e3935 to your computer and use it in GitHub Desktop.
Simplified version of plaiceholder, just support base64 and metadata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sharp, { type Metadata, type Sharp } from 'sharp'; | |
type SharpFormatOptions = Parameters<Sharp['toFormat']>; | |
type SharpModulateOptions = NonNullable<Parameters<Sharp['modulate']>[0]>; | |
export type GetPlaceholderSrc = Buffer; | |
export interface GetPlaceholderOptions extends SharpModulateOptions { | |
size?: number; | |
format?: SharpFormatOptions; | |
} | |
export interface GetPlaiceholderReturn { | |
metadata: Omit<Metadata, 'width' | 'height'> & | |
Required<Pick<Metadata, 'width' | 'height'>>; | |
base64: string; | |
} | |
export const getPlaceholder = async ( | |
src: GetPlaceholderSrc, | |
{ size = 8, format = ['png'] }: GetPlaceholderOptions = {}, | |
) => { | |
const metadata = await sharp(src) | |
.metadata() | |
.then(({ width, height, ...metadata }) => { | |
if (!width || !height) { | |
throw Error('Could not get required image metadata'); | |
} | |
return { width, height, ...metadata }; | |
}); | |
const sizeMin = 4; | |
const sizeMax = 64; | |
const isSizeValid = sizeMin <= size && size <= sizeMax; | |
!isSizeValid && | |
console.error( | |
['Please enter a `size` value between', sizeMin, 'and', sizeMax].join( | |
' ', | |
), | |
); | |
const pipeline = sharp(src) | |
.resize(size, size, { | |
fit: 'inside', | |
}) | |
.toFormat(...format); | |
const base64 = await pipeline | |
.clone() | |
.normalise() | |
.toBuffer({ resolveWithObject: true }) | |
.then( | |
({ data, info }) => | |
`data:image/${info.format};base64,${data.toString('base64')}`, | |
) | |
.catch((err) => { | |
console.error('base64 generation failed', err); | |
throw err; | |
}); | |
return { | |
base64, | |
metadata, | |
}; | |
}; |
One purpose is also to work with contentlayer and to solve the plaiceholder v2.5.0 vercel build error.
Vercel build error:
munmap_chunk(): invalid pointer
Error: Command "pnpm run build" exited with SIGABRT
You can fix it by doing this:
const { withContentlayer } = require('next-contentlayer');
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack(config) {
const sharpRule = {
sharp: 'commonjs sharp',
};
if (Array.isArray(config.externals)) {
config.externals.push(sharpRule);
} else {
config.externals = {
...config.externals,
...sharpRule,
};
}
return config;
},
transpilePackages: ['sharp'],
};
module.exports = nextConfig;
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prepare
Sharp
pnpm
npm
Usgae
With Next.js