gulp-sharp-optimize-images
/
index.js
138 строк · 3.6 Кб
1import { obj } from 'through2'2import sharp from 'sharp'3import Vinyl from 'vinyl'4import chalk from 'chalk'5import path from 'path'6
7const
8ALLOWED_EXTENSIONS = [9'.gif',10'.png',11'.jpg', '.jpeg',12'.webp',13'.avif',14'.tiff',15'.heif',16],17DEFAULT_CONVERSION_OPTIONS = {18quality: 90,19lossless: false,20chromaSubsampling: '4:2:0',21},22DEFAULT_SHARP_OPTIONS = {23animated: true,24limitInputPixels: false,25}26
27
28export default function sharpOptimizeImages(options) {29let logLevel = options.logLevel ?? 'small'30delete options.logLevel31let optionObjects = Object.entries(options)32
33return obj(async function (file, enc, callback) {34if (!file) return callback(null, file)35
36if (typeof options !== 'object')37throw new Error('Invalid parameters, they must be an object.')38
39if (!ALLOWED_EXTENSIONS.includes(file.extname)) {40logAboutSuccessfulCopy(file, logLevel)41return callback(null, file)42}43
44let originalFileExtname = file.extname.split('.').at(-1)45
46
47for (let [format, props] of optionObjects) {48let [convertFrom, convertTo] = format.split('_to_')49
50if (!extnamesIsCorrect(convertFrom, convertTo)) {51throw new Error('Invalid name of an object! Make sure you have spelled the extension names correctly.')52}53
54// Checking that the file has not a suitable extension55if (convertTo && `.${convertFrom}` != file.extname) continue56
57//? For general conversion rules such as png: {}58if (!convertTo) {59this.push(await convert(file, convertFrom, props))60logAboutSuccessfulConversion(file, convertFrom, logLevel)61
62if (props.alsoProcessOriginal) {63this.push(await convert(file, originalFileExtname, props))64logAboutSuccessfulConversion(file, originalFileExtname, logLevel)65}66}67//? For specific conversion rules such as png_to_webp: {}68else {69this.push(await convert(file, convertTo, props))70
71logAboutSuccessfulConversion(file, convertTo, logLevel)72}73}74
75return callback()76})77}
78
79async function convert(file, newFileFormat, options) {80if (newFileFormat == 'heif')81options.compression = 'av1'82
83let sharpBuffer =84await sharp(file.path, DEFAULT_SHARP_OPTIONS)85.toFormat(newFileFormat, Object.assign(DEFAULT_CONVERSION_OPTIONS, options))86.toBuffer()87
88return toVinyl(sharpBuffer, newFileFormat, file)89}
90
91function toVinyl(buffer, newFileFormat, file) {92let newFileName = file.basename.substr(0, file.basename.lastIndexOf('.'))93+ '.' + newFileFormat94
95return new Vinyl({96cwd: file.cwd,97base: file.base,98path: path.join(file.dirname, newFileName),99contents: buffer,100})101}
102
103
104function extnamesIsCorrect(...extnames) {105for (let extname of extnames) {106if (extname && !ALLOWED_EXTENSIONS.includes('.' + extname))107return false108}109
110return true111}
112
113function logAboutSuccessfulConversion(file, newFileExtname, logLevel) {114let filename = file.basename.split('.')[0]115
116if (logLevel == 'full')117console.log(118'The file ' + chalk.green(file.path)119+ ' was processed to '120+ chalk.green(filename + '.' + chalk.bold(newFileExtname))121)122else if (logLevel == 'small')123console.log(124chalk.green(file.basename) + ' => ' + chalk.green.bold(newFileExtname)125)126}
127function logAboutSuccessfulCopy(file, logLevel) {128if (logLevel == 'full')129console.log(chalk.hex('#FF8800')130(131`The image ${chalk.bold(file.basename)} cannot be processed, so it is copied.`132)133)134else if (logLevel == 'small')135console.log(chalk.hex('#FF8800')136(file.basename + ' => ' + chalk.bold('copied'))137)138}