@bundle-stats/utils 4.4.0-beta.1 → 4.4.0-beta.3

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.
Files changed (72) hide show
  1. package/lib/config/component-links.js +5 -1
  2. package/lib/config/component-links.js.map +1 -1
  3. package/lib/config/file-types.js +3 -3
  4. package/lib/config/file-types.js.map +1 -1
  5. package/lib/config/metrics.js.map +1 -1
  6. package/lib/constants.js +5 -5
  7. package/lib/constants.js.map +1 -1
  8. package/lib/i18n.js +5 -0
  9. package/lib/i18n.js.map +1 -1
  10. package/lib/utils/component-links.js +78 -14
  11. package/lib/utils/component-links.js.map +1 -1
  12. package/lib/utils/index.js +1 -0
  13. package/lib/utils/index.js.map +1 -1
  14. package/lib/utils/insights.js +54 -0
  15. package/lib/utils/insights.js.map +1 -0
  16. package/lib/webpack/extract/modules-packages-duplicate.js +21 -9
  17. package/lib/webpack/extract/modules-packages-duplicate.js.map +1 -1
  18. package/lib/webpack/extract/modules.js +45 -22
  19. package/lib/webpack/extract/modules.js.map +1 -1
  20. package/lib/webpack/metrics.js +5 -5
  21. package/lib/webpack/metrics.js.map +1 -1
  22. package/lib/webpack/types.js +1 -1
  23. package/lib/webpack/types.js.map +1 -1
  24. package/lib-esm/config/component-links.js +4 -0
  25. package/lib-esm/config/component-links.js.map +1 -1
  26. package/lib-esm/config/file-types.js +3 -3
  27. package/lib-esm/config/file-types.js.map +1 -1
  28. package/lib-esm/config/metrics.js +1 -1
  29. package/lib-esm/config/metrics.js.map +1 -1
  30. package/lib-esm/i18n.js +5 -0
  31. package/lib-esm/i18n.js.map +1 -1
  32. package/lib-esm/utils/component-links.js +72 -12
  33. package/lib-esm/utils/component-links.js.map +1 -1
  34. package/lib-esm/utils/index.js +1 -0
  35. package/lib-esm/utils/index.js.map +1 -1
  36. package/lib-esm/utils/insights.js +47 -0
  37. package/lib-esm/utils/insights.js.map +1 -0
  38. package/lib-esm/webpack/extract/modules-packages-duplicate.js +21 -9
  39. package/lib-esm/webpack/extract/modules-packages-duplicate.js.map +1 -1
  40. package/lib-esm/webpack/extract/modules.js +45 -23
  41. package/lib-esm/webpack/extract/modules.js.map +1 -1
  42. package/lib-esm/webpack/metrics.js +5 -5
  43. package/lib-esm/webpack/metrics.js.map +1 -1
  44. package/package.json +13 -13
  45. package/src/config/component-links.js +5 -0
  46. package/src/config/file-types.js +3 -3
  47. package/src/config/metrics.js +2 -6
  48. package/src/constants.ts +5 -0
  49. package/src/i18n.js +5 -0
  50. package/src/utils/component-links.ts +88 -15
  51. package/src/utils/index.js +1 -0
  52. package/src/utils/insights.ts +82 -0
  53. package/src/webpack/extract/modules-packages-duplicate.ts +31 -16
  54. package/src/webpack/extract/modules.ts +60 -33
  55. package/src/webpack/metrics.js +5 -5
  56. package/src/webpack/types.ts +1 -2
  57. package/types/browsertime/metrics.d.ts +22 -22
  58. package/types/config/component-links.d.ts +24 -18
  59. package/types/config/file-types.d.ts +17 -17
  60. package/types/config/metrics.d.ts +1 -30
  61. package/types/constants.d.ts +4 -0
  62. package/types/i18n.d.ts +17 -12
  63. package/types/lighthouse/metrics.d.ts +16 -16
  64. package/types/utils/component-links.d.ts +8 -2
  65. package/types/utils/index.d.ts +1 -0
  66. package/types/utils/insights.d.ts +9 -0
  67. package/types/webpack/constants.d.ts +1 -1
  68. package/types/webpack/extract/assets-size-total-insight.d.ts +1 -1
  69. package/types/webpack/extract/modules-packages-duplicate.d.ts +3 -3
  70. package/types/webpack/metrics.d.ts +51 -51
  71. package/types/webpack/types.d.ts +1 -2
  72. package/tsconfig.lib.json +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../../src/webpack/extract/modules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../../src/webpack/extract/modules.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { Metric } from './types';
4
4
  export const metrics = {
5
5
  [Metric.BUNDLE_SIZE]: {
6
6
  label: 'Bundle Size',
7
- description: 'The total size of the assets produced by webpack',
7
+ description: 'The total size of the assets processed by the bundler',
8
8
  url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
9
9
  type: METRIC_TYPE_FILE_SIZE,
10
10
  },
@@ -43,14 +43,14 @@ export const metrics = {
43
43
  },
44
44
  [Metric.MODULE_COUNT]: {
45
45
  label: 'Modules',
46
- description: 'The total number of modules bundled by webpack',
46
+ description: 'The total number of bundled modules',
47
47
  url: 'https://relative-ci.com/documentation/metrics-and-data#modules-1',
48
48
  type: METRIC_TYPE_NUMERIC,
49
49
  biggerIsBetter: false,
50
50
  },
51
51
  [Metric.DUPLICATE_MODULES_COUNT]: {
52
52
  label: 'Duplicate Modules',
53
- description: 'The total number of modules that belong to more than one chunk',
53
+ description: 'The total number of module instances bundled into multiple chunks',
54
54
  url: 'https://relative-ci.com/documentation/metrics-and-data#modules-1',
55
55
  type: METRIC_TYPE_NUMERIC,
56
56
  biggerIsBetter: false,
@@ -64,14 +64,14 @@ export const metrics = {
64
64
  },
65
65
  [Metric.PACKAGE_COUNT]: {
66
66
  label: 'Packages',
67
- description: 'The total number of packages bundled by webpack',
67
+ description: 'The total number of bundled packages',
68
68
  url: 'https://relative-ci.com/documentation/metrics-and-data#packages',
69
69
  type: METRIC_TYPE_NUMERIC,
70
70
  biggerIsBetter: false,
71
71
  },
72
72
  [Metric.DUPLICATE_PACKAGES_COUNT]: {
73
73
  label: 'Duplicate Packages',
74
- description: 'The total number of duplicate packages',
74
+ description: 'The total number of bundled duplicate package instances',
75
75
  url: 'https://relative-ci.com/documentation/metrics-and-data#packages',
76
76
  type: METRIC_TYPE_NUMERIC,
77
77
  biggerIsBetter: false,
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/webpack/metrics.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/webpack/metrics.js"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bundle-stats/utils",
3
- "version": "4.4.0-beta.1",
3
+ "version": "4.4.0-beta.3",
4
4
  "description": "BundleStats utils",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -35,28 +35,28 @@
35
35
  },
36
36
  "homepage": "https://github.com/relative-ci/bundle-stats/blob/master/packages/utils#readme",
37
37
  "dependencies": {
38
- "@bundle-stats/plugin-webpack-filter": "^4.4.0-beta.1",
39
- "@bundle-stats/plugin-webpack-validate": "^4.4.0-beta.1",
38
+ "@bundle-stats/plugin-webpack-filter": "^4.4.0-beta.3",
39
+ "@bundle-stats/plugin-webpack-validate": "^4.4.0-beta.3",
40
40
  "query-string": "7.1.3",
41
41
  "serialize-query-params": "2.0.2",
42
- "use-query-params": "2.2.0"
42
+ "use-query-params": "2.2.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/jest": "29.4.0",
46
- "@types/lodash": "4.14.191",
47
- "core-js": "3.27.2",
48
- "jest": "29.4.2",
49
- "jest-cli": "29.4.2",
45
+ "@types/jest": "29.5.2",
46
+ "@types/lodash": "4.14.195",
47
+ "core-js": "3.30.2",
48
+ "jest": "29.5.0",
49
+ "jest-cli": "29.5.0",
50
50
  "jest-date-mock": "1.0.8",
51
51
  "lodash": "4.17.21",
52
52
  "regenerator-runtime": "0.13.11",
53
- "rimraf": "4.1.2",
54
- "ts-jest": "29.0.5",
55
- "typescript": "4.9.5"
53
+ "rimraf": "4.4.1",
54
+ "ts-jest": "29.1.0",
55
+ "typescript": "5.1.3"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "core-js": "^3.0.0",
59
59
  "lodash": "^4.0.0"
60
60
  },
61
- "gitHead": "282bd9bf5f16be3a868b946e257f1e89c27c90d6"
61
+ "gitHead": "24b9c0091e6a2dee2745dc149c2743e72349c3f0"
62
62
  }
@@ -36,3 +36,8 @@ export const COMPONENT = {
36
36
  BUNDLE_MODULES: 'bm',
37
37
  BUNDLE_PACKAGES: 'bp',
38
38
  };
39
+
40
+ export const MODULE_SOURCE_TYPE_LABELS = {
41
+ FIRST_PARTY: 'First party',
42
+ THIRD_PARTY: 'Third party',
43
+ };
@@ -9,7 +9,7 @@ export const FILE_TYPE_OTHER = 'OTHER';
9
9
 
10
10
  export const FILE_TYPE_PATTERNS = {
11
11
  [FILE_TYPE_CSS]: /\.css$/,
12
- [FILE_TYPE_JS]: /\.js$/,
12
+ [FILE_TYPE_JS]: /\.(js|cjs|mjs)$/,
13
13
  [FILE_TYPE_IMG]: /\.(a?png|jpe?g|webp|gif|svg|ico|avif)$/,
14
14
  [FILE_TYPE_MEDIA]: /\.(mp4|mp3|m4a|aac|mov|webm|wav|ogg)$/,
15
15
  [FILE_TYPE_FONT]: /\.(woff|woff2|ttf|otf|eot)$/,
@@ -34,14 +34,14 @@ export const FILE_TYPES = [...Object.keys(FILE_TYPE_PATTERNS), FILE_TYPE_OTHER];
34
34
  */
35
35
  export const MODULE_SOURCE_PATTERNS = {
36
36
  [FILE_TYPE_CSS]: /\.(css|styl|sass|scss|less)$/,
37
- [FILE_TYPE_JS]: /\.(jsx?|tsx?|mjs)$/,
37
+ [FILE_TYPE_JS]: /\.(jsx?|tsx?|cjs|mjs)$/,
38
38
  };
39
39
 
40
40
  export const MODULE_SOURCE_FILE_TYPES = [...Object.keys(MODULE_SOURCE_PATTERNS), FILE_TYPE_OTHER];
41
41
 
42
42
  export const MODULE_DESTINATION_PATTERNS = {
43
43
  [FILE_TYPE_CSS]: /\.css$/,
44
- [FILE_TYPE_JS]: /\.(js|mjs)$/,
44
+ [FILE_TYPE_JS]: /\.(js|cjs|mjs)$/,
45
45
  };
46
46
 
47
47
  export const MODULE_DESTINATION_FILE_TYPES = Object.keys(MODULE_DESTINATION_PATTERNS);
@@ -1,9 +1,4 @@
1
- import {
2
- formatNumber,
3
- formatDuration,
4
- formatFileSize,
5
- formatPercentage,
6
- } from '../utils/format';
1
+ import { formatNumber, formatDuration, formatFileSize, formatPercentage } from '../utils/format';
7
2
 
8
3
  export const METRIC_TYPE_FILE_SIZE = 'METRIC_TYPE_FILE_SIZE';
9
4
  export const METRIC_TYPE_DURATION = 'METRIC_TYPE_DURATION';
@@ -11,6 +6,7 @@ export const METRIC_TYPE_NUMERIC = 'METRIC_TYPE_NUMERIC';
11
6
  export const METRIC_TYPE_SCORE = 'METRIC_TYPE_SCORE';
12
7
  export const METRIC_TYPE_PERCENTAGE = 'METRIC_TYPE_PERCENTAGE';
13
8
 
9
+ /** @type {Record<string, import('../constants').MetricType>} */
14
10
  export const METRIC_TYPES = {
15
11
  [METRIC_TYPE_NUMERIC]: {
16
12
  biggerIsBetter: false,
package/src/constants.ts CHANGED
@@ -101,6 +101,11 @@ export interface JobInsights {
101
101
  };
102
102
  }
103
103
 
104
+ export interface JobInsightsInfo {
105
+ duplicatePackages?: JobInsights['webpack']['duplicatePackagesV3'];
106
+ newPackages?: JobInsights['webpack']['newPackages'];
107
+ }
108
+
104
109
  export type JobMetricsSource = Record<string, MetricRun | Record<string, MetricRun>>;
105
110
  export type JobMetrics = JobSection<JobMetricsSource>;
106
111
 
package/src/i18n.js CHANGED
@@ -7,9 +7,14 @@ export default {
7
7
  COMPONENT_LINK_BUNDLE_ASSETS_CHUNK_COUNT: 'View all chunks',
8
8
  COMPONENT_LINK_MODULES: 'View modules',
9
9
  COMPONENT_LINK_MODULES_DUPLICATE: 'View duplicate modules',
10
+ COMPONENT_LINK_MODULES_BY_FILE_TYPE: (fileType) => `View all ${fileType} modules`,
11
+ COMPONENT_LINK_MODULES_BY_SOURCE: (source) => `View all ${source} modules`,
10
12
  COMPONENT_LINK_CHUNK_MODULES: 'View chunk modules',
11
13
  COMPONENT_LINK_PACKAGES_COUNT: 'View all packages',
14
+ COMPONENT_LINK_PACKAGES_CHANGED: 'View all changed packages',
12
15
  COMPONENT_LINK_PACKAGES_DUPLICATE: 'View all duplicate packages',
16
+ COMPONENT_LINK_PACKAGES_DUPLICATE_CHANGED: 'View all changed duplicate packages',
13
17
  COMPONENT_LINK_VIEW_PACKAGE: 'View package',
14
18
  COMPONENT_LINK_BUNDLE_ASSETS_BY_FILE_TYPE: ({ label }) => `View all ${label} assets`,
19
+ COMPONENT_LINK_BUNDLE_ASSETS_BY_ENTRY_TYPE: (assetType) => `View all ${assetType} assets`,
15
20
  };
@@ -16,6 +16,7 @@ import {
16
16
  MODULE_FILE_TYPE,
17
17
  MODULE_FILTERS,
18
18
  MODULE_SOURCE_TYPE,
19
+ MODULE_SOURCE_TYPE_LABELS,
19
20
  PACKAGE_FILTERS,
20
21
  SECTIONS,
21
22
  } from '../config/component-links';
@@ -25,6 +26,7 @@ export type ComponentLinkFilters = Record<string, boolean>;
25
26
 
26
27
  export interface ComponentLinkParams {
27
28
  search?: string;
29
+ entryId?: string;
28
30
  filters: ComponentLinkFilters;
29
31
  }
30
32
 
@@ -159,6 +161,51 @@ export const BUNDLE_ASSETS_CHUNK_COUNT: ComponentLink = {
159
161
  },
160
162
  };
161
163
 
164
+ export const getBundleAsset = (entryId: string): ComponentLink => ({
165
+ section: SECTIONS.ASSETS,
166
+ title: 'View asset details' as any,
167
+ params: {
168
+ [COMPONENT.BUNDLE_ASSETS]: {
169
+ entryId,
170
+ filters: {},
171
+ },
172
+ },
173
+ });
174
+
175
+ export const getBundleAssetsByEntryType = (
176
+ assetType: 'entry' | 'initial' | 'chunk',
177
+ ): ComponentLink => ({
178
+ section: SECTIONS.ASSETS,
179
+ title: I18N.COMPONENT_LINK_BUNDLE_ASSETS_BY_ENTRY_TYPE(assetType),
180
+ params: {
181
+ [COMPONENT.BUNDLE_ASSETS]: {
182
+ filters: {
183
+ [ASSET_FILTERS.CHANGED]: false,
184
+ ...getAssetEntryTypeFilters(false),
185
+ [`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`]: assetType === 'entry',
186
+ [`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`]: assetType === 'initial',
187
+ [`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`]: assetType === 'chunk',
188
+ },
189
+ },
190
+ },
191
+ });
192
+
193
+ export const getBundleAssetsFileTypeComponentLink = (
194
+ fileType: string,
195
+ label: string = fileType,
196
+ ): ComponentLink => ({
197
+ section: SECTIONS.ASSETS,
198
+ title: I18N.COMPONENT_LINK_BUNDLE_ASSETS_BY_FILE_TYPE({ label }),
199
+ params: {
200
+ [COMPONENT.BUNDLE_ASSETS]: {
201
+ filters: {
202
+ ...getAssetFileTypeFilters(false),
203
+ [`${ASSET_FILE_TYPE}.${fileType}`]: true,
204
+ },
205
+ },
206
+ },
207
+ });
208
+
162
209
  export const BUNDLE_MODULES: ComponentLink = {
163
210
  section: SECTIONS.MODULES,
164
211
  title: I18N.COMPONENT_LINK_MODULES,
@@ -221,6 +268,35 @@ export const getBundleModulesByChunk = (
221
268
  },
222
269
  });
223
270
 
271
+ export const getBundleModulesByFileTpe = (
272
+ fileType: string,
273
+ fileTypeLabel?: string,
274
+ ): ComponentLink => ({
275
+ section: SECTIONS.MODULES,
276
+ title: I18N.COMPONENT_LINK_MODULES_BY_FILE_TYPE(fileTypeLabel || fileType),
277
+ params: {
278
+ [COMPONENT.BUNDLE_MODULES]: {
279
+ filters: {
280
+ ...getModuleFileTypeFilters(false),
281
+ [`${MODULE_FILE_TYPE}.${fileType}`]: true,
282
+ },
283
+ },
284
+ },
285
+ });
286
+
287
+ export const getBundleModulesBySource = (thirdParty: boolean, label = ''): ComponentLink => ({
288
+ section: SECTIONS.MODULES,
289
+ title: I18N.COMPONENT_LINK_MODULES_BY_SOURCE(label),
290
+ params: {
291
+ [COMPONENT.BUNDLE_MODULES]: {
292
+ filters: {
293
+ [`${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.THIRD_PARTY}`]: thirdParty,
294
+ [`${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.FIRST_PARTY}`]: !thirdParty,
295
+ },
296
+ },
297
+ },
298
+ });
299
+
224
300
  export const BUNDLE_PACKAGES_COUNT: ComponentLink = {
225
301
  section: SECTIONS.PACKAGES,
226
302
  title: I18N.COMPONENT_LINK_PACKAGES_COUNT,
@@ -234,46 +310,43 @@ export const BUNDLE_PACKAGES_COUNT: ComponentLink = {
234
310
  },
235
311
  };
236
312
 
237
- export const BUNDLE_PACKAGES_DUPLICATE: ComponentLink = {
313
+ export const BUNDLE_PACKAGES_CHANGED: ComponentLink = {
238
314
  section: SECTIONS.PACKAGES,
239
- title: I18N.COMPONENT_LINK_PACKAGES_DUPLICATE,
315
+ title: I18N.COMPONENT_LINK_PACKAGES_CHANGED,
240
316
  params: {
241
317
  [COMPONENT.BUNDLE_PACKAGES]: {
242
318
  filters: {
243
- [PACKAGE_FILTERS.DUPLICATE]: true,
319
+ // Keep a filter to allow the merge and skip default
320
+ [PACKAGE_FILTERS.CHANGED]: true,
244
321
  },
245
322
  },
246
323
  },
247
324
  };
248
325
 
249
- export const BUNDLE_PACKAGES_DUPLICATE_NEW: ComponentLink = {
326
+ export const BUNDLE_PACKAGES_DUPLICATE: ComponentLink = {
250
327
  section: SECTIONS.PACKAGES,
251
328
  title: I18N.COMPONENT_LINK_PACKAGES_DUPLICATE,
252
329
  params: {
253
330
  [COMPONENT.BUNDLE_PACKAGES]: {
254
331
  filters: {
255
- [PACKAGE_FILTERS.CHANGED]: true,
256
332
  [PACKAGE_FILTERS.DUPLICATE]: true,
257
333
  },
258
334
  },
259
335
  },
260
336
  };
261
337
 
262
- export const getBundleAssetsFileTypeComponentLink = (
263
- fileType: string,
264
- label: string,
265
- ): ComponentLink => ({
266
- section: SECTIONS.ASSETS,
267
- title: I18N.COMPONENT_LINK_BUNDLE_ASSETS_BY_FILE_TYPE({ label }),
338
+ export const BUNDLE_PACKAGES_DUPLICATE_CHANGED: ComponentLink = {
339
+ section: SECTIONS.PACKAGES,
340
+ title: I18N.COMPONENT_LINK_PACKAGES_DUPLICATE_CHANGED,
268
341
  params: {
269
- [COMPONENT.BUNDLE_ASSETS]: {
342
+ [COMPONENT.BUNDLE_PACKAGES]: {
270
343
  filters: {
271
- ...getAssetFileTypeFilters(false),
272
- [`${ASSET_FILE_TYPE}.${fileType}`]: true,
344
+ [PACKAGE_FILTERS.CHANGED]: true,
345
+ [PACKAGE_FILTERS.DUPLICATE]: true,
273
346
  },
274
347
  },
275
348
  },
276
- });
349
+ };
277
350
 
278
351
  export const getBundlePackagesByNameComponentLink = (search: string): ComponentLink => ({
279
352
  section: SECTIONS.PACKAGES,
@@ -1,6 +1,7 @@
1
1
  export * from './component-links';
2
2
  export * from './delta';
3
3
  export * from './date';
4
+ export * from './insights';
4
5
  export * from './file-types';
5
6
  export * from './format';
6
7
  export * from './metrics';
@@ -0,0 +1,82 @@
1
+ import isEmpty from 'lodash/isEmpty';
2
+
3
+ import { InsightType, JobInsight, JobInsightsInfo } from '../constants';
4
+ import {
5
+ BUNDLE_PACKAGES_DUPLICATE,
6
+ BUNDLE_PACKAGES_CHANGED,
7
+ BUNDLE_PACKAGES_DUPLICATE_CHANGED,
8
+ } from './component-links';
9
+
10
+ interface InsightListItem {
11
+ /**
12
+ * Inight name
13
+ */
14
+ name: string;
15
+ /**
16
+ * Insight data
17
+ */
18
+ insight: JobInsight;
19
+ /**
20
+ * Custom link props
21
+ */
22
+ link: any;
23
+ }
24
+
25
+ /**
26
+ * Get the insigh list ordered by level type
27
+ */
28
+ export const getInsightList = (insights: JobInsightsInfo): Array<InsightListItem> => {
29
+ const { duplicatePackages, newPackages } = insights;
30
+
31
+ const insightsByLevel: Record<InsightType, Array<InsightListItem>> = {
32
+ [InsightType.ERROR]: [],
33
+ [InsightType.WARNING]: [],
34
+ [InsightType.INFO]: [],
35
+ };
36
+
37
+ if (duplicatePackages) {
38
+ insightsByLevel[duplicatePackages.type].push({
39
+ name: 'duplicatePackages',
40
+ insight: duplicatePackages,
41
+ link:
42
+ duplicatePackages.type === InsightType.WARNING
43
+ ? BUNDLE_PACKAGES_DUPLICATE
44
+ : BUNDLE_PACKAGES_DUPLICATE_CHANGED,
45
+ });
46
+ }
47
+
48
+ if (newPackages) {
49
+ insightsByLevel[newPackages.type].push({
50
+ name: 'newPackages',
51
+ insight: newPackages,
52
+ link: BUNDLE_PACKAGES_CHANGED,
53
+ });
54
+ }
55
+
56
+ return [
57
+ ...(insightsByLevel[InsightType.ERROR] || []),
58
+ ...(insightsByLevel[InsightType.WARNING] || []),
59
+ ...(insightsByLevel[InsightType.INFO] || []),
60
+ ];
61
+ };
62
+
63
+ /**
64
+ * Show only the insights that are introduced by a change
65
+ */
66
+ export const getChangedInsights = (normalizedInsights: JobInsightsInfo): JobInsightsInfo | null => {
67
+ const res: JobInsightsInfo = {};
68
+
69
+ if (normalizedInsights.duplicatePackages?.type === InsightType.ERROR) {
70
+ res.duplicatePackages = normalizedInsights.duplicatePackages;
71
+ }
72
+
73
+ if (normalizedInsights.newPackages) {
74
+ res.newPackages = normalizedInsights.newPackages;
75
+ }
76
+
77
+ if (isEmpty(res)) {
78
+ return null;
79
+ }
80
+
81
+ return res;
82
+ };
@@ -1,3 +1,4 @@
1
+ import isEmpty from 'lodash/isEmpty';
1
2
  import map from 'lodash/map';
2
3
  import orderBy from 'lodash/orderBy';
3
4
  import sum from 'lodash/sum';
@@ -25,9 +26,9 @@ interface DuplicatePackageGroup {
25
26
  }
26
27
 
27
28
  interface ModulesPackagesDuplicateData {
28
- insights: {
29
+ insights?: {
29
30
  duplicatePackages?: JobInsights['webpack']['duplicatePackages'];
30
- duplicatePackagesV3: JobInsights['webpack']['duplicatePackagesV3'];
31
+ duplicatePackagesV3?: JobInsights['webpack']['duplicatePackagesV3'];
31
32
  };
32
33
  metrics: {
33
34
  duplicatePackagesCount: MetricRun;
@@ -37,7 +38,7 @@ interface ModulesPackagesDuplicateData {
37
38
  export const getDuplicatePackagesInsight = (
38
39
  duplicatePackagesMap: Record<string, Array<string>>,
39
40
  baselineDuplicatePackagesMap?: Record<string, Array<string>>,
40
- ): JobInsight<JobInsightDuplicatePackagesV3Data> => {
41
+ ): JobInsight<JobInsightDuplicatePackagesV3Data> | null => {
41
42
  const duplicateInstances: Array<string> = [];
42
43
  const baselineDuplicateInstances: Array<string> = [];
43
44
  const newDuplicateInstances: Array<string> = [];
@@ -81,8 +82,8 @@ export const getDuplicatePackagesInsight = (
81
82
  const newDuplicateInstancesCount = newDuplicateInstances.length;
82
83
  const removedDuplicateInstancesCount = removedDuplicateInstances.length;
83
84
 
84
- let text: string;
85
- let insightType: InsightType;
85
+ let text = '';
86
+ let insightType: InsightType | null = null;
86
87
 
87
88
  if (newDuplicateInstancesCount > 0 && removedDuplicateInstancesCount > 0) {
88
89
  // New duplicate packages and removed duplicates
@@ -90,7 +91,7 @@ export const getDuplicatePackagesInsight = (
90
91
  newDuplicateInstancesCount > 1 || removedDuplicateInstancesCount > 1 ? 'packages' : 'package';
91
92
  text = `Bundle introduced ${newDuplicateInstancesCount} and removed ${removedDuplicateInstancesCount} duplicate ${item}`;
92
93
  insightType = InsightType.ERROR;
93
- } else if (newDuplicateInstancesCount > 0 && baselineDuplicatePackagesMap) {
94
+ } else if (newDuplicateInstancesCount > 0 && !isEmpty(baselineDuplicatePackagesMap)) {
94
95
  // New duplicate packages and baseline comparison
95
96
  const item = newDuplicateInstancesCount > 1 ? 'packages' : 'package';
96
97
  text = `Bundle introduced ${newDuplicateInstancesCount} duplicate ${item}`;
@@ -100,6 +101,12 @@ export const getDuplicatePackagesInsight = (
100
101
  const item = newDuplicateInstancesCount > 1 ? 'packages' : 'package';
101
102
  text = `Bundle contains ${newDuplicateInstancesCount} duplicate ${item}`;
102
103
  insightType = InsightType.WARNING;
104
+ } else if (removedDuplicateInstancesCount > 0 && duplicateInstancesCount > 0) {
105
+ // Removed duplicate packages, but there are duplicate packages remaining
106
+ const itemRemoved = removedDuplicateInstancesCount > 1 ? 'packages' : 'package';
107
+ const itemRemaining = duplicateInstancesCount > 1 ? 'packages' : 'package';
108
+ text = `Bundle removed ${removedDuplicateInstancesCount} duplicate ${itemRemoved}, ${duplicateInstancesCount} duplicate ${itemRemaining} remaining`;
109
+ insightType = InsightType.WARNING;
103
110
  } else if (removedDuplicateInstancesCount > 0) {
104
111
  // Removed duplicate packages
105
112
  const item = removedDuplicateInstancesCount > 1 ? 'packages' : 'package';
@@ -115,9 +122,11 @@ export const getDuplicatePackagesInsight = (
115
122
  text = `Bundle contains ${duplicateInstancesCount} duplicate ${item}`;
116
123
  insightType = InsightType.WARNING;
117
124
  } else {
118
- // No change
119
- text = 'Bundle does not contain duplicate packages';
120
- insightType = InsightType.INFO;
125
+ // No change - noop
126
+ }
127
+
128
+ if (!text || !insightType) {
129
+ return null;
121
130
  }
122
131
 
123
132
  return {
@@ -180,11 +189,15 @@ export const extractModulesPackagesDuplicate = (
180
189
  baselineJob?.insights?.webpack?.duplicatePackages?.data ||
181
190
  {};
182
191
 
192
+ const noDuplicatesDuplicatePackagesV3 = getDuplicatePackagesInsight({}, baselineDuplicatePackages);
193
+
183
194
  if (!count) {
184
195
  return {
185
- insights: {
186
- duplicatePackagesV3: getDuplicatePackagesInsight({}, baselineDuplicatePackages),
187
- },
196
+ ...(noDuplicatesDuplicatePackagesV3 && {
197
+ insights: {
198
+ duplicatePackagesV3: noDuplicatesDuplicatePackagesV3,
199
+ },
200
+ }),
188
201
  metrics: {
189
202
  duplicatePackagesCount: {
190
203
  value: count,
@@ -221,16 +234,18 @@ export const extractModulesPackagesDuplicate = (
221
234
  duplicatePackagesData[packageName] = packageData.children.map(({ id }) => id);
222
235
  });
223
236
 
237
+ const duplicatePackagesV3 = getDuplicatePackagesInsight(
238
+ duplicatePackagesData,
239
+ baselineDuplicatePackages,
240
+ );
241
+
224
242
  return {
225
243
  insights: {
226
244
  duplicatePackages: {
227
245
  type: InsightType.WARNING,
228
246
  data: duplicatePackagesData,
229
247
  },
230
- duplicatePackagesV3: getDuplicatePackagesInsight(
231
- duplicatePackagesData,
232
- baselineDuplicatePackages,
233
- ),
248
+ ...(duplicatePackagesV3 && { duplicatePackagesV3 }),
234
249
  },
235
250
  metrics: {
236
251
  duplicatePackagesCount: {