Skip to content

Instantly share code, notes, and snippets.

@jamesmillerburgess
Created April 14, 2020 11:16
Show Gist options
  • Save jamesmillerburgess/a16a0c3b789ceba50cbf30a905f49e30 to your computer and use it in GitHub Desktop.
Save jamesmillerburgess/a16a0c3b789ceba50cbf30a905f49e30 to your computer and use it in GitHub Desktop.
/* eslint-disable no-console */
// From: https://github.com/meteor/meteor/blob/devel/packages/non-core/bundle-visualizer/server.js
import { readFileSync } from 'fs';
import get from 'lodash.get';
import { WebAppInternals } from 'meteor/webapp';
import { MAX_BUNDLE_SIZE } from '/imports/config/bundleSize';
export const statFileFilter = f =>
f.type === 'json' && f.absolutePath && f.absolutePath.endsWith('.stats.json');
// Read the stat file, but if it's in any way unusable just return null.
export const readOrNull = file => {
try {
return JSON.parse(readFileSync(file, 'utf8'));
} catch (err) {
return null;
}
};
export const getStatBundles = () => {
const { staticFiles, staticFilesByArch } = WebAppInternals;
const files = [];
if (staticFilesByArch) {
Object.keys(staticFilesByArch).forEach(arch => {
const archStaticFiles = staticFilesByArch[arch];
Object.keys(archStaticFiles).forEach(path => {
files.push({ ...archStaticFiles[path], arch });
});
});
} else if (staticFiles) {
Object.keys(staticFiles).forEach(path => {
files.push({ ...staticFiles[path], arch: 'web.browser.legacy' });
});
}
return files.filter(statFileFilter).map(file => ({
name: file.hash,
arch: file.arch,
stats: readOrNull(file.absolutePath),
}));
};
export const checkBundleSize = () => {
if (!process.env.IS_BUNDLE_CHECK) {
return;
}
const statBundles = getStatBundles();
const modernizedBundleSize = getBundleSize(statBundles, 'web.browser');
const legacyBundleSize = getBundleSize(statBundles, 'web.browser.legacy');
console.info(
`Max bundle size: ${formatBytes(
MAX_BUNDLE_SIZE
)} gzipped (${MAX_BUNDLE_SIZE.toLocaleString()} bytes)`
);
console.info(
`Modernized bundle size: ${formatBytes(
modernizedBundleSize
)} (${modernizedBundleSize.toLocaleString()} bytes)`
);
console.info(
`Legacy bundle size: ${formatBytes(
legacyBundleSize
)} (${legacyBundleSize.toLocaleString()} bytes)`
);
if (modernizedBundleSize > MAX_BUNDLE_SIZE) {
console.error(
`Modernized bundle size of ${formatBytes(
modernizedBundleSize
)} exceeds maximum of ${formatBytes(MAX_BUNDLE_SIZE)} gzipped`
);
const excess = modernizedBundleSize - MAX_BUNDLE_SIZE;
console.error(
`Modernized bundle maximum size exceeded by ${modernizedBundleSize.toLocaleString()} - ${MAX_BUNDLE_SIZE.toLocaleString()} = ${excess.toLocaleString()} bytes`
);
process.exit(1);
return;
}
if (legacyBundleSize > MAX_BUNDLE_SIZE) {
console.error(
`Legacy bundle size of ${formatBytes(
legacyBundleSize
)} exceeds maximum of ${formatBytes(MAX_BUNDLE_SIZE)} gzipped`
);
const excess = legacyBundleSize - MAX_BUNDLE_SIZE;
console.error(
`Legacy bundle maximum size exceeded by ${legacyBundleSize.toLocaleString()} - ${MAX_BUNDLE_SIZE.toLocaleString()} = ${excess.toLocaleString()} bytes`
);
process.exit(1);
return;
}
// Exit the process no matter what, since we are done checking and don't want
// the CI process running forever
process.exit(0);
};
const getBundleSize = (bundles, arch) =>
get(
bundles.find(bundle => bundle.arch === arch),
'stats.totalMinifiedGzipBytes',
0
);
export const formatBytes = (bytes, decimals = 2) => {
if (bytes === 0) {
return '0 Bytes';
}
if (bytes === 1) {
return '1 Byte';
}
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
};
checkBundleSize();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment