rsnext/packages/next/next-server/server/lib/squoosh/main.ts
Joe Haddad 99a4ea6e9a
feat(next/image): remove sharp for wasm variant (#22253)
This pull request removes the native `sharp` dependency (which doesn't work on some Linux variants, nor **M1 Mac**) and replaces it with a wasm equivalent.

It also reduces Next.js' installed size by 27.3 MB.

The code is adapted from the [Squoosh CLI](https://github.com/GoogleChromeLabs/squoosh).

This PR still supports:

- Rotation normalization
- Resizing
- PNG
- JPEG
- Webp

However, it (temporarily) removes support for:
- Resizing Gifs
- Resizing Tiff

(these formats still get served and rendered correctly by the image component)

---

Fixes #20456
Closes #20738
Closes #21762
2021-02-18 10:23:24 +00:00

56 lines
1.6 KiB
TypeScript

import JestWorker from 'jest-worker'
import * as path from 'path'
import { execOnce } from '../../../lib/utils'
import ImageData from './image_data'
const getWorker = execOnce(
() =>
new JestWorker(path.resolve(__dirname, 'impl'), {
enableWorkerThreads: true,
})
)
export async function decodeBuffer(buffer: Buffer): Promise<ImageData> {
const worker: typeof import('./impl') = getWorker() as any
return ImageData.from(await worker.decodeBuffer(buffer))
}
export async function rotate(
image: ImageData,
numRotations: number
): Promise<ImageData> {
const worker: typeof import('./impl') = getWorker() as any
return ImageData.from(await worker.rotate(image, numRotations))
}
export async function resize(
image: ImageData,
{ width }: { width: number }
): Promise<ImageData> {
const worker: typeof import('./impl') = getWorker() as any
return ImageData.from(await worker.resize(image, { width }))
}
export async function encodeJpeg(
image: ImageData,
{ quality }: { quality: number }
): Promise<Buffer> {
const worker: typeof import('./impl') = getWorker() as any
const o = await worker.encodeJpeg(image, { quality })
return Buffer.from(o)
}
export async function encodeWebp(
image: ImageData,
{ quality }: { quality: number }
): Promise<Buffer> {
const worker: typeof import('./impl') = getWorker() as any
const o = await worker.encodeWebp(image, { quality })
return Buffer.from(o)
}
export async function encodePng(image: ImageData): Promise<Buffer> {
const worker: typeof import('./impl') = getWorker() as any
const o = await worker.encodePng(image)
return Buffer.from(o)
}