Introduces a new Bazel test that allows us to inspect what source-files contribute to a given bundled file and how much bytes they contribute to the bundle size. Additionally the size-tracking rule groups the size data by directories. This allows us to compare size changes in the scope of directories. e.g. a lot of files in a directory could increase slightly in size, but in the directory scope the size change could be significant and needs to be reported by the test target. Resolves FW-1278 PR Close #30070
		
			
				
	
	
		
			76 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * @license
 | 
						|
 * Copyright Google Inc. All Rights Reserved.
 | 
						|
 *
 | 
						|
 * Use of this source code is governed by an MIT-style license that can be
 | 
						|
 * found in the LICENSE file at https://angular.io/license
 | 
						|
 */
 | 
						|
 | 
						|
export interface DirectorySizeEntry {
 | 
						|
  size: number;
 | 
						|
  [filePath: string]: DirectorySizeEntry|number;
 | 
						|
}
 | 
						|
 | 
						|
export interface FileSizeData {
 | 
						|
  unmapped: number;
 | 
						|
  files: DirectorySizeEntry;
 | 
						|
}
 | 
						|
 | 
						|
/** Returns a new file size data sorted by keys in ascending alphabetical order. */
 | 
						|
export function sortFileSizeData({unmapped, files}: FileSizeData): FileSizeData {
 | 
						|
  return {unmapped, files: _sortDirectorySizeEntryObject(files)};
 | 
						|
}
 | 
						|
 | 
						|
/** Gets the name of all child size entries of the specified one. */
 | 
						|
export function getChildEntryNames(entry: DirectorySizeEntry): string[] {
 | 
						|
  // The "size" property is reserved for the stored size value.
 | 
						|
  return Object.keys(entry).filter(key => key !== 'size');
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Returns the first size-entry that has multiple children. This is also known as
 | 
						|
 * the omitting of the common path prefix.
 | 
						|
 * */
 | 
						|
export function omitCommonPathPrefix(entry: DirectorySizeEntry): DirectorySizeEntry {
 | 
						|
  let current: DirectorySizeEntry = entry;
 | 
						|
  while (getChildEntryNames(current).length === 1) {
 | 
						|
    const newChild = current[getChildEntryNames(current)[0]];
 | 
						|
    // Only omit the current node if it is a size entry. In case the new
 | 
						|
    // child is a holding a number, then this is a file and we don'twant
 | 
						|
    // to incorrectly omit the leaf file entries.
 | 
						|
    if (typeof newChild === 'number') {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    current = newChild;
 | 
						|
  }
 | 
						|
  return current;
 | 
						|
}
 | 
						|
 | 
						|
function _sortDirectorySizeEntryObject(oldObject: DirectorySizeEntry): DirectorySizeEntry {
 | 
						|
  return Object.keys(oldObject)
 | 
						|
      .sort(_sortSizeEntryKeys)
 | 
						|
      .reduce(
 | 
						|
          (result, key) => {
 | 
						|
            if (typeof oldObject[key] === 'number') {
 | 
						|
              result[key] = oldObject[key];
 | 
						|
            } else {
 | 
						|
              result[key] = _sortDirectorySizeEntryObject(oldObject[key] as DirectorySizeEntry);
 | 
						|
            }
 | 
						|
            return result;
 | 
						|
          },
 | 
						|
          {} as DirectorySizeEntry);
 | 
						|
}
 | 
						|
 | 
						|
function _sortSizeEntryKeys(a: string, b: string) {
 | 
						|
  // The "size" property should always be the first item in the size entry.
 | 
						|
  // This makes it easier to inspect the size of an entry in the golden.
 | 
						|
  if (a === 'size') {
 | 
						|
    return -1;
 | 
						|
  } else if (a < b) {
 | 
						|
    return -1;
 | 
						|
  } else if (a > b) {
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 |