forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(analytics): Generalize file size analytics
Move file size analytics code into a reusable module. See angular#5312, angular#5314
- Loading branch information
Showing
2 changed files
with
123 additions
and
28 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |