marko/benchmark/size/minify.js
2020-02-24 16:48:25 -08:00

150 lines
3.8 KiB
JavaScript

console.log("Minifying JavaScript bundles...");
const fs = require("fs");
const path = require("path");
const zlib = require("zlib");
const UglifyJS = require("uglify-js");
const formatNumber = require("format-number")();
var buildDir = path.join(__dirname, "build");
var bundlesDir = path.join(__dirname, "build/bundles");
var bundlesMinDir = path.join(__dirname, "build/bundles.min");
try {
fs.mkdirSync(bundlesMinDir);
} catch (e) {
/* ignore error */
}
var promiseChain = Promise.resolve();
function getVersion(name) {
return require(name + "/package.json").version;
}
function leftPad(str, padding) {
if (str.length < padding) {
str = new Array(padding - str.length).join(" ") + str;
}
return str;
}
var minifiers = {
gcc: function minifyGCC(src, file) {
const gcc = require("google-closure-compiler-js");
const options = {
jsCode: [{ src: src }],
languageIn: "ES5"
};
const out = gcc.compile(options);
if (out.errors && out.errors.length) {
console.error(out.errors);
throw new Error(`Minification failed for ${file}`);
}
return out.compiledCode;
},
uglify: function minifyUglifyJS(src, file) {
try {
return UglifyJS.minify(src, {
fromString: true
}).code;
} catch (e) {
if (e.line != null) {
console.error(`Failed to minify ${file}`);
console.error(` Location: ${file}:${e.line}:${e.col}`);
console.error(` Message: ${e.message}`);
process.exit(1);
}
throw e;
}
},
both: function(src, file) {
var withGCC = minifiers.gcc(src, file);
var withBoth = minifiers.uglify(withGCC, file);
return withBoth.length < withGCC.length ? withBoth : withGCC;
}
};
var minifier = minifiers.both;
var bundleFiles = fs.readdirSync(bundlesDir);
var sizes = {};
var targetLib = process.argv[2];
bundleFiles.forEach(filename => {
if (!filename.endsWith(".js")) {
return;
}
var file = path.join(bundlesDir, filename);
var ext = path.extname(filename);
var lib = filename.slice(0, 0 - ext.length);
if (targetLib && lib !== targetLib) {
return;
}
console.log(`Minifying ${file}...`);
var src = fs.readFileSync(file, { encoding: "utf8" });
var minifiedSrc = minifier(src, file);
console.log(`Done minifying ${file}`);
var minFile = path.join(bundlesMinDir, filename);
fs.writeFileSync(minFile, minifiedSrc, { encoding: "utf8" });
var sizeInfo = (sizes[lib] = {});
promiseChain = promiseChain.then(() => {
return new Promise((resolve, reject) => {
console.log(`Compressing and calculating size of ${file}...`);
zlib.gzip(minifiedSrc, function(err, gzippedBuffer) {
if (err) {
return reject(err);
}
// Compare the sizes
var minifiedBuffer = new Buffer(minifiedSrc, "utf8");
// console.log(nodePath.basename(templateInfo.outputCompileMinifiedFile) + ': ' + gzippedBuffer.length + ' bytes gzipped (' + minifiedBuffer.length + ' bytes uncompressed)');
sizeInfo.gzipped = gzippedBuffer.length;
sizeInfo.min = minifiedBuffer.length;
var libVersion = getVersion(lib);
var sizeFilename = lib + (libVersion ? "-" + libVersion : "") + ".json";
fs.writeFileSync(
path.join(buildDir, sizeFilename),
JSON.stringify(sizeInfo, null, 4),
{ encoding: "utf8" }
);
resolve();
});
});
});
});
promiseChain.then(() => {
console.log();
for (var lib in sizes) {
var sizeInfo = sizes[lib];
console.log("[" + lib + "]");
console.log(
" gzip: " + leftPad(formatNumber(sizeInfo.gzipped), 8) + " bytes"
);
console.log(" min: " + leftPad(formatNumber(sizeInfo.min), 8) + " bytes");
console.log();
}
console.log("Minification complete.");
});