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