111 lines
4.0 KiB
JavaScript
111 lines
4.0 KiB
JavaScript
const fs = require('fs')
|
|
const path = require('path')
|
|
const Jimp = require('jimp')
|
|
const imagemin = require('imagemin')
|
|
const rimraf = require('rimraf')
|
|
const zopfli = require('node-zopfli')
|
|
const brotli = require('iltorb')
|
|
const filewalker = require('filewalker')
|
|
const chalk = require('chalk')
|
|
const log = console.log;
|
|
|
|
// clear dist path
|
|
const clear_dist = config => new Promise((resolve, reject) => rimraf(path.join(config.basepath, config.dist_path, config.image_path), err => err ? reject(err) : resolve()))
|
|
|
|
// webp conversion
|
|
const convertToWebp = config => {
|
|
return new Promise((resolve, reject) => {
|
|
let cbw_counter = 0
|
|
const webp_plug = [require('imagemin-webp')({method: 6})]
|
|
const wcb = () => cbw_counter++ === config.images.length - 1 ? resolve() : false
|
|
config.images.forEach(orig => {
|
|
let folder = path.basename(path.dirname(orig))
|
|
let destination = path.join(config.basepath, config.dist_path, config.image_path, folder)
|
|
let original_path = path.join(destination, path.basename(orig)).replace(',svg', '')
|
|
imagemin([original_path], destination, {plugins: webp_plug}).then(wcb)
|
|
})
|
|
})
|
|
}
|
|
|
|
// losslessly optimize images
|
|
const lossless_optimize = config => {
|
|
return new Promise((resolve, reject) => {
|
|
let cb_counter = 0
|
|
const plugins = [
|
|
require('imagemin-jpegtran')(),
|
|
require('imagemin-jpegoptim')(),
|
|
require('imagemin-mozjpeg')(),
|
|
require('imagemin-zopfli')({more: true}),
|
|
require('imagemin-pngcrush')(),
|
|
require('imagemin-advpng')(),
|
|
require('imagemin-optipng')(),
|
|
require('imagemin-svgo')(),
|
|
]
|
|
const cb = () => cb_counter++ === config.images.length - 1 ? resolve() : false
|
|
|
|
config.images.forEach(orig => {
|
|
const folder = path.basename(path.dirname(orig))
|
|
const destination = path.join(config.basepath, config.dist_path, config.image_path, folder)
|
|
const source = path.join(config.basepath, config.image_path, orig)
|
|
imagemin([source], destination, {plugins: plugins}).then(cb)
|
|
})
|
|
})
|
|
}
|
|
|
|
// compress svg with zopfli & brotli
|
|
const compress_svg = config => {
|
|
return new Promise((resolve, reject) => {
|
|
const find_images = () => {
|
|
let images = []
|
|
filewalker(path.join(config.basepath, config.dist_path, config.image_path))
|
|
.on('file', file => images.push(path.join(config.basepath, config.dist_path, config.image_path, file)))
|
|
.on('done', filter_svgs.bind(null, images))
|
|
.walk()
|
|
}
|
|
|
|
const filter_svgs = images => compress_items(images.filter(image => image.substr(-4) === '.svg'))
|
|
|
|
const compress_items = images => {
|
|
const iterations = images.length * 2
|
|
let scb_counter = 0
|
|
const scb = () => scb_counter++ === iterations ? resolve() : false
|
|
images.forEach(image => {
|
|
// read original file contents
|
|
fs.readFile(image, 'utf-8', (err, contents) => {
|
|
// write zopfli compressed file
|
|
zopfli.gzip(Buffer.from(contents), (err, output) => fs.writeFile(image + '.gz', output, err => err ? reject(err) : scb()))
|
|
// write brotli compressed file
|
|
brotli.compress(Buffer.from(contents), (err, output) => fs.writeFile(image + '.br', output, err => err ? reject(err) : scb()))
|
|
})
|
|
})
|
|
}
|
|
|
|
find_images()
|
|
})
|
|
}
|
|
|
|
module.exports = (config, result) => {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
log(' ', chalk.green('>>'), 'Deleting old destination folder')
|
|
const cleared = await clear_dist(config)
|
|
log(' ', chalk.green('>>'), 'Optimize images')
|
|
const optimized = await lossless_optimize(config)
|
|
log(' ', chalk.green('>>'), 'Convert to WebP')
|
|
const webp = await convertToWebp(config)
|
|
log(' ', chalk.green('>>'), 'Static compress SVG')
|
|
const compressedSvg = compress_svg(config)
|
|
resolve({cleared, optimized, webp, compressedSvg})
|
|
} catch (err) {
|
|
reject(err)
|
|
}
|
|
})
|
|
}
|
|
|
|
/*
|
|
Jimp.read('../img/content/article.jpg', (err, image) => {
|
|
if (err) throw err
|
|
image.resize(Jimp.AUTO, 400).quality(100).write('../dist/article-home.jpg')
|
|
})
|
|
*/
|