collab/mermaid/scripts/size.tsblame
View source
6dd74de1/* eslint-disable no-console */
6dd74de2import type { Metafile } from 'esbuild';
6dd74de3import { readFile } from 'fs/promises';
6dd74de4import { globby } from 'globby';
6dd74de5import { markdownTable } from 'markdown-table';
6dd74de6export const getSizes = (metafile: Metafile) => {
6dd74de7 const { outputs } = metafile;
6dd74de8 const sizes = Object.keys(outputs)
6dd74de9 .filter((key) => key.endsWith('js') && !key.includes('chunk'))
6dd74de10 .map((key) => {
6dd74de11 const { bytes } = outputs[key];
6dd74de12 return [key.replace('dist/', ''), bytes];
6dd74de13 });
6dd74de14 return sizes;
6dd74de15};
6dd74de16
6dd74de17const readStats = async (path: string): Promise<Record<string, number>> => {
6dd74de18 const files = await globby(path);
6dd74de19 const contents = await Promise.all(files.map((file) => readFile(file, 'utf-8')));
6dd74de20 const sizes = contents.flatMap((content) => getSizes(JSON.parse(content)));
6dd74de21 return Object.fromEntries(sizes);
6dd74de22};
6dd74de23
6dd74de24const formatBytes = (bytes: number): string => {
6dd74de25 if (bytes == 0) {
6dd74de26 return '0 Bytes';
6dd74de27 }
6dd74de28 bytes = Math.abs(bytes);
6dd74de29 const base = 1024;
6dd74de30 const decimals = 2;
6dd74de31 const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
6dd74de32 const i = Math.floor(Math.log(bytes) / Math.log(base));
6dd74de33 return parseFloat((bytes / Math.pow(base, i)).toFixed(decimals)) + ' ' + sizes[i];
6dd74de34};
6dd74de35
6dd74de36const formatSize = (bytes: number): string => {
6dd74de37 const formatted = formatBytes(bytes);
6dd74de38 if (formatted.includes('Bytes')) {
6dd74de39 return formatted;
6dd74de40 }
6dd74de41 return `${formatBytes(bytes)} (${bytes} Bytes)`;
6dd74de42};
6dd74de43
6dd74de44const percentageDifference = (oldValue: number, newValue: number): string => {
6dd74de45 const difference = Math.abs(newValue - oldValue);
6dd74de46 const avg = (newValue + oldValue) / 2;
6dd74de47 const percentage = (difference / avg) * 100;
6dd74de48 const roundedPercentage = percentage.toFixed(2); // Round to two decimal places
6dd74de49 if (roundedPercentage === '0.00') {
6dd74de50 return '0.00%';
6dd74de51 }
6dd74de52 const sign = newValue > oldValue ? '+' : '-';
6dd74de53 return `${sign}${roundedPercentage}%`;
6dd74de54};
6dd74de55
6dd74de56const main = async () => {
6dd74de57 const oldStats = await readStats('./cypress/snapshots/stats/base/**/*.json');
6dd74de58 const newStats = await readStats('./cypress/snapshots/stats/head/**/*.json');
6dd74de59 const diff = Object.entries(newStats)
6dd74de60 .filter(([, value]) => value > 2048)
6dd74de61 .map(([key, value]) => {
6dd74de62 const oldValue = oldStats[key];
6dd74de63 const delta = value - oldValue;
6dd74de64 const output = [
6dd74de65 key,
6dd74de66 formatSize(oldValue),
6dd74de67 formatSize(value),
6dd74de68 formatSize(delta),
6dd74de69 percentageDifference(oldValue, value),
6dd74de70 ];
6dd74de71 return output;
6dd74de72 })
6dd74de73 .filter(([, , , delta]) => delta !== '0 Bytes');
6dd74de74 if (diff.length === 0) {
6dd74de75 console.log('No changes in bundle sizes');
6dd74de76 return;
6dd74de77 }
6dd74de78 console.log(
6dd74de79 markdownTable([['File', 'Previous Size', 'New Size', 'Difference', '% Change'], ...diff])
6dd74de80 );
6dd74de81};
6dd74de82
6dd74de83void main().catch((e) => console.error(e));