From d972e4da41e09cbb40e1197bd620fa337ebe78bc Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Fri, 29 Dec 2023 17:53:04 -0800 Subject: [PATCH] Module duplicates: transition to using a custom selector This allows pretty easy extension to measuring other types (like duplicate count) I've declined not to add a metric selector at this time because creating a new dropdown that only allows a single selection would be a lot more changes. --- .../src/components/bundle-modules/index.jsx | 7 +-- packages/utils/src/webpack/compare.js | 35 +++++--------- packages/utils/src/webpack/selectors.js | 46 +++++++++++++++---- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/ui/src/components/bundle-modules/index.jsx b/packages/ui/src/components/bundle-modules/index.jsx index 65d06cd12b..9bedd672c8 100644 --- a/packages/ui/src/components/bundle-modules/index.jsx +++ b/packages/ui/src/components/bundle-modules/index.jsx @@ -62,11 +62,12 @@ export const BundleModules = (props) => { const [useDuplicatedSize, setUseDuplicatedSize] = useState(false); const { rows, totalRowCount } = useMemo(() => { - let jobsToCompare = jobs; + let result; if (useDuplicatedSize) { - jobsToCompare = webpack.factorDuplicateSizeIntoModules(jobs) + result = webpack.compareModuleDuplicateSize(jobs, [addRowFlags]); + } else { + result = webpack.compareBySection.modules(jobs, [addRowFlags]); } - const result = webpack.compareBySection.modules(jobsToCompare, [addRowFlags]); return { rows: result, totalRowCount: result.length }; }, [jobs, useDuplicatedSize]); diff --git a/packages/utils/src/webpack/compare.js b/packages/utils/src/webpack/compare.js index 2f43781b6d..b6676effd1 100644 --- a/packages/utils/src/webpack/compare.js +++ b/packages/utils/src/webpack/compare.js @@ -8,7 +8,7 @@ import { SECTION_WEBPACK_PACKAGES, SECTIONS, } from './constants'; -import { selectors } from './selectors'; +import { selectors, getModuleDuplicateSize } from './selectors'; /** * Compare stats metrics @@ -53,6 +53,16 @@ const compareAssets = (jobs, rowTransformers) => const compareModules = (jobs, rowTransformers) => compareMetrics(jobs, selectors.modules, MetricTypes.FileSize, rowTransformers); +/** + * Compare module size including duplicates + * + * @param {Object[]} jobs - List of jobs to compare + * @param {Array} [rowTransformers] + * @return {Object[]} Compared module metrics + */ +export const compareModuleDuplicateSize = (jobs, rowTransformers) => + compareMetrics(jobs, getModuleDuplicateSize, MetricTypes.FileSize, rowTransformers); + /** * Compare package metrics * @@ -86,26 +96,3 @@ export const compare = (jobs) => }), {}, ); - -/** - * Augment the modules data in jobs to count the bytes from each duplicate - */ -export const factorDuplicateSizeIntoModules = (jobs) => - jobs.map((job) => ({ - ...job, - metrics: { - ...job.metrics, - webpack: { - ...job.metrics.webpack, - modules: Object.keys(job.metrics.webpack.modules).reduce((modulesWithDupes, key) => { - const module = job.metrics.webpack.modules[key]; - // eslint-disable-next-line no-param-reassign - modulesWithDupes[key] = { - ...module, - value: module.value * module.chunkIds.length, - }; - return modulesWithDupes; - }, {}), - }, - }, - })) diff --git a/packages/utils/src/webpack/selectors.js b/packages/utils/src/webpack/selectors.js index 789520361e..1eae3fb958 100644 --- a/packages/utils/src/webpack/selectors.js +++ b/packages/utils/src/webpack/selectors.js @@ -26,10 +26,13 @@ const getStatsMetrics = (job) => { const metrics = pick(data, SUMMARY_METRIC_PATHS); // Rename metric keys - return Object.entries(metrics).reduce((agg, [key, value]) => ({ - ...agg, - [`webpack.${key}`]: value, - }), {}); + return Object.entries(metrics).reduce( + (agg, [key, value]) => ({ + ...agg, + [`webpack.${key}`]: value, + }), + {}, + ); }; /** @@ -47,10 +50,13 @@ const getSizeMetrics = (job) => { const metrics = get(job, 'metrics.webpack.sizes', {}); // List metrics by the metrics list - return Object.keys(metricTypes.sizes).reduce((agg, key) => ({ - ...agg, - [`webpack.sizes.${key}`]: metrics[key], - }), {}); + return Object.keys(metricTypes.sizes).reduce( + (agg, key) => ({ + ...agg, + [`webpack.sizes.${key}`]: metrics[key], + }), + {}, + ); }; /** @@ -79,6 +85,30 @@ const getAssetsMetrics = (job) => get(job, 'metrics.webpack.assets', {}); */ const getModulesMetrics = (job) => get(job, 'metrics.webpack.modules', {}); +/** + * + * Select webpack module size including duplication + * + * @param {Object} job Job data + * @param {Object} job.metrics Job metrics + * @param {Object} job.metrics.webpack Job webpack metrics + * @param {Object} job.metrics.webpack.modules Job webpack module metrics + * + * @return {Object} Webpack module metrics + */ +export const getModuleDuplicateSize = (job) => { + const modules = get(job, 'metrics.webpack.modules', {}); + return Object.keys(modules).reduce((modulesWithDupes, key) => { + const module = modules[key]; + // eslint-disable-next-line no-param-reassign + modulesWithDupes[key] = { + ...module, + value: module.value * module.chunkIds.length, + }; + return modulesWithDupes; + }, {}); +}; + /** * * Get package metrics