UNPKG

laravel-mix-compress-images

Version:

Add compress-images tools for laravel mix

125 lines (111 loc) 2.88 kB
const fs = require('fs'); const RawSource = require('webpack-sources/lib/RawSource'); const minimatch = require('minimatch'); let compress_images = require('compress-images'); class CompressImagesPlugin { constructor(patterns = {}, output = {}, compressParameters = {}) { this.patterns = patterns; this.output = output; this.compressParameters = { ...{ jpg: { engine: 'mozjpeg', command: ['-quality', '60'] }, png: { engine: 'pngquant', command: ['--quality=20-50'] }, svg: { engine: 'svgo', command: '--multipass' }, gif: { engine: 'gifsicle', command: ['--colors', '64', '--use-col=web'] }, }, ...compressParameters }; } apply(compiler) { // Access the assets once they have been assembled const onEmit = async (compilation, callback) => { try { // Filter assets that matches current pattern. const assets = Object.keys(compilation.assets).filter(item => { return this.patterns.filter(pattern => { return minimatch(item, pattern); }).length > 0; }); // Process each input file. await Promise.all( assets.map(path => this.processOneFile(path, compilation)) ); // When all files are done. callback(); } catch (err) { callback(err) } } // Check if the webpack 4 plugin API is available if (compiler.hooks) { // Register emit event listener for webpack 4 compiler.hooks.emit.tapAsync(this.constructor.name, onEmit) } else { // Register emit event listener for older webpack versions compiler.plugin('emit', onEmit) } } /** * Process only one file * * @param path * @param compilation * @returns {Promise<any>} */ processOneFile(path, compilation) { const callback = (resolve) => { let destination = path.split('/'); // Forget the filename. let filename = destination.pop(); // As we use this.output, we delete the first rep. destination = destination.splice(1); destination = (destination.length > 0 ? '/' + destination.join('/') : '') + '/'; destination = this.compressParameters.destination + '/' + this.output + destination; compress_images( path, destination, { compress_force: false, statistic: true, autoupdate: true }, false, { jpg: this.compressParameters.jpg }, { png: this.compressParameters.png }, { svg: this.compressParameters.svg }, { gif: this.compressParameters.gif }, (error, completed, statistic) => { if (completed) { let data = fs.readFileSync(destination + filename); if (data) { delete compilation.assets[path]; compilation.assets[destination + filename] = new RawSource(data); } } resolve(); }); } return new Promise(callback); } } module.exports = CompressImagesPlugin;