@bundle-stats/ui 3.4.0-alpha.1 → 3.4.0-alpha.5
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/CHANGELOG.md +0 -29
- package/lib/app/app.js +3 -1
- package/lib/app/header/header.js +2 -1
- package/lib/components/bundle-assets/bundle-assets.js +2 -1
- package/lib/components/bundle-modules/bundle-modules.js +18 -4
- package/lib/components/bundle-modules/bundle-modules.module.css +11 -2
- package/lib/components/bundle-modules/bundle-modules.utils.js +14 -10
- package/lib/components/bundle-modules/index.js +4 -4
- package/lib/constants.js +1 -1
- package/lib-esm/app/app.js +3 -1
- package/lib-esm/app/header/header.js +2 -1
- package/lib-esm/components/bundle-assets/bundle-assets.js +2 -1
- package/lib-esm/components/bundle-modules/bundle-modules.js +17 -3
- package/lib-esm/components/bundle-modules/bundle-modules.module.css +11 -2
- package/lib-esm/components/bundle-modules/bundle-modules.utils.js +14 -6
- package/lib-esm/components/bundle-modules/index.js +5 -3
- package/lib-esm/constants.js +1 -1
- package/package.json +13 -13
- package/src/app/app.jsx +2 -2
- package/src/app/header/header.jsx +1 -1
- package/src/components/bundle-assets/bundle-assets.jsx +1 -1
- package/src/components/bundle-modules/bundle-modules.jsx +18 -1
- package/src/components/bundle-modules/bundle-modules.module.css +11 -2
- package/src/components/bundle-modules/bundle-modules.utils.js +16 -4
- package/src/components/bundle-modules/index.jsx +3 -0
- package/src/constants.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,35 +3,6 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
# [3.4.0-alpha.0](https://github.com/relative-ci/bundle-stats/compare/v3.2.9...v3.4.0-alpha.0) (2022-03-12)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### Bug Fixes
|
|
10
|
-
|
|
11
|
-
* **ui:** Alert - allow to override props ([c9f85cd](https://github.com/relative-ci/bundle-stats/commit/c9f85cde563291da7de47f7c5ddaa7f2caa1d674))
|
|
12
|
-
* **ui:** Summary - pass budget data to SummaryItem ([9023a19](https://github.com/relative-ci/bundle-stats/commit/9023a19d164cf8e5c6b7c23d086b689c938c67c8))
|
|
13
|
-
* **utils:** Budgets - take biggerIsBetter in consideration ([b95b956](https://github.com/relative-ci/bundle-stats/commit/b95b95637a47cc266d4e4c254cb49f1a4f19794c))
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### Features
|
|
17
|
-
|
|
18
|
-
* App - add BudgetInsights ([84a6698](https://github.com/relative-ci/bundle-stats/commit/84a669806f25a1f164055ab1cbca39dc1e19987a))
|
|
19
|
-
* **ui:** App - pass budgets info to Summary ([d665805](https://github.com/relative-ci/bundle-stats/commit/d665805298e26d9771c017c0bddacc80dcc19f87))
|
|
20
|
-
* **ui:** BudgetInsights component ([f097f38](https://github.com/relative-ci/bundle-stats/commit/f097f388147910b6abb69fc3398d04796102aad1))
|
|
21
|
-
* **ui:** BundleAssetsTotalsTable - add budgets ([1a45ce8](https://github.com/relative-ci/bundle-stats/commit/1a45ce8a63f411b95a2a9092a13d45925e692062))
|
|
22
|
-
* **ui:** Icon - add check-circle icon ([8ce4c40](https://github.com/relative-ci/bundle-stats/commit/8ce4c40d92759d1a898c2311026d52d311520451))
|
|
23
|
-
* **ui:** Icon - alert-circle icon ([c571e57](https://github.com/relative-ci/bundle-stats/commit/c571e57405b4533cf55067f7ba71b944552579a5))
|
|
24
|
-
* **ui:** SummaryItem - budgets ([105ed0e](https://github.com/relative-ci/bundle-stats/commit/105ed0ef693c0b26c44217189d2d3cb5c4547af5))
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### Performance Improvements
|
|
28
|
-
|
|
29
|
-
* **ui:** BundleAssetsTotalsTable - use memo / callback ([f027cbc](https://github.com/relative-ci/bundle-stats/commit/f027cbcb59ff3890b2bf6db6b95d23c7c898bc6b))
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
6
|
## [3.2.8](https://github.com/relative-ci/bundle-stats/compare/v3.2.7...v3.2.8) (2022-03-10)
|
|
36
7
|
|
|
37
8
|
**Note:** Version bump only for package @bundle-stats/ui
|
package/lib/app/app.js
CHANGED
|
@@ -109,6 +109,7 @@ var Layout = function Layout(_ref) {
|
|
|
109
109
|
|
|
110
110
|
Layout.propTypes = {
|
|
111
111
|
jobs: _propTypes["default"].arrayOf(_propTypes["default"].object),
|
|
112
|
+
// eslint-disable-line react/forbid-prop-types
|
|
112
113
|
version: _propTypes["default"].string
|
|
113
114
|
};
|
|
114
115
|
Layout.defaultProps = {
|
|
@@ -135,7 +136,8 @@ var JobsProvider = function JobsProvider(_ref2) {
|
|
|
135
136
|
};
|
|
136
137
|
|
|
137
138
|
JobsProvider.propTypes = {
|
|
138
|
-
jobs: _propTypes["default"].arrayOf(_propTypes["default"].object).isRequired
|
|
139
|
+
jobs: _propTypes["default"].arrayOf(_propTypes["default"].object).isRequired // eslint-disable-line react/forbid-prop-types
|
|
140
|
+
|
|
139
141
|
};
|
|
140
142
|
|
|
141
143
|
var OverviewContent = function OverviewContent() {
|
package/lib/app/header/header.js
CHANGED
|
@@ -36,7 +36,8 @@ var Header = function Header(_ref) {
|
|
|
36
36
|
exports.Header = Header;
|
|
37
37
|
Header.propTypes = {
|
|
38
38
|
className: _propTypes["default"].string,
|
|
39
|
-
jobs: _propTypes["default"].arrayOf(_propTypes["default"].object)
|
|
39
|
+
jobs: _propTypes["default"].arrayOf(_propTypes["default"].object) // eslint-disable-line react/forbid-prop-types
|
|
40
|
+
|
|
40
41
|
};
|
|
41
42
|
Header.defaultProps = {
|
|
42
43
|
className: '',
|
|
@@ -206,7 +206,8 @@ RowHeader.propTypes = {
|
|
|
206
206
|
isChunk: _propTypes["default"].bool,
|
|
207
207
|
isInitial: _propTypes["default"].bool,
|
|
208
208
|
isEntry: _propTypes["default"].bool,
|
|
209
|
-
runs: _propTypes["default"].arrayOf(_propTypes["default"].object)
|
|
209
|
+
runs: _propTypes["default"].arrayOf(_propTypes["default"].object) // eslint-disable-line react/forbid-prop-types
|
|
210
|
+
|
|
210
211
|
}).isRequired,
|
|
211
212
|
chunks: _propTypes["default"].arrayOf(_propTypes["default"].shape({
|
|
212
213
|
id: _propTypes["default"].string,
|
|
@@ -39,6 +39,8 @@ var _hoverCard = require("../../ui/hover-card");
|
|
|
39
39
|
|
|
40
40
|
var _sortDropdown = require("../../ui/sort-dropdown");
|
|
41
41
|
|
|
42
|
+
var _tag = require("../../ui/tag");
|
|
43
|
+
|
|
42
44
|
var _toolbar = require("../../ui/toolbar");
|
|
43
45
|
|
|
44
46
|
var _metricsTable = require("../metrics-table");
|
|
@@ -95,10 +97,17 @@ var RowHeader = function RowHeader(_ref) {
|
|
|
95
97
|
return setHoverCard(true);
|
|
96
98
|
}, [showHoverCard]);
|
|
97
99
|
var content = (0, _react.useMemo)(function () {
|
|
98
|
-
return /*#__PURE__*/_react["default"].createElement(
|
|
100
|
+
return /*#__PURE__*/_react["default"].createElement("span", {
|
|
101
|
+
className: _bundleModulesModule["default"].name
|
|
102
|
+
}, row.duplicated && /*#__PURE__*/_react["default"].createElement(_tag.Tag, {
|
|
103
|
+
className: _bundleModulesModule["default"].nameTagDuplicated,
|
|
104
|
+
size: "small",
|
|
105
|
+
kind: _tag.Tag.KINDS.DANGER
|
|
106
|
+
}), /*#__PURE__*/_react["default"].createElement(_fileName.FileName, {
|
|
107
|
+
className: _bundleModulesModule["default"].nameText,
|
|
99
108
|
name: row.label
|
|
100
|
-
});
|
|
101
|
-
}, [row
|
|
109
|
+
}));
|
|
110
|
+
}, [row]);
|
|
102
111
|
|
|
103
112
|
if (!showHoverCard) {
|
|
104
113
|
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
@@ -120,7 +129,8 @@ var RowHeader = function RowHeader(_ref) {
|
|
|
120
129
|
|
|
121
130
|
RowHeader.propTypes = {
|
|
122
131
|
row: _propTypes["default"].shape({
|
|
123
|
-
label: _propTypes["default"].string
|
|
132
|
+
label: _propTypes["default"].string,
|
|
133
|
+
duplicated: _propTypes["default"].bool
|
|
124
134
|
}).isRequired,
|
|
125
135
|
chunks: _propTypes["default"].arrayOf(_propTypes["default"].shape({
|
|
126
136
|
id: _propTypes["default"].string,
|
|
@@ -173,6 +183,10 @@ var BundleModules = function BundleModules(_ref2) {
|
|
|
173
183
|
label: 'Changed',
|
|
174
184
|
defaultValue: filters.changed,
|
|
175
185
|
disabled: jobs.length <= 1
|
|
186
|
+
}), _defineProperty(_objectSpread2, _utils.MODULE_FILTERS.DUPLICATED, {
|
|
187
|
+
label: 'Duplicate',
|
|
188
|
+
defaultValue: filters[_utils.MODULE_FILTERS.DUPLICATED],
|
|
189
|
+
disabled: jobs.length <= 1
|
|
176
190
|
}), _defineProperty(_objectSpread2, _utils.MODULE_SOURCE_TYPE, (_MODULE_SOURCE_TYPE = {
|
|
177
191
|
label: 'Source'
|
|
178
192
|
}, _defineProperty(_MODULE_SOURCE_TYPE, _utils.MODULE_FILTERS.FIRST_PARTY, {
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
margin-right: -1px; /** collapse border */
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.
|
|
16
|
-
|
|
15
|
+
.nameTagDuplicated {
|
|
16
|
+
margin-right: var(--space-xxxsmall);
|
|
17
|
+
vertical-align: baseline;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.nameTagDuplicated::before {
|
|
21
|
+
content: 'D';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.nameText {
|
|
25
|
+
vertical-align: middle;
|
|
17
26
|
}
|
|
@@ -41,18 +41,17 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
|
|
|
41
41
|
|
|
42
42
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
var addRowSourceFlag = function addRowSourceFlag(row) {
|
|
45
|
+
var key = row.key,
|
|
46
|
+
runs = row.runs; // @NOTE Assign instead destructuring for perf reasons
|
|
47
|
+
// eslint-disable-next-line no-param-reassign
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
row.thirdParty = Boolean(key.match(_webpack.MODULE_PATH_PACKAGES)); // eslint-disable-next-line no-param-reassign
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
thirdParty: thirdParty
|
|
55
|
-
});
|
|
51
|
+
row.duplicated = Boolean(runs.find(function (run) {
|
|
52
|
+
return (run === null || run === void 0 ? void 0 : run.duplicated) === true;
|
|
53
|
+
}));
|
|
54
|
+
return row;
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
exports.addRowSourceFlag = addRowSourceFlag;
|
|
@@ -82,6 +81,11 @@ var getRowFilter = function getRowFilter(filters) {
|
|
|
82
81
|
// Skip not changed rows
|
|
83
82
|
if (filters[_utils.MODULE_FILTERS.CHANGED] && !row.changed) {
|
|
84
83
|
return false;
|
|
84
|
+
} // Skip not duplicated rows
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
if (filters[_utils.MODULE_FILTERS.DUPLICATED] && !row.duplicated) {
|
|
88
|
+
return false;
|
|
85
89
|
} // Skip not matching source type
|
|
86
90
|
|
|
87
91
|
|
|
@@ -72,12 +72,12 @@ var BundleModules = function BundleModules(props) {
|
|
|
72
72
|
|
|
73
73
|
var _useMemo = (0, _react.useMemo)(function () {
|
|
74
74
|
return {
|
|
75
|
-
defaultFilters: _objectSpread(_objectSpread(_objectSpread({
|
|
75
|
+
defaultFilters: _objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
76
76
|
changed: (jobs === null || jobs === void 0 ? void 0 : jobs.length) > 1
|
|
77
|
-
}, (0, _utils.getModuleSourceTypeFilters)(true)), (0, _utils.getModuleChunkFilters)(chunkIds, true)), (0, _utils.getModuleFileTypeFilters)(true)),
|
|
78
|
-
allEntriesFilters: _objectSpread(_objectSpread(_objectSpread({
|
|
77
|
+
}, (0, _utils.getModuleSourceTypeFilters)(true)), (0, _utils.getModuleChunkFilters)(chunkIds, true)), (0, _utils.getModuleFileTypeFilters)(true)), {}, _defineProperty({}, _utils.MODULE_FILTERS.DUPLICATED, false)),
|
|
78
|
+
allEntriesFilters: _objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
79
79
|
changed: false
|
|
80
|
-
}, (0, _utils.getModuleSourceTypeFilters)(true)), (0, _utils.getModuleChunkFilters)(chunkIds, true)), (0, _utils.getModuleFileTypeFilters)(true))
|
|
80
|
+
}, (0, _utils.getModuleSourceTypeFilters)(true)), (0, _utils.getModuleChunkFilters)(chunkIds, true)), (0, _utils.getModuleFileTypeFilters)(true)), {}, _defineProperty({}, _utils.MODULE_FILTERS.DUPLICATED, false))
|
|
81
81
|
};
|
|
82
82
|
}, [jobs]),
|
|
83
83
|
defaultFilters = _useMemo.defaultFilters,
|
package/lib/constants.js
CHANGED
|
@@ -56,7 +56,7 @@ var METRICS_WEBPACK_GENERAL = ['totalSizeByTypeALL', 'totalInitialSizeJS', 'tota
|
|
|
56
56
|
exports.METRICS_WEBPACK_GENERAL = METRICS_WEBPACK_GENERAL;
|
|
57
57
|
var METRICS_WEBPACK_ASSETS = ['assetCount', 'chunkCount'];
|
|
58
58
|
exports.METRICS_WEBPACK_ASSETS = METRICS_WEBPACK_ASSETS;
|
|
59
|
-
var METRICS_WEBPACK_MODULES = ['moduleCount'];
|
|
59
|
+
var METRICS_WEBPACK_MODULES = ['moduleCount', 'duplicateModulesCount', 'duplicateCode'];
|
|
60
60
|
exports.METRICS_WEBPACK_MODULES = METRICS_WEBPACK_MODULES;
|
|
61
61
|
var METRICS_WEBPACK_PACKAGES = ['packageCount', 'duplicatePackagesCount'];
|
|
62
62
|
exports.METRICS_WEBPACK_PACKAGES = METRICS_WEBPACK_PACKAGES;
|
package/lib-esm/app/app.js
CHANGED
|
@@ -54,6 +54,7 @@ const Layout = _ref => {
|
|
|
54
54
|
|
|
55
55
|
Layout.propTypes = {
|
|
56
56
|
jobs: PropTypes.arrayOf(PropTypes.object),
|
|
57
|
+
// eslint-disable-line react/forbid-prop-types
|
|
57
58
|
version: PropTypes.string
|
|
58
59
|
};
|
|
59
60
|
Layout.defaultProps = {
|
|
@@ -78,7 +79,8 @@ const JobsProvider = _ref2 => {
|
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
JobsProvider.propTypes = {
|
|
81
|
-
jobs: PropTypes.arrayOf(PropTypes.object).isRequired
|
|
82
|
+
jobs: PropTypes.arrayOf(PropTypes.object).isRequired // eslint-disable-line react/forbid-prop-types
|
|
83
|
+
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
const OverviewContent = () => {
|
|
@@ -21,7 +21,8 @@ export const Header = _ref => {
|
|
|
21
21
|
};
|
|
22
22
|
Header.propTypes = {
|
|
23
23
|
className: PropTypes.string,
|
|
24
|
-
jobs: PropTypes.arrayOf(PropTypes.object)
|
|
24
|
+
jobs: PropTypes.arrayOf(PropTypes.object) // eslint-disable-line react/forbid-prop-types
|
|
25
|
+
|
|
25
26
|
};
|
|
26
27
|
Header.defaultProps = {
|
|
27
28
|
className: '',
|
|
@@ -145,7 +145,8 @@ RowHeader.propTypes = {
|
|
|
145
145
|
isChunk: PropTypes.bool,
|
|
146
146
|
isInitial: PropTypes.bool,
|
|
147
147
|
isEntry: PropTypes.bool,
|
|
148
|
-
runs: PropTypes.arrayOf(PropTypes.object)
|
|
148
|
+
runs: PropTypes.arrayOf(PropTypes.object) // eslint-disable-line react/forbid-prop-types
|
|
149
|
+
|
|
149
150
|
}).isRequired,
|
|
150
151
|
chunks: PropTypes.arrayOf(PropTypes.shape({
|
|
151
152
|
id: PropTypes.string,
|
|
@@ -17,6 +17,7 @@ import { FileName } from '../../ui/file-name';
|
|
|
17
17
|
import { Filters } from '../../ui/filters';
|
|
18
18
|
import { HoverCard } from '../../ui/hover-card';
|
|
19
19
|
import { SortDropdown } from '../../ui/sort-dropdown';
|
|
20
|
+
import { Tag } from '../../ui/tag';
|
|
20
21
|
import { Toolbar } from '../../ui/toolbar';
|
|
21
22
|
import { MetricsTable } from '../metrics-table';
|
|
22
23
|
import { MetricsTableSearch } from '../metrics-table-search';
|
|
@@ -37,9 +38,16 @@ const RowHeader = _ref => {
|
|
|
37
38
|
|
|
38
39
|
const [showHoverCard, setHoverCard] = useState(false);
|
|
39
40
|
const handleOnMouseEnter = useCallback(() => setHoverCard(true), [showHoverCard]);
|
|
40
|
-
const content = useMemo(() => /*#__PURE__*/React.createElement(
|
|
41
|
+
const content = useMemo(() => /*#__PURE__*/React.createElement("span", {
|
|
42
|
+
className: css.name
|
|
43
|
+
}, row.duplicated && /*#__PURE__*/React.createElement(Tag, {
|
|
44
|
+
className: css.nameTagDuplicated,
|
|
45
|
+
size: "small",
|
|
46
|
+
kind: Tag.KINDS.DANGER
|
|
47
|
+
}), /*#__PURE__*/React.createElement(FileName, {
|
|
48
|
+
className: css.nameText,
|
|
41
49
|
name: row.label
|
|
42
|
-
}), [row
|
|
50
|
+
})), [row]);
|
|
43
51
|
|
|
44
52
|
if (!showHoverCard) {
|
|
45
53
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -61,7 +69,8 @@ const RowHeader = _ref => {
|
|
|
61
69
|
|
|
62
70
|
RowHeader.propTypes = {
|
|
63
71
|
row: PropTypes.shape({
|
|
64
|
-
label: PropTypes.string
|
|
72
|
+
label: PropTypes.string,
|
|
73
|
+
duplicated: PropTypes.bool
|
|
65
74
|
}).isRequired,
|
|
66
75
|
chunks: PropTypes.arrayOf(PropTypes.shape({
|
|
67
76
|
id: PropTypes.string,
|
|
@@ -111,6 +120,11 @@ export const BundleModules = _ref2 => {
|
|
|
111
120
|
defaultValue: filters.changed,
|
|
112
121
|
disabled: jobs.length <= 1
|
|
113
122
|
},
|
|
123
|
+
[MODULE_FILTERS.DUPLICATED]: {
|
|
124
|
+
label: 'Duplicate',
|
|
125
|
+
defaultValue: filters[MODULE_FILTERS.DUPLICATED],
|
|
126
|
+
disabled: jobs.length <= 1
|
|
127
|
+
},
|
|
114
128
|
[MODULE_SOURCE_TYPE]: {
|
|
115
129
|
label: 'Source',
|
|
116
130
|
[MODULE_FILTERS.FIRST_PARTY]: {
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
margin-right: -1px; /** collapse border */
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.
|
|
16
|
-
|
|
15
|
+
.nameTagDuplicated {
|
|
16
|
+
margin-right: var(--space-xxxsmall);
|
|
17
|
+
vertical-align: baseline;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.nameTagDuplicated::before {
|
|
21
|
+
content: 'D';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.nameText {
|
|
25
|
+
vertical-align: middle;
|
|
17
26
|
}
|
|
@@ -7,12 +7,15 @@ import { MODULE_CHUNK, MODULE_FILTERS, MODULE_FILE_TYPE, MODULE_SOURCE_TYPE, get
|
|
|
7
7
|
import { SORT_BY_NAME, SORT_BY_SIZE, SORT_BY_DELTA } from './bundle-modules.constants';
|
|
8
8
|
export const addRowSourceFlag = row => {
|
|
9
9
|
const {
|
|
10
|
-
key
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
key,
|
|
11
|
+
runs
|
|
12
|
+
} = row; // @NOTE Assign instead destructuring for perf reasons
|
|
13
|
+
// eslint-disable-next-line no-param-reassign
|
|
14
|
+
|
|
15
|
+
row.thirdParty = Boolean(key.match(MODULE_PATH_PACKAGES)); // eslint-disable-next-line no-param-reassign
|
|
16
|
+
|
|
17
|
+
row.duplicated = Boolean(runs.find(run => (run == null ? void 0 : run.duplicated) === true));
|
|
18
|
+
return row;
|
|
16
19
|
};
|
|
17
20
|
export const getCustomSort = sortBy => item => {
|
|
18
21
|
if (sortBy === SORT_BY_NAME) {
|
|
@@ -33,6 +36,11 @@ export const getRowFilter = filters => row => {
|
|
|
33
36
|
// Skip not changed rows
|
|
34
37
|
if (filters[MODULE_FILTERS.CHANGED] && !row.changed) {
|
|
35
38
|
return false;
|
|
39
|
+
} // Skip not duplicated rows
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if (filters[MODULE_FILTERS.DUPLICATED] && !row.duplicated) {
|
|
43
|
+
return false;
|
|
36
44
|
} // Skip not matching source type
|
|
37
45
|
|
|
38
46
|
|
|
@@ -5,7 +5,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
|
|
|
5
5
|
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { getModuleChunkFilters, getModuleSourceTypeFilters, getModuleFileTypeFilters } from '@bundle-stats/utils';
|
|
8
|
+
import { MODULE_FILTERS, getModuleChunkFilters, getModuleSourceTypeFilters, getModuleFileTypeFilters } from '@bundle-stats/utils';
|
|
9
9
|
import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
|
|
10
10
|
import { useRowsFilter } from '../../hooks/rows-filter';
|
|
11
11
|
import { useRowsSort } from '../../hooks/rows-sort';
|
|
@@ -45,13 +45,15 @@ export const BundleModules = props => {
|
|
|
45
45
|
changed: (jobs == null ? void 0 : jobs.length) > 1,
|
|
46
46
|
...getModuleSourceTypeFilters(true),
|
|
47
47
|
...getModuleChunkFilters(chunkIds, true),
|
|
48
|
-
...getModuleFileTypeFilters(true)
|
|
48
|
+
...getModuleFileTypeFilters(true),
|
|
49
|
+
[MODULE_FILTERS.DUPLICATED]: false
|
|
49
50
|
},
|
|
50
51
|
allEntriesFilters: {
|
|
51
52
|
changed: false,
|
|
52
53
|
...getModuleSourceTypeFilters(true),
|
|
53
54
|
...getModuleChunkFilters(chunkIds, true),
|
|
54
|
-
...getModuleFileTypeFilters(true)
|
|
55
|
+
...getModuleFileTypeFilters(true),
|
|
56
|
+
[MODULE_FILTERS.DUPLICATED]: false
|
|
55
57
|
}
|
|
56
58
|
}), [jobs]);
|
|
57
59
|
const searchParams = useSearchParams({
|
package/lib-esm/constants.js
CHANGED
|
@@ -27,5 +27,5 @@ export const ASSETS_SIZES_FILE_TYPE_MAP = FILE_TYPES.reduce((agg, fileType) => (
|
|
|
27
27
|
}), {});
|
|
28
28
|
export const METRICS_WEBPACK_GENERAL = ['totalSizeByTypeALL', 'totalInitialSizeJS', 'totalInitialSizeCSS', 'cacheInvalidation'];
|
|
29
29
|
export const METRICS_WEBPACK_ASSETS = ['assetCount', 'chunkCount'];
|
|
30
|
-
export const METRICS_WEBPACK_MODULES = ['moduleCount'];
|
|
30
|
+
export const METRICS_WEBPACK_MODULES = ['moduleCount', 'duplicateModulesCount', 'duplicateCode'];
|
|
31
31
|
export const METRICS_WEBPACK_PACKAGES = ['packageCount', 'duplicatePackagesCount'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundle-stats/ui",
|
|
3
|
-
"version": "3.4.0-alpha.
|
|
3
|
+
"version": "3.4.0-alpha.5",
|
|
4
4
|
"description": "UI components for BundleStats projects.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-esm/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"homepage": "https://github.com/relative-ci/bundle-stats/blob/master/packages/ui#readme",
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@babel/cli": "7.17.6",
|
|
40
|
-
"@babel/core": "7.17.
|
|
40
|
+
"@babel/core": "7.17.7",
|
|
41
41
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
|
42
42
|
"@babel/preset-env": "7.16.11",
|
|
43
43
|
"@babel/preset-react": "7.16.7",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"babel-jest": "27.5.1",
|
|
55
55
|
"babel-plugin-lodash": "3.3.4",
|
|
56
56
|
"babel-plugin-require-context-hook": "1.0.0",
|
|
57
|
-
"chromatic": "6.5.
|
|
57
|
+
"chromatic": "6.5.3",
|
|
58
58
|
"classnames": "2.3.1",
|
|
59
59
|
"colormap": "2.3.2",
|
|
60
60
|
"core-js": "3.20.2",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"jest": "27.5.1",
|
|
68
68
|
"jest-date-mock": "1.0.8",
|
|
69
69
|
"lodash": "4.17.21",
|
|
70
|
-
"postcss": "8.4.
|
|
70
|
+
"postcss": "8.4.12",
|
|
71
71
|
"prop-types": "15.8.1",
|
|
72
72
|
"react": "16.14.0",
|
|
73
73
|
"react-dom": "16.14.0",
|
|
@@ -76,21 +76,21 @@
|
|
|
76
76
|
"rimraf": "3.0.2"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
|
-
"classnames": "2.
|
|
80
|
-
"core-js": "3.
|
|
81
|
-
"lodash": "4.
|
|
82
|
-
"prop-types": "15.
|
|
83
|
-
"react": "16.
|
|
84
|
-
"react-dom": "16.
|
|
85
|
-
"react-router-dom": "5.
|
|
79
|
+
"classnames": "^2.0.0",
|
|
80
|
+
"core-js": "^3.0.0",
|
|
81
|
+
"lodash": "^4.0.0",
|
|
82
|
+
"prop-types": "^15.0.0",
|
|
83
|
+
"react": "^16.0.0",
|
|
84
|
+
"react-dom": "^16.0.0",
|
|
85
|
+
"react-router-dom": "^5.0.0"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"@bundle-stats/utils": "^3.4.0-alpha.
|
|
88
|
+
"@bundle-stats/utils": "^3.4.0-alpha.5",
|
|
89
89
|
"ariakit": "2.0.0-alpha.19",
|
|
90
90
|
"date-fns": "2.28.0",
|
|
91
91
|
"modern-css-reset": "1.4.0",
|
|
92
92
|
"query-string": "7.1.1",
|
|
93
93
|
"use-query-params": "1.2.3"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "8cf4f784d15aed35e09a911a2fc9646a3fb9b06c"
|
|
96
96
|
}
|
package/src/app/app.jsx
CHANGED
|
@@ -48,7 +48,7 @@ const Layout = ({ jobs, version, ...props }) => (
|
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
Layout.propTypes = {
|
|
51
|
-
jobs: PropTypes.arrayOf(PropTypes.object),
|
|
51
|
+
jobs: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
|
|
52
52
|
version: PropTypes.string,
|
|
53
53
|
};
|
|
54
54
|
|
|
@@ -64,7 +64,7 @@ const JobsProvider = ({ jobs, ...restProps }) => {
|
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
JobsProvider.propTypes = {
|
|
67
|
-
jobs: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
67
|
+
jobs: PropTypes.arrayOf(PropTypes.object).isRequired, // eslint-disable-line react/forbid-prop-types
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
const OverviewContent = () => {
|
|
@@ -16,7 +16,7 @@ export const Header = ({ className, jobs }) => (
|
|
|
16
16
|
|
|
17
17
|
Header.propTypes = {
|
|
18
18
|
className: PropTypes.string,
|
|
19
|
-
jobs: PropTypes.arrayOf(PropTypes.object),
|
|
19
|
+
jobs: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
Header.defaultProps = {
|
|
@@ -146,7 +146,7 @@ RowHeader.propTypes = {
|
|
|
146
146
|
isChunk: PropTypes.bool,
|
|
147
147
|
isInitial: PropTypes.bool,
|
|
148
148
|
isEntry: PropTypes.bool,
|
|
149
|
-
runs: PropTypes.arrayOf(PropTypes.object),
|
|
149
|
+
runs: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
|
|
150
150
|
}).isRequired,
|
|
151
151
|
chunks: PropTypes.arrayOf(
|
|
152
152
|
PropTypes.shape({
|
|
@@ -20,6 +20,7 @@ import { FileName } from '../../ui/file-name';
|
|
|
20
20
|
import { Filters } from '../../ui/filters';
|
|
21
21
|
import { HoverCard } from '../../ui/hover-card';
|
|
22
22
|
import { SortDropdown } from '../../ui/sort-dropdown';
|
|
23
|
+
import { Tag } from '../../ui/tag';
|
|
23
24
|
import { Toolbar } from '../../ui/toolbar';
|
|
24
25
|
import { MetricsTable } from '../metrics-table';
|
|
25
26
|
import { MetricsTableSearch } from '../metrics-table-search';
|
|
@@ -33,7 +34,17 @@ const RowHeader = ({ row, chunks, labels, CustomComponentLink }) => {
|
|
|
33
34
|
|
|
34
35
|
const [showHoverCard, setHoverCard] = useState(false);
|
|
35
36
|
const handleOnMouseEnter = useCallback(() => setHoverCard(true), [showHoverCard]);
|
|
36
|
-
const content = useMemo(
|
|
37
|
+
const content = useMemo(
|
|
38
|
+
() => (
|
|
39
|
+
<span className={css.name}>
|
|
40
|
+
{row.duplicated && (
|
|
41
|
+
<Tag className={css.nameTagDuplicated} size="small" kind={Tag.KINDS.DANGER} />
|
|
42
|
+
)}
|
|
43
|
+
<FileName className={css.nameText} name={row.label} />
|
|
44
|
+
</span>
|
|
45
|
+
),
|
|
46
|
+
[row],
|
|
47
|
+
);
|
|
37
48
|
|
|
38
49
|
if (!showHoverCard) {
|
|
39
50
|
return <div onMouseEnter={handleOnMouseEnter}>{content}</div>;
|
|
@@ -56,6 +67,7 @@ const RowHeader = ({ row, chunks, labels, CustomComponentLink }) => {
|
|
|
56
67
|
RowHeader.propTypes = {
|
|
57
68
|
row: PropTypes.shape({
|
|
58
69
|
label: PropTypes.string,
|
|
70
|
+
duplicated: PropTypes.bool,
|
|
59
71
|
}).isRequired,
|
|
60
72
|
chunks: PropTypes.arrayOf(
|
|
61
73
|
PropTypes.shape({
|
|
@@ -118,6 +130,11 @@ export const BundleModules = ({
|
|
|
118
130
|
defaultValue: filters.changed,
|
|
119
131
|
disabled: jobs.length <= 1,
|
|
120
132
|
},
|
|
133
|
+
[MODULE_FILTERS.DUPLICATED]: {
|
|
134
|
+
label: 'Duplicate',
|
|
135
|
+
defaultValue: filters[MODULE_FILTERS.DUPLICATED],
|
|
136
|
+
disabled: jobs.length <= 1,
|
|
137
|
+
},
|
|
121
138
|
[MODULE_SOURCE_TYPE]: {
|
|
122
139
|
label: 'Source',
|
|
123
140
|
[MODULE_FILTERS.FIRST_PARTY]: {
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
margin-right: -1px; /** collapse border */
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.
|
|
16
|
-
|
|
15
|
+
.nameTagDuplicated {
|
|
16
|
+
margin-right: var(--space-xxxsmall);
|
|
17
|
+
vertical-align: baseline;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.nameTagDuplicated::before {
|
|
21
|
+
content: 'D';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.nameText {
|
|
25
|
+
vertical-align: middle;
|
|
17
26
|
}
|
|
@@ -12,9 +12,15 @@ import {
|
|
|
12
12
|
import { SORT_BY_NAME, SORT_BY_SIZE, SORT_BY_DELTA } from './bundle-modules.constants';
|
|
13
13
|
|
|
14
14
|
export const addRowSourceFlag = (row) => {
|
|
15
|
-
const { key } = row;
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const { key, runs } = row;
|
|
16
|
+
|
|
17
|
+
// @NOTE Assign instead destructuring for perf reasons
|
|
18
|
+
// eslint-disable-next-line no-param-reassign
|
|
19
|
+
row.thirdParty = Boolean(key.match(MODULE_PATH_PACKAGES));
|
|
20
|
+
// eslint-disable-next-line no-param-reassign
|
|
21
|
+
row.duplicated = Boolean(runs.find((run) => run?.duplicated === true));
|
|
22
|
+
|
|
23
|
+
return row;
|
|
18
24
|
};
|
|
19
25
|
|
|
20
26
|
export const getCustomSort = (sortBy) => (item) => {
|
|
@@ -39,10 +45,16 @@ export const getRowFilter = (filters) => (row) => {
|
|
|
39
45
|
return false;
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
// Skip not duplicated rows
|
|
49
|
+
if (filters[MODULE_FILTERS.DUPLICATED] && !row.duplicated) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
// Skip not matching source type
|
|
43
54
|
if (
|
|
44
55
|
!(
|
|
45
|
-
(filters[`${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.FIRST_PARTY}`] &&
|
|
56
|
+
(filters[`${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.FIRST_PARTY}`] &&
|
|
57
|
+
row.thirdParty === false) ||
|
|
46
58
|
(filters[`${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.THIRD_PARTY}`] && row.thirdParty === true)
|
|
47
59
|
)
|
|
48
60
|
) {
|
|
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { uniqBy, map } from 'lodash';
|
|
4
4
|
import {
|
|
5
|
+
MODULE_FILTERS,
|
|
5
6
|
getModuleChunkFilters,
|
|
6
7
|
getModuleSourceTypeFilters,
|
|
7
8
|
getModuleFileTypeFilters,
|
|
@@ -33,12 +34,14 @@ export const BundleModules = (props) => {
|
|
|
33
34
|
...getModuleSourceTypeFilters(true),
|
|
34
35
|
...getModuleChunkFilters(chunkIds, true),
|
|
35
36
|
...getModuleFileTypeFilters(true),
|
|
37
|
+
[MODULE_FILTERS.DUPLICATED]: false,
|
|
36
38
|
},
|
|
37
39
|
allEntriesFilters: {
|
|
38
40
|
changed: false,
|
|
39
41
|
...getModuleSourceTypeFilters(true),
|
|
40
42
|
...getModuleChunkFilters(chunkIds, true),
|
|
41
43
|
...getModuleFileTypeFilters(true),
|
|
44
|
+
[MODULE_FILTERS.DUPLICATED]: false,
|
|
42
45
|
},
|
|
43
46
|
}),
|
|
44
47
|
[jobs],
|
package/src/constants.js
CHANGED
|
@@ -53,5 +53,5 @@ export const METRICS_WEBPACK_GENERAL = [
|
|
|
53
53
|
'cacheInvalidation',
|
|
54
54
|
];
|
|
55
55
|
export const METRICS_WEBPACK_ASSETS = ['assetCount', 'chunkCount'];
|
|
56
|
-
export const METRICS_WEBPACK_MODULES = ['moduleCount'];
|
|
56
|
+
export const METRICS_WEBPACK_MODULES = ['moduleCount', 'duplicateModulesCount', 'duplicateCode'];
|
|
57
57
|
export const METRICS_WEBPACK_PACKAGES = ['packageCount', 'duplicatePackagesCount'];
|