Create gulp targets to build `hello_world` and check its gzipped size against size constraints. See #5312, #5314
		
			
				
	
	
		
			140 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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;
 |