Created
March 20, 2017 00:44
-
-
Save danclarke/7a5b647d38a63241b71fb3743db15160 to your computer and use it in GitHub Desktop.
Compress files in directory and sub directories using gzip and brotli
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const brotli = require('brotli'); | |
const zlib = require('zlib'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const compressDir = function (dir) { | |
console.log('Reading in: ' + dir); | |
fs.readdir(dir, function (err, files) { | |
if (err) { | |
console.error("Could not list the directory.", err); | |
process.exit(1); | |
} | |
files.forEach(function (file, index) { | |
const filePath = path.join(dir, file); | |
fs.stat(filePath, function (error, stat) { | |
if (error) { | |
console.error("Error stating file.", error); | |
return; | |
} | |
if (stat.isFile()) { | |
console.log("Compressing '%s'", filePath); | |
const originalSize = stat.size; | |
// Read in data to compress | |
fs.readFile(filePath, function (readError, readData) { | |
if (readError) { | |
console.error("Error reading file.", error); | |
return; | |
} | |
// Compress | |
compressGzip(originalSize, filePath, readData); | |
compressBrotli(originalSize, filePath, readData); | |
}); | |
} | |
else if (stat.isDirectory()) { | |
compressDir(filePath); | |
} | |
}); | |
}); | |
}); | |
} | |
const compressBrotli = function(originalSize, filePath, fileData) { | |
const compressed = brotli.compress(fileData, { | |
mode: getBrotliMode(filePath), | |
quality: 11, | |
lgwin: 22 | |
}); | |
// Write out the compressed file | |
const compressedFilePath = filePath + '.br'; | |
fs.writeFile(compressedFilePath, new Buffer(compressed), { | |
encoding: 'binary' | |
}, function (writeError) { | |
if (writeError) { | |
console.error("Error writing file.", writeError); | |
return; | |
} | |
ensureCompressedSmaller(originalSize, compressedFilePath); | |
}); | |
} | |
const compressGzip = function(originalSize, filePath, fileData) { | |
const compressedFilePath = filePath + '.gz'; | |
zlib.gzip(fileData, function (error, compressedData) { | |
if (error) { | |
console.error("Error gzipping file.", writeError); | |
return; | |
} | |
fs.writeFile(compressedFilePath, compressedData, function (saveError) { | |
if (saveError) { | |
console.error("Error writing file.", writeError); | |
return; | |
} | |
ensureCompressedSmaller(originalSize, compressedFilePath); | |
}); | |
}) | |
} | |
const ensureCompressedSmaller = function(originalSize, filePath) { | |
// Get filesize of compressed file to ensure compression | |
fs.stat(filePath, function (compressError, compressStat) { | |
if (originalSize <= compressStat.size) { | |
// Uncompressed file is smaller, so delete the compressed file | |
console.log("Compressed file '%s' is bigger, deleting", filePath); | |
fs.unlink(filePath, function (deleteError) { | |
if (deleteError) { | |
console.error('Error deleting compressed file.', deleteError); | |
} | |
}); | |
} | |
}); | |
} | |
const getBrotliMode = function(filePath) { | |
const ext = path.extname(filePath).toLowerCase(); | |
switch (ext) { | |
case '.js': | |
case '.css': | |
case '.svg': | |
case '.map': | |
case '.json': | |
case '.html': | |
case '.htm': | |
case '.map': | |
return 1; // Text | |
default: | |
return 0; // General | |
} | |
} | |
compressDir('dist'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment