angular-cn/tools/analytics/reportsize.js

140 lines
4.6 KiB
JavaScript

'use strict';
let analytics = require('./analytics');
let gulp = require('gulp');
let gzip = require('gulp-gzip');
let merge2 = require('merge2');
let path = require('path');
let Stream = require('stream');
// Keys are a text description of compressionLevel.
// Values are "gzipOptions" passed to gzip.
// We report one `analytics.bundleSize` event
// * each file in `glob`
// * each entry in `_gzipConfigs`.
const _gzipConfigs = {
'uncompressed': null,
'gzip level=1': {level: 1}, // code.angular.js
'gzip level=2': {level: 2}, // github pages, most common
'gzip level=6': {level: 6}, // default gzip level
'gzip level=9': {level: 9} // max gzip level
};
const _defaultOptions = {
// @type {Object<string, number>}
// - Key(s) must match one of `_gzipConfigs` keys.
// - Values are the max size (in bytes) allowed for that configuration.
failConditions: {},
prefix: '',
// @type {Array<string>|boolean}
// Entries must match one of `_gzipConfigs` keys. These values will be
// printed to the screen.
// If this is the boolean value `true`, will print all to screen.
printToConsole: ['gzip level=6'],
reportAnalytics: true
};
// `glob` is a string representing a glob of files.
// options is an object containing zero or more of
// - printToConsole: Write debug to console. Default: false.
// - reportAnalytics: Report to Google Analytics. Default: true.
function reportSize(glob, options) {
options = options || {};
for (const key in _defaultOptions) {
if (!options.hasOwnProperty(key)) {
options[key] = _defaultOptions[key];
}
}
var errStream = _checkConfig(options);
if (errStream) {
return errStream;
}
const allStreams = [];
for (const compressionLevel in _gzipConfigs) {
if (_gzipConfigs.hasOwnProperty(compressionLevel)) {
let stream = gulp.src(glob);
if (_gzipConfigs[compressionLevel]) {
stream = stream.pipe(gzip({gzipOptions: _gzipConfigs[compressionLevel]}));
}
allStreams.push(stream.on('data', checkFileSizeFactory(compressionLevel)));
}
}
let didRun = false;
var errs = [];
return merge2(allStreams, {end: false})
.on('queueDrain', function() {
if (errs.length) {
errs.unshift(`Failed with ${errs.length} error(s).`);
this.emit('error', new Error(errs.join('\n ')));
}
if (!didRun) {
this.emit('error', new Error(`No file found for pattern "${glob}".`));
}
this.emit('end');
});
function checkFileSizeFactory(compressionLevel) {
return function checkFileSize(file) {
if (file.isNull()) return;
didRun = true;
var filePath = path.basename(file.path).replace('\.gz', '');
if (options.prefix) {
filePath = path.join(options.prefix, filePath);
}
const fileLen = file.contents.length;
if (options.reportAnalytics) {
analytics.bundleSize(filePath, fileLen, compressionLevel);
}
if (_shouldPrint(options, compressionLevel)) {
console.log(` ${filePath} => ${fileLen} bytes (${compressionLevel})`)
}
if (options.failConditions.hasOwnProperty(compressionLevel)) {
if (options.failConditions[compressionLevel] < fileLen) {
errs.push(`Max size for "${compressionLevel}" is ` +
`${options.failConditions[compressionLevel]}, but the size is now ${fileLen}.`);
}
}
}
}
}
function _shouldPrint(options, compressionLevel) {
const printAll = typeof options.printToConsole == 'boolean' && options.printToConsole;
return printAll || options.printToConsole.indexOf(compressionLevel) >= 0;
}
// Returns an error stream if the fail conditions are not provided property.
// Returns `null` if everything is fine.
function _checkConfig(config) {
for (const key in config.failConditions) {
if (config.failConditions.hasOwnProperty(key)) {
if (!_gzipConfigs.hasOwnProperty(key)) {
var stream = new Stream();
stream.emit(
'error',
new Error(`failCondition for "${key}" will not be tested. Check _gzipConfigs.`));
stream.emit('end');
return stream;
}
}
}
if (typeof config.printToConsole != 'boolean') {
for (var i = 0; i < config.printToConsole.length; ++i) {
const key = config.printToConsole[i];
if (!_gzipConfigs.hasOwnProperty(key)) {
var stream = new Stream();
stream.emit(
'error',
new Error(`Incorrect value "${key}" in printToConsole. Check _gzipConfigs.`));
stream.emit('end');
return stream;
}
}
}
return null;
}
module.exports = reportSize;