1+ import { obj } from 'through2'
2+ import sharp from 'sharp'
3+ import Vinyl from 'vinyl'
4+
5+ const ALLOWED_EXTENTIONS = [
6+ '.gif' ,
7+ '.png' ,
8+ '.jpg' , '.jpeg' ,
9+ '.webp' ,
10+ '.avif' ,
11+ '.tiff' ,
12+ '.heif' ,
13+ ]
14+ const optionsByDefualt = {
15+ quality : 90 ,
16+ lossless : false ,
17+ chromaSubsampling : '4:2:0'
18+ }
19+
20+
21+ export default function sharpImageOptimize ( options ) {
22+ return obj ( async function ( file , enc , callback ) {
23+ if ( file . isNull ( ) ) {
24+ return callback ( null , file )
25+ }
26+ if ( ALLOWED_EXTENTIONS . includes ( file . extname ) == false ) {
27+ console . error ( `${ file . basename } not supported, just copy.` )
28+
29+ return callback ( null , file )
30+ }
31+ if ( typeof options !== 'object' ) {
32+ throw new Error ( 'Invalid parameters, they must be an object.' )
33+ }
34+
35+ let convertedImages = [ ]
36+ let optionObjects = Object . entries ( options )
37+
38+ for ( let [ optionObjectFormat , optionObjectProps ] of optionObjects ) {
39+ let convertedFile = await convert ( file , optionObjectFormat , optionObjectProps )
40+ convertedImages . push ( convertedFile )
41+ }
42+
43+ for ( let convertedImage of convertedImages ) {
44+ this . push ( convertedImage )
45+ }
46+
47+ return callback ( )
48+ } )
49+ }
50+
51+ async function convert ( file , newFileFormat , options ) {
52+ let sharpInstance = sharp ( file . contents , { animated : true , limitInputPixels : false , } )
53+
54+ switch ( newFileFormat ) {
55+ case 'gif' :
56+ sharpInstance = sharpInstance . gif ( Object . assign ( optionsByDefualt , options ) )
57+ break
58+ case 'png' :
59+ sharpInstance = sharpInstance . png ( Object . assign ( optionsByDefualt , options ) )
60+ break
61+ case 'jpg' :
62+ case 'jpeg' :
63+ sharpInstance = sharpInstance . jpeg ( Object . assign ( optionsByDefualt , options ) )
64+ break
65+ case 'webp' :
66+ sharpInstance = sharpInstance . webp ( Object . assign ( optionsByDefualt , options ) )
67+ break
68+ case 'tiff' :
69+ sharpInstance = sharpInstance . tiff ( Object . assign ( optionsByDefualt , options ) )
70+ break
71+ case 'avif' :
72+ sharpInstance = sharpInstance . avif ( Object . assign ( optionsByDefualt , options ) )
73+ break
74+ case 'heif' :
75+ sharpInstance = sharpInstance . heif ( Object . assign ( optionsByDefualt , options ) )
76+ break
77+ default :
78+ return false
79+ }
80+
81+ let buffer = await sharpInstance . toBuffer ( )
82+ return toVinyl ( buffer , newFileFormat , file )
83+ }
84+
85+ function toVinyl ( buffer , newFileFormat , file ) {
86+ if ( file . extname != '.' + newFileFormat ) {
87+ file . extname = '.' + newFileFormat
88+ }
89+
90+ return new Vinyl ( {
91+ cwd : file . cwd ,
92+ base : file . base ,
93+ path : file . path ,
94+ contents : buffer ,
95+ } )
96+ }
0 commit comments