@bundle-stats/ui 4.3.0-beta.1 → 4.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app/app.js +4 -5
- package/lib/app/app.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.js +1 -2
- package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.module.css +4 -0
- package/lib/components/duplicate-packages-insight/duplicate-packages-insight.js +31 -0
- package/lib/components/duplicate-packages-insight/duplicate-packages-insight.js.map +1 -0
- package/lib/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
- package/lib/components/{duplicate-packages-warning → duplicate-packages-insight}/index.js +1 -1
- package/lib/components/duplicate-packages-insight/index.js.map +1 -0
- package/lib/components/index.js +3 -3
- package/lib/components/job-header/job-header.js +1 -1
- package/lib/components/job-header/job-header.js.map +1 -1
- package/lib/components/module-info/module-info.js +24 -16
- package/lib/components/module-info/module-info.js.map +1 -1
- package/lib/components/module-info/module-info.module.css +27 -8
- package/lib-esm/app/app.js +5 -5
- package/lib-esm/app/app.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.js +1 -2
- package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.module.css +4 -0
- package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.js +24 -0
- package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.js.map +1 -0
- package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
- package/lib-esm/components/duplicate-packages-insight/index.js +2 -0
- package/lib-esm/components/duplicate-packages-insight/index.js.map +1 -0
- package/lib-esm/components/index.js +1 -1
- package/lib-esm/components/job-header/job-header.js +2 -2
- package/lib-esm/components/job-header/job-header.js.map +1 -1
- package/lib-esm/components/module-info/module-info.js +25 -17
- package/lib-esm/components/module-info/module-info.js.map +1 -1
- package/lib-esm/components/module-info/module-info.module.css +27 -8
- package/package.json +7 -7
- package/src/app/app.jsx +7 -8
- package/src/components/bundle-modules/bundle-modules.jsx +11 -9
- package/src/components/bundle-modules/bundle-modules.module.css +4 -0
- package/src/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
- package/src/components/duplicate-packages-insight/duplicate-packages-insight.stories.tsx +66 -0
- package/src/components/duplicate-packages-insight/duplicate-packages-insight.tsx +81 -0
- package/src/components/duplicate-packages-insight/index.ts +1 -0
- package/src/components/index.js +1 -1
- package/src/components/job-header/job-header.jsx +2 -2
- package/src/components/module-info/module-info.jsx +55 -25
- package/src/components/module-info/module-info.module.css +27 -8
- package/tsconfig.esm.json +1 -1
- package/tsconfig.lib.json +1 -1
- package/types/components/duplicate-packages-insight/duplicate-packages-insight.d.ts +11 -0
- package/types/components/duplicate-packages-insight/index.d.ts +1 -0
- package/types/components/index.d.ts +1 -1
- package/lib/components/duplicate-packages-warning/duplicate-packages-warning.js +0 -41
- package/lib/components/duplicate-packages-warning/duplicate-packages-warning.js.map +0 -1
- package/lib/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
- package/lib/components/duplicate-packages-warning/index.js.map +0 -1
- package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.js +0 -34
- package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.js.map +0 -1
- package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
- package/lib-esm/components/duplicate-packages-warning/index.js +0 -2
- package/lib-esm/components/duplicate-packages-warning/index.js.map +0 -1
- package/src/components/duplicate-packages-warning/duplicate-packages-warning.jsx +0 -60
- package/src/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
- package/src/components/duplicate-packages-warning/index.js +0 -1
- package/types/components/duplicate-packages-warning/duplicate-packages-warning.d.ts +0 -21
- package/types/components/duplicate-packages-warning/index.d.ts +0 -1
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import cx from 'classnames';
|
|
3
4
|
import isEmpty from 'lodash/isEmpty';
|
|
4
5
|
import noop from 'lodash/noop';
|
|
5
|
-
import { getBundleModulesByChunk } from '@bundle-stats/utils';
|
|
6
|
+
import { getBundleModulesByChunk, getBundleModulesBySearch } from '@bundle-stats/utils';
|
|
6
7
|
import { Stack } from '../../layout/stack';
|
|
8
|
+
import { FlexStack } from '../../layout/flex-stack';
|
|
7
9
|
import { FileName } from '../../ui/file-name';
|
|
10
|
+
import { Tag } from '../../ui/tag';
|
|
8
11
|
import { ComponentLink } from '../component-link';
|
|
9
12
|
import css from './module-info.module.css';
|
|
10
13
|
export const ModuleInfo = (props) => {
|
|
11
14
|
const { className, item, labels, chunks, chunkIds, customComponentLink: CustomComponentLink, onClick, } = props;
|
|
12
|
-
return (React.createElement(Stack, { space: "
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
return (React.createElement(Stack, { space: "small", className: cx(css.root, className) }, item.runs.map((run, index) => (React.createElement(Stack, { space: "xsmall", key: `module-info-${(run === null || run === void 0 ? void 0 : run.name) || index}-${index}`, className: css.run },
|
|
16
|
+
React.createElement(Stack, { space: "xxxsmall" },
|
|
17
|
+
React.createElement(FlexStack, { space: "xxxsmall", alignItems: "center", as: "h4", className: css.title },
|
|
18
|
+
React.createElement("span", null, labels[index]),
|
|
19
|
+
React.createElement(Tag, { className: css.titleTag }, index === 0 ? 'current' : 'baseline')),
|
|
20
|
+
React.createElement(FileName, { className: css.fileName, as: "code", name: (run === null || run === void 0 ? void 0 : run.name) || '-' })),
|
|
21
|
+
index === 0 && !isEmpty(run === null || run === void 0 ? void 0 : run.chunkIds) && (React.createElement(Stack, { className: css.chunks },
|
|
22
|
+
React.createElement("h5", null, "Chunks"),
|
|
23
|
+
React.createElement("ul", { className: css.list }, run.chunkIds.map((chunkId) => {
|
|
24
|
+
const chunk = chunks === null || chunks === void 0 ? void 0 : chunks.find(({ id }) => id === chunkId);
|
|
25
|
+
if (!chunk) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return (React.createElement("li", null,
|
|
29
|
+
React.createElement(CustomComponentLink, { ...getBundleModulesByChunk(chunkIds, chunkId), onClick: onClick, className: css.chunksItem }, chunk.name)));
|
|
30
|
+
})))),
|
|
31
|
+
(run === null || run === void 0 ? void 0 : run.reasons) && (React.createElement(Stack, null,
|
|
32
|
+
React.createElement("h5", null, "Reasons"),
|
|
33
|
+
React.createElement("ul", { className: css.list }, run.reasons.map((reason) => (React.createElement("li", { key: reason },
|
|
34
|
+
React.createElement(CustomComponentLink, { ...getBundleModulesBySearch(`^${reason}$`), onClick: onClick, className: css.reasonLink },
|
|
35
|
+
React.createElement(FileName, { name: reason, className: css.reason })))))))))))));
|
|
28
36
|
};
|
|
29
37
|
ModuleInfo.propTypes = {
|
|
30
38
|
className: PropTypes.string,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-info.js","sourceRoot":"","sources":["../../../src/components/module-info/module-info.jsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,OAAO,MAAM,gBAAgB,CAAC;AACrC,OAAO,IAAI,MAAM,aAAa,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"module-info.js","sourceRoot":"","sources":["../../../src/components/module-info/module-info.jsx"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,40 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
1
|
+
.titleTag {
|
|
2
|
+
border: 1px solid var(--color-outline);
|
|
3
|
+
background: var(--color-highlight);
|
|
4
|
+
color: var(--color-text-light);
|
|
3
5
|
}
|
|
4
6
|
|
|
5
|
-
.
|
|
6
|
-
|
|
7
|
+
.run:first-child .title {
|
|
8
|
+
font-size: var(--size-xlarge);
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
.chunksItem {
|
|
10
12
|
overflow-wrap: break-word;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
.chunksItem + .chunksItem {
|
|
14
|
-
margin-left: var(--space-xxxsmall);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
15
|
.fileName {
|
|
18
16
|
max-width: 100%;
|
|
19
17
|
padding: 2px;
|
|
20
18
|
background: var(--color-highlight-warning);
|
|
21
19
|
}
|
|
20
|
+
|
|
21
|
+
.reasonLink {
|
|
22
|
+
text-decoration: underline;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.reasonLink .reason {
|
|
26
|
+
text-decoration: inherit;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.reason {
|
|
30
|
+
display: inline;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.list {
|
|
34
|
+
padding: 0 0 0 var(--space-small);
|
|
35
|
+
list-style: outside;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.list li::marker {
|
|
39
|
+
color: var(--color-text-ultra-light);
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundle-stats/ui",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0-beta.0",
|
|
4
4
|
"description": "UI components for BundleStats projects.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-esm/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@storybook/react": "6.5.15",
|
|
52
52
|
"@types/react": "18.0.26",
|
|
53
53
|
"babel-plugin-require-context-hook": "1.0.0",
|
|
54
|
-
"chromatic": "6.
|
|
54
|
+
"chromatic": "6.15.0",
|
|
55
55
|
"classnames": "2.3.2",
|
|
56
56
|
"colormap": "2.3.2",
|
|
57
57
|
"cross-env": "7.0.3",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"enzyme-to-json": "3.6.2",
|
|
61
61
|
"hex-rgb": "5.0.0",
|
|
62
62
|
"identity-obj-proxy": "3.0.0",
|
|
63
|
-
"jest": "29.
|
|
63
|
+
"jest": "29.4.0",
|
|
64
64
|
"jest-date-mock": "1.0.8",
|
|
65
|
-
"jest-environment-jsdom": "29.
|
|
65
|
+
"jest-environment-jsdom": "29.4.0",
|
|
66
66
|
"lodash": "4.17.21",
|
|
67
67
|
"postcss": "8.4.21",
|
|
68
68
|
"prop-types": "15.8.1",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"react-dom": "17.0.2",
|
|
71
71
|
"react-router-dom": "5.3.4",
|
|
72
72
|
"react-test-renderer": "18.2.0",
|
|
73
|
-
"rimraf": "4.1.
|
|
73
|
+
"rimraf": "4.1.2",
|
|
74
74
|
"typescript": "4.9.4"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
"react-router-dom": "^5.0.0"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@bundle-stats/utils": "^4.
|
|
85
|
+
"@bundle-stats/utils": "^4.4.0-beta.0",
|
|
86
86
|
"ariakit": "2.0.0-next.43",
|
|
87
87
|
"modern-css-reset": "1.4.0",
|
|
88
88
|
"query-string": "7.1.3",
|
|
89
89
|
"use-query-params": "2.1.2"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "e2c2b5a9b7bd31c07baad4f5fefa682d21470600"
|
|
92
92
|
}
|
package/src/app/app.jsx
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '../constants';
|
|
13
13
|
import { Box } from '../layout/box';
|
|
14
14
|
import { Container } from '../ui/container';
|
|
15
|
-
import {
|
|
15
|
+
import { DuplicatePackagesInsight } from '../components/duplicate-packages-insight';
|
|
16
16
|
import { Summary } from '../components/summary';
|
|
17
17
|
import { BundleAssets } from '../components/bundle-assets';
|
|
18
18
|
import { BundleAssetsTotalsChartBars } from '../components/bundle-assets-totals-chart-bars';
|
|
@@ -68,17 +68,16 @@ JobsProvider.propTypes = {
|
|
|
68
68
|
|
|
69
69
|
const OverviewContent = () => {
|
|
70
70
|
const { jobs } = useContext(JobsContext);
|
|
71
|
-
const
|
|
72
|
-
const duplicatePackagesInsights = Boolean(
|
|
73
|
-
duplicatePackagesCount.current || duplicatePackagesCount.baseline,
|
|
74
|
-
);
|
|
71
|
+
const duplicatePackagesInsight = jobs[0].insights?.webpack?.duplicatePackagesV3;
|
|
75
72
|
|
|
76
73
|
return (
|
|
77
74
|
<Stack space="medium">
|
|
78
|
-
{
|
|
75
|
+
{duplicatePackagesInsight && (
|
|
79
76
|
<Container>
|
|
80
|
-
<
|
|
81
|
-
|
|
77
|
+
<DuplicatePackagesInsight
|
|
78
|
+
type={duplicatePackagesInsight.type}
|
|
79
|
+
data={duplicatePackagesInsight.data}
|
|
80
|
+
summary={jobs[0].summary.webpack?.duplicatePackagesCount}
|
|
82
81
|
showDelta={jobs.length > 1}
|
|
83
82
|
/>
|
|
84
83
|
</Container>
|
|
@@ -107,15 +107,17 @@ const RowHeader = ({ row, chunks, labels, CustomComponentLink }) => {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
return (
|
|
110
|
-
<HoverCard label={content}>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
<HoverCard label={content} hoverCardClassName={css.nameHoverCard}>
|
|
111
|
+
{({ close }) => (
|
|
112
|
+
<ModuleInfo
|
|
113
|
+
item={row}
|
|
114
|
+
chunks={chunks}
|
|
115
|
+
chunkIds={chunkIds}
|
|
116
|
+
labels={labels}
|
|
117
|
+
customComponentLink={CustomComponentLink}
|
|
118
|
+
onClick={close}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
119
121
|
</HoverCard>
|
|
120
122
|
);
|
|
121
123
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.metric {
|
|
2
|
+
font-weight: bold;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.metric::before,
|
|
6
|
+
.link::before {
|
|
7
|
+
content: '\00A0\2014\00A0';
|
|
8
|
+
font-weight: normal;
|
|
9
|
+
color: var(--color-text-ultra-light);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.delta {
|
|
13
|
+
margin-left: var(--space-xxxsmall);
|
|
14
|
+
padding: 1px 2px;
|
|
15
|
+
vertical-align: super;
|
|
16
|
+
font-size: 9px;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
3
|
+
import { DuplicatePackagesInsight } from '.';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/DuplicatePackagesInsight',
|
|
7
|
+
component: DuplicatePackagesInsight,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Template = (props: any) => <MemoryRouter><DuplicatePackagesInsight {...props} /></MemoryRouter>;
|
|
11
|
+
|
|
12
|
+
export const Default = Template.bind({});
|
|
13
|
+
|
|
14
|
+
Default.args = {
|
|
15
|
+
type: 'INFO',
|
|
16
|
+
data: {
|
|
17
|
+
packages: {},
|
|
18
|
+
text: 'Bundle does not contain duplicate packages',
|
|
19
|
+
},
|
|
20
|
+
summary: {
|
|
21
|
+
current: 0,
|
|
22
|
+
baseline: 0,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const NewDuplicates = Template.bind({});
|
|
27
|
+
|
|
28
|
+
NewDuplicates.args = {
|
|
29
|
+
type: 'ERROR',
|
|
30
|
+
data: {
|
|
31
|
+
packages: {},
|
|
32
|
+
text: 'Bundle introduced 2 duplicate packages',
|
|
33
|
+
},
|
|
34
|
+
summary: {
|
|
35
|
+
current: 4,
|
|
36
|
+
baseline: 2,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const NewDuplicatesAndRemovals = Template.bind({});
|
|
41
|
+
|
|
42
|
+
NewDuplicatesAndRemovals.args = {
|
|
43
|
+
type: 'ERROR',
|
|
44
|
+
data: {
|
|
45
|
+
packages: {},
|
|
46
|
+
text: 'Bundle introduced 2 and removed 1 duplicate packages',
|
|
47
|
+
},
|
|
48
|
+
summary: {
|
|
49
|
+
current: 4,
|
|
50
|
+
baseline: 3,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const NoChangeDuplicates = Template.bind({});
|
|
55
|
+
|
|
56
|
+
NoChangeDuplicates.args = {
|
|
57
|
+
type: 'WARNING',
|
|
58
|
+
data: {
|
|
59
|
+
packages: {},
|
|
60
|
+
text: 'Bundle contains 4 duplicate packages',
|
|
61
|
+
},
|
|
62
|
+
summary: {
|
|
63
|
+
current: 4,
|
|
64
|
+
baseline: 4,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
BUNDLE_PACKAGES_DUPLICATE,
|
|
4
|
+
BUNDLE_PACKAGES_COUNT,
|
|
5
|
+
InsightType,
|
|
6
|
+
JobSummaryItem,
|
|
7
|
+
getMetricRunInfo,
|
|
8
|
+
JobInsightDuplicatePackagesV3Data,
|
|
9
|
+
getGlobalMetricType,
|
|
10
|
+
} from '@bundle-stats/utils';
|
|
11
|
+
|
|
12
|
+
import { Alert } from '../../ui/alert';
|
|
13
|
+
import { ComponentLink } from '../component-link';
|
|
14
|
+
import { Delta } from '../delta';
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
import css from './duplicate-packages-insight.module.css';
|
|
17
|
+
|
|
18
|
+
interface DuplicatePackagesInsightProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
19
|
+
type: InsightType;
|
|
20
|
+
data: JobInsightDuplicatePackagesV3Data;
|
|
21
|
+
summary: JobSummaryItem;
|
|
22
|
+
showDelta?: boolean;
|
|
23
|
+
customComponentLink?: React.FunctionComponent<React.HTMLAttributes<HTMLLinkElement>>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const AlertKindMap = new Map([
|
|
27
|
+
[InsightType.INFO, 'info'],
|
|
28
|
+
[InsightType.ERROR, 'danger'],
|
|
29
|
+
[InsightType.WARNING, 'warning'],
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
export const DuplicatePackagesInsight = (props: DuplicatePackagesInsightProps) => {
|
|
33
|
+
const {
|
|
34
|
+
type,
|
|
35
|
+
data,
|
|
36
|
+
summary,
|
|
37
|
+
showDelta = true,
|
|
38
|
+
customComponentLink: CustomComponentLink = ComponentLink,
|
|
39
|
+
...restProps
|
|
40
|
+
} = props;
|
|
41
|
+
|
|
42
|
+
const metric = getGlobalMetricType('webpack.duplicatePackageCount');
|
|
43
|
+
|
|
44
|
+
const metricRunInfo = getMetricRunInfo(
|
|
45
|
+
metric,
|
|
46
|
+
summary.current,
|
|
47
|
+
summary.baseline,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const hasDuplicatePackages = metricRunInfo.value > 0 || (metricRunInfo && (metricRunInfo.delta !== 0));
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Alert kind={AlertKindMap.get(type)} {...restProps}>
|
|
54
|
+
<span className={css.message}>{data.text}</span>
|
|
55
|
+
{hasDuplicatePackages && (
|
|
56
|
+
<span className={css.metric}>
|
|
57
|
+
{metricRunInfo.value}
|
|
58
|
+
{showDelta && typeof metricRunInfo.delta !== 'undefined' && (
|
|
59
|
+
<Delta
|
|
60
|
+
className={css.delta}
|
|
61
|
+
inverted
|
|
62
|
+
displayValue={metricRunInfo.displayDelta as string}
|
|
63
|
+
deltaType={metricRunInfo.deltaType as string}
|
|
64
|
+
/>
|
|
65
|
+
)}
|
|
66
|
+
</span>
|
|
67
|
+
)}
|
|
68
|
+
<span className={css.link}>
|
|
69
|
+
{hasDuplicatePackages ? (
|
|
70
|
+
<CustomComponentLink {...BUNDLE_PACKAGES_DUPLICATE as any}>
|
|
71
|
+
View duplicate packages
|
|
72
|
+
</CustomComponentLink>
|
|
73
|
+
) : (
|
|
74
|
+
<CustomComponentLink {...BUNDLE_PACKAGES_COUNT as any}>
|
|
75
|
+
View packages
|
|
76
|
+
</CustomComponentLink>
|
|
77
|
+
)}
|
|
78
|
+
</span>
|
|
79
|
+
</Alert>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './duplicate-packages-insight';
|
package/src/components/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export { BundleAssetsTotalsChartBars } from './bundle-assets-totals-chart-bars';
|
|
|
5
5
|
export { BundlePackages } from './bundle-packages';
|
|
6
6
|
export { BundleModules } from './bundle-modules';
|
|
7
7
|
export { ComponentLink } from './component-link';
|
|
8
|
-
export {
|
|
8
|
+
export { DuplicatePackagesInsight } from './duplicate-packages-insight';
|
|
9
9
|
export { Delta } from './delta';
|
|
10
10
|
export { JobName } from './job-name';
|
|
11
11
|
export { JobHeader } from './job-header';
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
|
-
import {
|
|
5
|
+
import { Source, formatDateTime } from '@bundle-stats/utils';
|
|
6
6
|
|
|
7
7
|
import { FlexStack } from '../../layout/flex-stack';
|
|
8
8
|
import { Stack } from '../../layout/stack';
|
|
@@ -13,7 +13,7 @@ import css from './job-header.module.css';
|
|
|
13
13
|
export const JobHeader = (props) => {
|
|
14
14
|
const { className, tag, job, children } = props;
|
|
15
15
|
|
|
16
|
-
const { builtAt, hash } = get(job, `meta.${
|
|
16
|
+
const { builtAt, hash } = get(job, `meta.${Source.webpack}`, {});
|
|
17
17
|
const rootClassName = cx(css.root, className);
|
|
18
18
|
|
|
19
19
|
return (
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import cx from 'classnames';
|
|
3
4
|
import isEmpty from 'lodash/isEmpty';
|
|
4
5
|
import noop from 'lodash/noop';
|
|
5
|
-
import { getBundleModulesByChunk } from '@bundle-stats/utils';
|
|
6
|
+
import { getBundleModulesByChunk, getBundleModulesBySearch } from '@bundle-stats/utils';
|
|
6
7
|
|
|
7
8
|
import { Stack } from '../../layout/stack';
|
|
9
|
+
import { FlexStack } from '../../layout/flex-stack';
|
|
8
10
|
import { FileName } from '../../ui/file-name';
|
|
11
|
+
import { Tag } from '../../ui/tag';
|
|
9
12
|
import { ComponentLink } from '../component-link';
|
|
10
13
|
import css from './module-info.module.css';
|
|
11
14
|
|
|
@@ -21,25 +24,34 @@ export const ModuleInfo = (props) => {
|
|
|
21
24
|
} = props;
|
|
22
25
|
|
|
23
26
|
return (
|
|
24
|
-
<Stack space="
|
|
25
|
-
{item.runs.map((run, index) =>
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
<Stack space="small" className={cx(css.root, className)}>
|
|
28
|
+
{item.runs.map((run, index) => (
|
|
29
|
+
<Stack space="xsmall" key={`module-info-${run?.name || index}-${index}`} className={css.run}>
|
|
30
|
+
<Stack space="xxxsmall">
|
|
31
|
+
<FlexStack space="xxxsmall" alignItems="center" as="h4" className={css.title}>
|
|
32
|
+
<span>{labels[index]}</span>
|
|
33
|
+
<Tag className={css.titleTag}>{index === 0 ? 'current' : 'baseline'}</Tag>
|
|
34
|
+
</FlexStack>
|
|
35
|
+
<FileName className={css.fileName} as="code" name={run?.name || '-'} />
|
|
36
|
+
</Stack>
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
{/**
|
|
39
|
+
* Render chunks only for the current run
|
|
40
|
+
* we do not have the correct chunk ids for baselines
|
|
41
|
+
*/}
|
|
42
|
+
{index === 0 && !isEmpty(run?.chunkIds) && (
|
|
43
|
+
<Stack className={css.chunks}>
|
|
44
|
+
<h5>Chunks</h5>
|
|
45
|
+
<ul className={css.list}>
|
|
46
|
+
{run.chunkIds.map((chunkId) => {
|
|
47
|
+
const chunk = chunks?.find(({ id }) => id === chunkId);
|
|
37
48
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
if (!chunk) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
return (
|
|
54
|
+
<li>
|
|
43
55
|
<CustomComponentLink
|
|
44
56
|
{...getBundleModulesByChunk(chunkIds, chunkId)}
|
|
45
57
|
onClick={onClick}
|
|
@@ -47,15 +59,33 @@ export const ModuleInfo = (props) => {
|
|
|
47
59
|
>
|
|
48
60
|
{chunk.name}
|
|
49
61
|
</CustomComponentLink>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
</li>
|
|
63
|
+
);
|
|
64
|
+
})}
|
|
65
|
+
</ul>
|
|
66
|
+
</Stack>
|
|
67
|
+
)}
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
{run?.reasons && (
|
|
70
|
+
<Stack>
|
|
71
|
+
<h5>Reasons</h5>
|
|
72
|
+
<ul className={css.list}>
|
|
73
|
+
{run.reasons.map((reason) => (
|
|
74
|
+
<li key={reason}>
|
|
75
|
+
<CustomComponentLink
|
|
76
|
+
{...getBundleModulesBySearch(`^${reason}$`)}
|
|
77
|
+
onClick={onClick}
|
|
78
|
+
className={css.reasonLink}
|
|
79
|
+
>
|
|
80
|
+
<FileName name={reason} className={css.reason} />
|
|
81
|
+
</CustomComponentLink>
|
|
82
|
+
</li>
|
|
83
|
+
))}
|
|
84
|
+
</ul>
|
|
85
|
+
</Stack>
|
|
86
|
+
)}
|
|
87
|
+
</Stack>
|
|
88
|
+
))}
|
|
59
89
|
</Stack>
|
|
60
90
|
);
|
|
61
91
|
};
|
|
@@ -1,21 +1,40 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
1
|
+
.titleTag {
|
|
2
|
+
border: 1px solid var(--color-outline);
|
|
3
|
+
background: var(--color-highlight);
|
|
4
|
+
color: var(--color-text-light);
|
|
3
5
|
}
|
|
4
6
|
|
|
5
|
-
.
|
|
6
|
-
|
|
7
|
+
.run:first-child .title {
|
|
8
|
+
font-size: var(--size-xlarge);
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
.chunksItem {
|
|
10
12
|
overflow-wrap: break-word;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
.chunksItem + .chunksItem {
|
|
14
|
-
margin-left: var(--space-xxxsmall);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
15
|
.fileName {
|
|
18
16
|
max-width: 100%;
|
|
19
17
|
padding: 2px;
|
|
20
18
|
background: var(--color-highlight-warning);
|
|
21
19
|
}
|
|
20
|
+
|
|
21
|
+
.reasonLink {
|
|
22
|
+
text-decoration: underline;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.reasonLink .reason {
|
|
26
|
+
text-decoration: inherit;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.reason {
|
|
30
|
+
display: inline;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.list {
|
|
34
|
+
padding: 0 0 0 var(--space-small);
|
|
35
|
+
list-style: outside;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.list li::marker {
|
|
39
|
+
color: var(--color-text-ultra-light);
|
|
40
|
+
}
|
package/tsconfig.esm.json
CHANGED
package/tsconfig.lib.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InsightType, JobSummaryItem, JobInsightDuplicatePackagesV3Data } from '@bundle-stats/utils';
|
|
3
|
+
interface DuplicatePackagesInsightProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
type: InsightType;
|
|
5
|
+
data: JobInsightDuplicatePackagesV3Data;
|
|
6
|
+
summary: JobSummaryItem;
|
|
7
|
+
showDelta?: boolean;
|
|
8
|
+
customComponentLink?: React.FunctionComponent<React.HTMLAttributes<HTMLLinkElement>>;
|
|
9
|
+
}
|
|
10
|
+
export declare const DuplicatePackagesInsight: (props: DuplicatePackagesInsightProps) => JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './duplicate-packages-insight';
|
|
@@ -5,7 +5,7 @@ export { BundleAssetsTotalsChartBars } from "./bundle-assets-totals-chart-bars";
|
|
|
5
5
|
export { BundlePackages } from "./bundle-packages";
|
|
6
6
|
export { BundleModules } from "./bundle-modules";
|
|
7
7
|
export { ComponentLink } from "./component-link";
|
|
8
|
-
export {
|
|
8
|
+
export { DuplicatePackagesInsight } from "./duplicate-packages-insight";
|
|
9
9
|
export { Delta } from "./delta";
|
|
10
10
|
export { JobName } from "./job-name";
|
|
11
11
|
export { JobHeader } from "./job-header";
|