1import { Platform } from '@expo/config'; 2import chalk from 'chalk'; 3import prettyBytes from 'pretty-bytes'; 4import table from 'text-table'; 5 6import { BundleOutput } from './fork-bundleAsync'; 7import * as Log from '../log'; 8import { stripAnsi } from '../utils/ansi'; 9import { learnMore } from '../utils/link'; 10 11export function printBundleSizes(bundles: Partial<Record<Platform, BundleOutput>>) { 12 const files: [string, string | Uint8Array][] = []; 13 14 for (const [platform, bundleOutput] of Object.entries(bundles) as [ 15 Platform, 16 Pick<BundleOutput, 'hermesBytecodeBundle' | 'code' | 'hermesSourcemap' | 'map'>, 17 ][]) { 18 if (bundleOutput.hermesBytecodeBundle) { 19 files.push([chalk.bold(`index.${platform}.hbc`), bundleOutput.hermesBytecodeBundle]); 20 } else if (bundleOutput.code) { 21 files.push([chalk.bold(`index.${platform}.js`), bundleOutput.code]); 22 } 23 if (bundleOutput.hermesSourcemap) { 24 files.push([chalk.dim(`index.${platform}.hbc.map`), bundleOutput.hermesSourcemap]); 25 } else if (bundleOutput.map) { 26 files.push([chalk.dim(`index.${platform}.js.map`), bundleOutput.map]); 27 } 28 } 29 30 Log.log(); 31 Log.log(createFilesTable(files.sort((a, b) => a[1].length - b[1].length))); 32 Log.log(); 33 Log.log( 34 chalk` JavaScript bundle sizes affect startup time. {dim ${learnMore( 35 `https://expo.fyi/javascript-bundle-sizes` 36 )}}` 37 ); 38 Log.log(); 39 40 return files; 41} 42 43export function createFilesTable(files: [string, string | Uint8Array][]): string { 44 const tableData = files.map((item, index) => { 45 const fileBranch = 46 index === 0 ? (files.length > 1 ? '┌' : '─') : index === files.length - 1 ? '└' : '├'; 47 48 return [`${fileBranch} ${item[0]}`, prettyBytes(Buffer.byteLength(item[1], 'utf8'))]; 49 }); 50 return table([['Bundle', 'Size'].map((v) => chalk.underline(v)), ...tableData], { 51 align: ['l', 'r'], 52 stringLength: (str) => stripAnsi(str)?.length ?? 0, 53 }); 54} 55