Skip to content

Commit 423b819

Browse files
committed
feat: 🚀 Add convertFormat
It allows you to convert images from any extension to another extension.
1 parent 5f21a62 commit 423b819

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

‎__tests__/components/image/config.js

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
const config = {
55
imageDir: '_custom-optimize',
66
filenameGenerator: ({ path, name, width, quality, extension }) => `${path}-${name}.${width}.${quality}.${extension}`,
7+
convertFormat: [
8+
['png', 'webp']
9+
]
710
}
811

912
module.exports = config

‎__tests__/components/image/config.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import React from 'react'
99
import CustomImage from '../../../src/image'
1010

1111
describe('Apply config', () => {
12-
test('Set `imageDir` and `filenameGenerator`', () => {
12+
test('Set `imageDir` and `filenameGenerator` and `convetFormat`', () => {
1313
render(<CustomImage src="/images/img.png" width={1920} height={1280} priority />)
1414

15-
expect(screen.getByRole('img').getAttribute('src')).toBe('/_custom-optimize/images-img.3840.75.png')
15+
expect(screen.getByRole('img').getAttribute('src')).toBe('/_custom-optimize/images-img.3840.75.webp')
1616
})
1717
})

‎src/image.tsx

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Image, { ImageLoader, ImageProps } from 'next/dist/client/image'
33
import React from 'react'
44

55
import type { Manifest } from './cli/types'
6+
import formatValidate from './cli/utils/formatValidate'
67
import getConfig from './utils/getConfig'
78

89
const config = getConfig()
@@ -21,11 +22,24 @@ const exportableLoader: ImageLoader = ({ src: _src, width, quality }) => {
2122
}
2223

2324
// Generate a reasonably unique base folder. Doesn't have to be perfectly unique
24-
const [path, extension] = src.split(/\.([^.]*$)/)
25+
const path = src.split(/\.([^.]*$)/)[0]
26+
let extension = src.split(/\.([^.]*$)/)[1]
2527
if (!path || !extension) {
2628
throw new Error(`Invalid path or no file extension: ${src}`)
2729
}
2830

31+
if (config.convertFormat !== undefined) {
32+
const convertArray = config.convertFormat.find(([beforeConvert]) => beforeConvert === extension)
33+
if (convertArray !== undefined) {
34+
if (!formatValidate(convertArray[0]))
35+
throw Error(`Unauthorized format specified in \`configFormat\`. beforeConvert: ${convertArray[0]}`)
36+
if (!formatValidate(convertArray[1]))
37+
throw Error(`Unauthorized format specified in \`configFormat\`. afterConvert: ${convertArray[1]}`)
38+
39+
extension = convertArray[1]
40+
}
41+
}
42+
2943
const pathWithoutName = path.split('/').slice(0, -1).join('/')
3044
const name = path.split('/').slice(-1).toString()
3145

‎src/utils/getConfig.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { AvifOptions, JpegOptions, PngOptions, WebpOptions } from 'sharp'
22

3+
import type { AllowedFormat } from '../cli/utils/formatValidate'
4+
35
export type Config = {
46
/**
57
* Specify if you are customizing the default output directory, such as next export -o outDir.
@@ -49,6 +51,10 @@ export type Config = {
4951
webp?: WebpOptions
5052
avif?: AvifOptions
5153
}
54+
/**
55+
* It allows you to convert images from any extension to another extension.
56+
*/
57+
convertFormat?: [beforeConvert: AllowedFormat, afterConvert: AllowedFormat][]
5258
}
5359

5460
const getConfig = (): Config => {

0 commit comments

Comments
 (0)