Skip to content

Commit

Permalink
Merge pull request #4069 from iFixit/duplicate-true-sizes
Browse files Browse the repository at this point in the history
Duplicate Modules: Add option to include their bytes
  • Loading branch information
vio authored Feb 20, 2024
2 parents 4b282d2 + e23d926 commit c86e729
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum ModuleMetric {
SIZE = 'value',
TOTAL_SIZE = 'totalSize',
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
margin-right: -1px; /** collapse border */
}

.metricSelector {
border-bottom: 1px solid var(--color-outline);
}

.nameTagDuplicated {
margin-right: var(--space-xxxsmall);
vertical-align: baseline;
Expand Down
31 changes: 31 additions & 0 deletions packages/ui/src/components/bundle-modules/bundle-modules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ import { MetricsTableOptions } from '../metrics-table-options';
import { MetricsTableTitle } from '../metrics-table-title';
import { ModuleInfo } from '../module-info';
import { generateFilterFieldsData } from './bundle-modules.utils';
import { ModuleMetric } from './bundle-modules.constants';
import type { Chunk, Job, ReportMetricModuleRow } from './bundle-modules.types';
import * as I18N_MODULES from './bundle-modules.i18n';
import css from './bundle-modules.module.css';
import { Box } from '../../layout';
import { Button } from '../../ui';
import { Tooltip } from '../../ui/tooltip';

interface RowHeaderProps {
row: ReportMetricModuleRow;
Expand Down Expand Up @@ -68,6 +72,9 @@ interface BundleModulesProps extends React.ComponentProps<'div'> {
entryId?: string;
hideEntryInfo: () => void;

moduleMetric: ModuleMetric;
setModuleMetric: (newValue: ModuleMetric) => void;

customComponentLink: React.ElementType;
}

Expand All @@ -89,6 +96,8 @@ export const BundleModules = (props: BundleModulesProps) => {
updateSearch,
entryId,
hideEntryInfo,
moduleMetric,
setModuleMetric,
customComponentLink: CustomComponentLink = ComponentLink,
} = props;

Expand Down Expand Up @@ -172,6 +181,28 @@ export const BundleModules = (props: BundleModulesProps) => {
/>
</FlexStack>
</Toolbar>
<Box padding={['xsmall', 'small']} className={css.metricSelector}>
<FlexStack space="xxsmall" as="nav">
<Button
outline
kind={moduleMetric === ModuleMetric.SIZE ? 'primary' : 'default'}
size="small"
type="button"
onClick={() => setModuleMetric(ModuleMetric.SIZE)}
>
<Tooltip title="Size (excluding duplicate modules)">Module size</Tooltip>
</Button>
<Button
outline
kind={moduleMetric === ModuleMetric.TOTAL_SIZE ? 'primary' : 'default'}
size="small"
type="button"
onClick={() => setModuleMetric(ModuleMetric.TOTAL_SIZE)}
>
<Tooltip title="Size (including duplicate modules)">Module total size</Tooltip>
</Button>
</FlexStack>
</Box>
<MetricsTable
className={css.table}
items={items}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type ReportMetricModuleRow = {
} & ReportMetricRun &
Module;

interface Job {
export interface Job {
label: string;
internalBuildNumber: number;
meta?: {
Expand Down
16 changes: 13 additions & 3 deletions packages/ui/src/components/bundle-modules/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
// @ts-ignore
import * as webpack from '@bundle-stats/utils/lib-esm/webpack';

Expand All @@ -14,6 +14,7 @@ import {
generateFilters,
getCustomSort,
} from './bundle-modules.utils';
import { ModuleMetric } from './bundle-modules.constants';
import * as types from './bundle-modules.types';

interface BundleModulesProps
Expand Down Expand Up @@ -46,6 +47,8 @@ interface BundleModulesProps
export const BundleModules = (props: BundleModulesProps) => {
const { jobs, filters, search, setState, sortBy, direction, ...restProps } = props;

const [moduleMetric, setModuleMetric] = useState<ModuleMetric>(ModuleMetric.SIZE);

const { chunks, chunkIds } = useMemo(() => extractChunkData(jobs), [jobs]);

const { defaultFilters, allEntriesFilters } = useMemo(
Expand All @@ -62,12 +65,17 @@ export const BundleModules = (props: BundleModulesProps) => {
});

const { rows, totalRowCount } = useMemo(() => {
const result = webpack.compareBySection.modules(jobs, [addRowFlags]);
let result;
if (moduleMetric === ModuleMetric.TOTAL_SIZE) {
result = webpack.compareModuleDuplicateSize(jobs, [addRowFlags]);
} else if (moduleMetric === ModuleMetric.SIZE) {
result = webpack.compareBySection.modules(jobs, [addRowFlags]);
}
return {
rows: result as Array<types.ReportMetricModuleRow>,
totalRowCount: result.length,
};
}, [jobs]);
}, [jobs, moduleMetric]);

const filteredRows = useRowsFilter({
rows,
Expand Down Expand Up @@ -97,6 +105,8 @@ export const BundleModules = (props: BundleModulesProps) => {
allItems={rows}
totalRowCount={totalRowCount}
hideEntryInfo={hideEntryInfo}
moduleMetric={moduleMetric}
setModuleMetric={setModuleMetric}
/>
);
};
41 changes: 22 additions & 19 deletions packages/ui/src/components/module-info/module-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export const ModuleInfo = (props: ModuleInfoProps & React.ComponentProps<'div'>)
} = props;

const rootClassName = cx(css.root, className);
const currentRun = item.runs?.[0];

const tags = useMemo(() => {
if (!item.duplicated) {
Expand All @@ -73,26 +72,30 @@ export const ModuleInfo = (props: ModuleInfoProps & React.ComponentProps<'div'>)
return (
<EntryInfo item={item} labels={labels} tags={tags} onClose={onClose} className={rootClassName}>
<Stack space="xxxsmall">
{!isEmpty(currentRun?.chunkIds) && (
<EntryInfo.Meta label="Chunks" className={css.chunks}>
{currentRun.chunkIds.map((chunkId) => {
const chunk = chunks?.find(({ id }) => id === chunkId);
{item.runs?.map(
(currentRun, index) =>
!isEmpty(currentRun?.chunkIds) && (
<EntryInfo.Meta label="Chunks" className={css.chunks}>
Job #{index + 1}:
{currentRun.chunkIds.map((chunkId) => {
const chunk = chunks?.find(({ id }) => id === chunkId);

if (!chunk) {
return null;
}
if (!chunk) {
return null;
}

return (
<EntryInfoMetaLink
as={CustomComponentLink}
{...getBundleModulesByChunk(chunkIds, chunkId)}
className={css.chunksItem}
>
{chunk.name}
</EntryInfoMetaLink>
);
})}
</EntryInfo.Meta>
return (
<EntryInfoMetaLink
as={CustomComponentLink}
{...getBundleModulesByChunk(chunkIds, chunkId)}
className={css.chunksItem}
>
{chunk.name}
</EntryInfoMetaLink>
);
})}
</EntryInfo.Meta>
),
)}

{item?.fileType && (
Expand Down
7 changes: 6 additions & 1 deletion packages/utils/src/webpack/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SECTION_WEBPACK_PACKAGES,
SECTIONS,
} from './constants';
import { selectors } from './selectors';
import { selectors, getModuleDuplicateSize } from './selectors';

const compareStats = (jobs: Array<unknown>, rowTransformers?: Array<MetricReportRowTransformFn>) =>
compareMetrics(jobs, selectors.stats, undefined, rowTransformers);
Expand All @@ -25,6 +25,11 @@ const compareModules = (
rowTransformers?: Array<MetricReportRowTransformFn>,
) => compareMetrics(jobs, selectors.modules, MetricTypes.FileSize, rowTransformers);

export const compareModuleDuplicateSize = (
jobs: Array<unknown>,
rowTransformers?: Array<MetricReportRowTransformFn>,
) => compareMetrics(jobs, getModuleDuplicateSize, MetricTypes.FileSize, rowTransformers);

const comparePackages = (
jobs: Array<unknown>,
rowTransformers?: Array<MetricReportRowTransformFn>,
Expand Down
24 changes: 24 additions & 0 deletions packages/utils/src/webpack/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,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
Expand Down

0 comments on commit c86e729

Please sign in to comment.