Skip to content

Commit e66cdfe

Browse files
authored
feat: support for compressing avif images (#11)
1 parent 7ea9f60 commit e66cdfe

File tree

6 files changed

+22
-2
lines changed

6 files changed

+22
-2
lines changed

src/shared/codecs.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ export const icoCodec: Codec<'ico'> = {
4444
},
4545
};
4646

47+
export const avifCodec: Codec<'avif'> = {
48+
handler(buf, options) {
49+
return new Transformer(buf).avif(options);
50+
},
51+
defaultOptions: {
52+
test: /\.avif$/,
53+
},
54+
};
55+
4756
export const svgCodec: Codec<'svg'> = {
4857
async handler(buf, options) {
4958
const result = svgo.optimize(buf.toString(), options);
@@ -61,6 +70,7 @@ const codecs: Record<Codecs, Codec<any>> = {
6170
pngLossless: pngLosslessCodec,
6271
ico: icoCodec,
6372
svg: svgCodec,
73+
avif: avifCodec,
6474
};
6575

6676
export default codecs;

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Buffer } from 'node:buffer';
22
import type {
3+
AvifConfig,
34
JpegCompressOptions,
45
PNGLosslessOptions,
56
PngQuantOptions,
@@ -18,6 +19,7 @@ export interface CodecBaseOptions {
1819
pngLossless: PNGLosslessOptions;
1920
ico: Record<string, unknown>;
2021
svg: SvgoConfig;
22+
avif: AvifConfig;
2123
}
2224

2325
export interface BaseCompressOptions<T extends Codecs> {

test/assets/image.avif

61.1 KB
Binary file not shown.

test/basic/index.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,24 @@ test('should compress image with use plugin-image-compress', async () => {
2626
join(__dirname, 'dist/static/svg/mobile.svg'),
2727
'utf-8',
2828
);
29+
const avif = readFileSync(
30+
join(__dirname, 'dist/static/image/image.avif'),
31+
'utf-8',
32+
);
2933
// const ico = names.find((item) => item.endsWith('.ico'))!;
3034

3135
const assetsDir = join(__dirname, '../assets');
3236
const originJpeg = readFileSync(join(assetsDir, 'image.jpeg'), 'utf-8');
3337
const originPng = readFileSync(join(assetsDir, 'image.png'), 'utf-8');
3438
const originSvg = readFileSync(join(assetsDir, 'mobile.svg'), 'utf-8');
39+
const originAvif = readFileSync(join(assetsDir, 'image.avif'), 'utf-8');
3540
// const originIco = readFileSync(join(assetsDir, 'image.ico'), 'utf-8');
3641

3742
expect(jpeg.length).toBeLessThan(originJpeg.length);
3843
expect(png.length).toBeLessThan(originPng.length);
3944
expect(svg.length).toBeLessThan(originSvg.length);
45+
expect(avif.length).toBeLessThan(originAvif.length);
46+
console.log(avif.length, originAvif.length);
4047
// TODO ico file size is not less than origin
4148
// expect(outputs[ico].length).toBeLessThan(originIco.length);
4249
});

test/basic/rsbuild.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { defineConfig } from '@rsbuild/core';
22
import { pluginImageCompress } from '@rsbuild/plugin-image-compress';
33

44
export default defineConfig({
5-
plugins: [pluginImageCompress(['jpeg', 'png', 'ico', 'svg'])],
5+
plugins: [pluginImageCompress(['jpeg', 'png', 'ico', 'svg', 'avif'])],
66
output: {
77
filename: {
88
svg: '[name][ext]',

test/basic/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import imageAvif from '../../assets/image.avif?url';
12
import imageIco from '../../assets/image.ico?url';
23
import imageJpeg from '../../assets/image.jpeg?url';
34
import imagePng from '../../assets/image.png?url';
45
import imageSvg from '../../assets/mobile.svg?url';
56

6-
const images = [imageIco, imagePng, imageJpeg, imageSvg];
7+
const images = [imageIco, imagePng, imageJpeg, imageSvg, imageAvif];
78

89
for (const image of images) {
910
const el = new Image();

0 commit comments

Comments
 (0)