chore(analytics): Generalize file size analytics

Move file size analytics code into a reusable module.

See #5312, #5314
This commit is contained in:
Tim Blasi 2015-11-19 14:50:44 -08:00 committed by Timothy Blasi
parent 9ca8a35553
commit 225b9d306b
2 changed files with 123 additions and 28 deletions

View File

@ -1054,34 +1054,9 @@ gulp.task('!bundle.copy', function() {
});
gulp.task('!bundles.js.checksize', function() {
var gzip = require('gulp-gzip');
var path = require('path');
return merge2(gulp.src('dist/js/bundle/**').on('data', checkFileSizeFactory('uncompressed')),
gulp.src('dist/js/bundle/**')
.pipe(gzip({gzipOptions: {level: 1}})) // code.angular.js
.on('data', checkFileSizeFactory('gzip level=1')),
gulp.src('dist/js/bundle/**')
.pipe(gzip({gzipOptions: {level: 2}})) // github pages, most common
.on('data', checkFileSizeFactory('gzip level=2', true)),
gulp.src('dist/js/bundle/**')
.pipe(gzip({gzipOptions: {level: 6}})) // default gzip level
.on('data', checkFileSizeFactory('gzip level=6')),
gulp.src('dist/js/bundle/**')
.pipe(gzip({gzipOptions: {level: 9}})) // max gzip level
.on('data', checkFileSizeFactory('gzip level=9')));
function checkFileSizeFactory(compressionLevel, printToConsole) {
return function checkFileSize(file) {
if (file.isNull()) return;
var filePath =
path.relative(path.join('dist', 'js', 'bundle'), file.path).replace('\.gz', '');
analytics.bundleSize(filePath, file.contents.length, compressionLevel);
if (printToConsole) {
console.log(` ${filePath} => ${file.contents.length} bytes (${compressionLevel})`)
}
}
}
var reportSize = require('./tools/analytics/reportsize');
return reportSize('dist/js/bundle/**', {printToConsole: false,
reportAnalytics: true});
});
gulp.task('bundles.js',

View File

@ -0,0 +1,120 @@
'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 keys of `_gzipConfigs`.
// - Values are the max size (in bytes) allowed for that configuration.
failConditions: {},
prefix: '',
printToConsole: false,
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 = _checkFailConditionConfig(options.failConditions);
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 (options.printToConsole) {
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}.`);
if (options.printToConsole) {
console.log(` !!! ${errs[errs.length - 1]}`);
}
}
}
}
}
}
// Returns an error stream if the fail conditions are not provided property.
// Returns `null` if everything is fine.
function _checkFailConditionConfig(failConditions) {
for (const key in failConditions) {
if (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;
}
}
}
return null;
}
module.exports = reportSize;