1import { Platform } from '@expo/config'; 2import { BundleOutput } from '@expo/dev-server'; 3import chalk from 'chalk'; 4import prettyBytes from 'pretty-bytes'; 5import table from 'text-table'; 6 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}.js (Hermes)`), 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}.js.map (Hermes)`), 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 = index === 0 ? '┌' : index === files.length - 1 ? '└' : '├'; 46 47 return [`${fileBranch} ${item[0]}`, prettyBytes(Buffer.byteLength(item[1], 'utf8'))]; 48 }); 49 return table([['Bundle', 'Size'].map((v) => chalk.underline(v)), ...tableData], { 50 align: ['l', 'r'], 51 stringLength: (str) => stripAnsi(str)?.length ?? 0, 52 }); 53} 54