scripts/bundleSize/index.js
#! /usr/bin/env node
/* eslint-disable import/extensions */
/* eslint-disable no-console */
import chalk from 'chalk';
import Table from 'cli-table';
import sortByBundlesTotalAscending from './sortByBundlesTotalAscending.js';
import getAverageBundleSize from './getAverageBundleSize.js';
import createConsoleError from './createConsoleError.js';
import {
getPageBundleData,
getServiceConfigBundleData,
getServiceThemeBundleData,
} from './getBundleData.js';
import { MIN_SIZE, MAX_SIZE } from './bundleSizeConfig.js';
export default () => {
const bundleType = process.env.bundleType || 'modern';
const serviceConfigBundleData = sortByBundlesTotalAscending(
getServiceConfigBundleData(),
);
const serviceThemeBundleData = sortByBundlesTotalAscending(
getServiceThemeBundleData(),
);
const serviceConfigBundlesTotals = serviceConfigBundleData.map(
({ totalSize }) => totalSize,
);
const serviceThemeBundlesTotals = serviceThemeBundleData.map(
({ totalSize }) => totalSize,
);
const smallestServiceConfigBundleSize = Math.min(
...serviceConfigBundlesTotals,
);
const largestServiceConfigBundleSize = Math.max(
...serviceConfigBundlesTotals,
);
const averageServiceConfigBundleSize = getAverageBundleSize(
serviceConfigBundlesTotals,
);
const smallestServiceThemeBundleSize = Math.min(...serviceThemeBundlesTotals);
const largestServiceThemeBundleSize = Math.max(...serviceThemeBundlesTotals);
const averageServiceThemeBundleSize = getAverageBundleSize(
serviceThemeBundlesTotals,
);
const pageBundleData = sortByBundlesTotalAscending(getPageBundleData());
const pageBundlesTotals = pageBundleData.map(({ totalSize }) => totalSize);
const smallestPageBundleSize = Math.min(...pageBundlesTotals);
const largestPageBundleSize = Math.max(...pageBundlesTotals);
const averagePageBundleSize = getAverageBundleSize(pageBundlesTotals);
const largestPagePlusServiceBundleSize =
largestServiceConfigBundleSize +
largestServiceThemeBundleSize +
largestPageBundleSize;
const smallestPagePlusServiceBundleSize =
smallestServiceConfigBundleSize +
smallestServiceThemeBundleSize +
smallestPageBundleSize;
const removeBundleTypePrefix = name => name.replace(`${bundleType}.`, '');
const serviceConfigBundlesTable = new Table({
head: ['Service name', 'bundles', 'Total size (Bytes)', 'Total size (kB)'],
});
const serviceThemeBundlesTable = new Table({
head: ['Service name', 'bundles', 'Total size (Bytes)', 'Total size (kB)'],
});
const pageBundlesTable = new Table({
head: [
'Page type',
'main',
'framework',
'lib',
'shared',
'commons',
'page',
'Total size (Bytes)',
'Total size (kB)',
],
});
pageBundleData.forEach(
({
pageName,
main,
framework,
lib,
shared,
commons,
page,
totalSizeInBytes,
totalSize,
}) => {
const getFileInfo = ({ name, size }) =>
`${removeBundleTypePrefix(name).slice(0, 10)}…${name.slice(
-6,
)} (${size}kB)`;
pageBundlesTable.push([
pageName,
main.map(getFileInfo).join('\n'),
framework.map(getFileInfo).join('\n'),
lib.map(getFileInfo).join('\n'),
shared.map(getFileInfo).join('\n'),
commons.map(getFileInfo).join('\n'),
page.map(getFileInfo).join('\n'),
totalSizeInBytes,
totalSize,
]);
},
);
serviceConfigBundleData.forEach(
({ serviceName, bundles, totalSizeInBytes, totalSize }) => {
const getFileInfo = ({ name, size }) =>
`${removeBundleTypePrefix(name)} (${size}kB)`;
serviceConfigBundlesTable.push([
serviceName,
bundles.map(getFileInfo).join('\n'),
totalSizeInBytes,
totalSize,
]);
},
);
serviceThemeBundleData.forEach(
({ serviceName, bundles, totalSizeInBytes, totalSize }) => {
const getFileInfo = ({ name, size }) =>
`${removeBundleTypePrefix(name)} (${size}kB)`;
serviceThemeBundlesTable.push([
serviceName,
bundles.map(getFileInfo).join('\n'),
totalSizeInBytes,
totalSize,
]);
},
);
const pageSummaryTable = new Table();
pageSummaryTable.push(
{ 'Smallest total bundle size (kB)': smallestPageBundleSize },
{ 'Largest total bundle size (kB)': largestPageBundleSize },
{ 'Average total bundle size (kB)': averagePageBundleSize },
);
const serviceSummaryTable = new Table();
serviceSummaryTable.push(
{ 'Smallest total bundle size (kB)': smallestServiceConfigBundleSize },
{ 'Largest total bundle size (kB)': largestServiceConfigBundleSize },
{ 'Average total bundle size (kB)': averageServiceConfigBundleSize },
);
const serviceThemeSummaryTable = new Table();
serviceThemeSummaryTable.push(
{ 'Smallest total bundle size (kB)': smallestServiceThemeBundleSize },
{ 'Largest total bundle size (kB)': largestServiceThemeBundleSize },
{ 'Average total bundle size (kB)': averageServiceThemeBundleSize },
);
const servicePageSummaryTable = new Table();
servicePageSummaryTable.push(
{
'Smallest total bundle size (kB) (smallest service + smallest page)':
smallestPagePlusServiceBundleSize,
},
{
'Largest total bundle size (kB) (largest service + largest page)':
largestPagePlusServiceBundleSize,
},
);
const styledBundleTypeTitle = chalk.green(bundleType.toUpperCase());
console.log(chalk.magenta('Analysing bundles...'));
console.log(chalk.bold('\n\nResults'));
console.log(
chalk.bold(`\n${styledBundleTypeTitle} service config bundle sizes\n`),
);
console.log(serviceConfigBundlesTable.toString());
console.log(
chalk.bold(
`\n\n${styledBundleTypeTitle} service config bundle sizes summary\n`,
),
);
console.log(serviceSummaryTable.toString());
console.log(
chalk.bold(`\n${styledBundleTypeTitle} service theme bundle sizes\n`),
);
console.log(serviceThemeBundlesTable.toString());
console.log(
chalk.bold(
`\n\n${styledBundleTypeTitle} service theme bundle sizes summary\n`,
),
);
console.log(serviceThemeSummaryTable.toString());
console.log(
chalk.bold(`\n\n${styledBundleTypeTitle} page type bundle sizes\n`),
);
console.log(pageBundlesTable.toString());
console.log(
[
chalk.bold(`\n\n${styledBundleTypeTitle} page bundle sizes summary`),
chalk.cyan.bold('(excludes service bundle)\n'),
].join(' '),
);
console.log(pageSummaryTable.toString());
console.log(
chalk.bold(
`\n\n${styledBundleTypeTitle} service config & theme + page bundle sizes summary\n`,
),
);
console.log(servicePageSummaryTable.toString());
const errors = [];
if (smallestPagePlusServiceBundleSize < MIN_SIZE) {
const service = serviceConfigBundleData[0].serviceName;
const pageType = pageBundleData[0].pageName;
errors.push(
createConsoleError({
service,
pageType,
size: smallestPagePlusServiceBundleSize,
adjective: 'small',
}),
);
}
if (largestPagePlusServiceBundleSize > MAX_SIZE) {
const service =
serviceConfigBundleData[serviceConfigBundleData.length - 1].serviceName;
const pageType = pageBundleData[pageBundleData.length - 1].pageName;
errors.push(
createConsoleError({
service,
pageType,
size: largestPagePlusServiceBundleSize,
adjective: 'large',
}),
);
}
if (errors.length) {
console.error('Issues with service bundles: ');
errors.forEach(err => console.error(err));
throw new Error();
} else {
console.log('All bundle sizes are good!');
}
};