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;
 |