@mui/internal-bundle-size-checker 1.0.6 → 1.0.9-canary.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/internal-bundle-size-checker",
3
- "version": "1.0.6",
3
+ "version": "1.0.9-canary.0",
4
4
  "description": "Bundle size checker for MUI packages.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -48,6 +48,7 @@
48
48
  "@types/webpack-bundle-analyzer": "^4.7.0",
49
49
  "@types/yargs": "^17.0.33"
50
50
  },
51
+ "gitSha": "1c2b2282d97b7e09cf2d01ccc23046544f4e36ba",
51
52
  "scripts": {
52
53
  "typescript": "tsc -p tsconfig.json",
53
54
  "test": "pnpm -w test --project @mui/internal-bundle-size-checker"
@@ -69,6 +69,51 @@ function generateEmphasizedChange({ id: bundle, parsed, gzip }) {
69
69
  return `**${bundle}** **parsed:** ${changeParsed} **gzip:** ${changeGzip}`;
70
70
  }
71
71
 
72
+ /**
73
+ * @typedef {Object} ColumnDefinition
74
+ * @property {string} field - The property key to extract from data objects
75
+ * @property {string} [header] - Column header (defaults to field name)
76
+ * @property {'left'|'center'|'right'} [align='left'] - Column alignment
77
+ */
78
+
79
+ /**
80
+ * Formats data as a markdown table
81
+ * @param {ColumnDefinition[]} columns - Column definitions
82
+ * @param {Partial<Record<string, unknown>>[]} data - Array of data objects
83
+ * @returns {string} Formatted markdown table
84
+ */
85
+ function formatMarkdownTable(columns, data) {
86
+ let table = '';
87
+
88
+ // Extract headers and alignments from column definitions
89
+ const headers = columns.map((col) => col.header || col.field);
90
+ const alignments = columns.map((col) => col.align || 'left');
91
+
92
+ // Header row
93
+ table += `| ${headers.join(' | ')} |\n`;
94
+
95
+ // Separator row with alignment
96
+ const separators = alignments.map((align) => {
97
+ switch (align) {
98
+ case 'center':
99
+ return ':----------:';
100
+ case 'right':
101
+ return '----------:';
102
+ default:
103
+ return '----------';
104
+ }
105
+ });
106
+ table += `|${separators.join('|')}|\n`;
107
+
108
+ // Data rows
109
+ data.forEach((row) => {
110
+ const cells = columns.map((col) => row[col.field] ?? '');
111
+ table += `| ${cells.join(' | ')} |\n`;
112
+ });
113
+
114
+ return table;
115
+ }
116
+
72
117
  /**
73
118
  * Generates a Markdown report for bundle size changes
74
119
  * @param {ComparisonResult} comparison - Comparison result from calculateSizeDiff
@@ -92,9 +137,20 @@ export function renderMarkdownReportContent(
92
137
  }
93
138
  return trackedEntry;
94
139
  });
95
- // Show all tracked bundles directly (including unchanged ones)
96
- const trackedChanges = trackedEntries.map(generateEmphasizedChange);
97
- markdownContent += `${trackedChanges.join('\n')}`;
140
+
141
+ markdownContent += formatMarkdownTable(
142
+ [
143
+ { field: 'id', header: 'Bundle' },
144
+ { field: 'parsed', header: 'Parsed Size', align: 'right' },
145
+ { field: 'gzip', header: 'Gzip Size', align: 'right' },
146
+ ],
147
+ trackedEntries.map(({ id, parsed, gzip }) => ({
148
+ id,
149
+ parsed: formatChange(parsed.absoluteDiff, parsed.relativeDiff),
150
+ gzip: formatChange(gzip.absoluteDiff, gzip.relativeDiff),
151
+ })),
152
+ );
153
+ markdownContent += '\n';
98
154
  } else {
99
155
  markdownContent += `**Total Size Change:** ${formatChange(
100
156
  comparison.totals.totalParsed,
@@ -107,26 +163,26 @@ export function renderMarkdownReportContent(
107
163
  markdownContent += `Files: ${comparison.fileCounts.total} total (${
108
164
  comparison.fileCounts.added
109
165
  } added, ${comparison.fileCounts.removed} removed, ${comparison.fileCounts.changed} changed)\n\n`;
110
- }
111
166
 
112
- // Show all entries in details section, not just changed ones
113
- // Filter out tracked bundles to avoid duplication
114
- const trackedIdSet = new Set(track);
115
- const detailsEntries = comparison.entries.filter((entry) => !trackedIdSet.has(entry.id));
116
-
117
- // Cap at maxDetailsLines bundles to avoid overly large reports
118
- const cappedEntries = detailsEntries.slice(0, maxDetailsLines);
119
- const hasMore = detailsEntries.length > maxDetailsLines;
120
-
121
- if (cappedEntries.length > 0) {
122
- const allChanges = cappedEntries.map(generateEmphasizedChange);
123
- const bundleWord = cappedEntries.length === 1 ? 'bundle' : 'bundles';
124
- const summaryText = hasMore
125
- ? `Show details for ${cappedEntries.length} more ${bundleWord} (${detailsEntries.length - maxDetailsLines} more not shown)`
126
- : `Show details for ${cappedEntries.length} more ${bundleWord}`;
127
- markdownContent += `<details>\n<summary>${summaryText}</summary>\n\n`;
128
- markdownContent += `${allChanges.join('\n')}\n\n`;
129
- markdownContent += `</details>`;
167
+ // Show all entries in details section, not just changed ones
168
+ // Filter out tracked bundles to avoid duplication
169
+ const trackedIdSet = new Set(track);
170
+ const detailsEntries = comparison.entries.filter((entry) => !trackedIdSet.has(entry.id));
171
+
172
+ // Cap at maxDetailsLines bundles to avoid overly large reports
173
+ const cappedEntries = detailsEntries.slice(0, maxDetailsLines);
174
+ const hasMore = detailsEntries.length > maxDetailsLines;
175
+
176
+ if (cappedEntries.length > 0) {
177
+ const allChanges = cappedEntries.map(generateEmphasizedChange);
178
+ const bundleWord = cappedEntries.length === 1 ? 'bundle' : 'bundles';
179
+ const summaryText = hasMore
180
+ ? `Show details for ${cappedEntries.length} more ${bundleWord} (${detailsEntries.length - maxDetailsLines} more not shown)`
181
+ : `Show details for ${cappedEntries.length} more ${bundleWord}`;
182
+ markdownContent += `<details>\n<summary>${summaryText}</summary>\n\n`;
183
+ markdownContent += `${allChanges.join('\n')}\n\n`;
184
+ markdownContent += `</details>`;
185
+ }
130
186
  }
131
187
 
132
188
  return markdownContent;
@@ -323,13 +323,12 @@ describe('renderMarkdownReport', () => {
323
323
  });
324
324
 
325
325
  expect(result).toMatchInlineSnapshot(`
326
- "**@mui/material/Button/index.js**&emsp;**parsed:** 🔺+400B<sup>(+2.67%)</sup> **gzip:** 🔺+100B<sup>(+2.22%)</sup>
327
- **@mui/material/TextField/index.js**&emsp;**parsed:** 🔺+200B<sup>(+0.91%)</sup> **gzip:** 🔺+100B<sup>(+1.54%)</sup><details>
328
- <summary>Show details for 1 more bundle</summary>
326
+ "| Bundle | Parsed Size | Gzip Size |
327
+ |----------|----------:|----------:|
328
+ | @mui/material/Button/index.js | 🔺+400B<sup>(+2.67%)</sup> | 🔺+100B<sup>(+2.22%)</sup> |
329
+ | @mui/material/TextField/index.js | 🔺+200B<sup>(+0.91%)</sup> | 🔺+100B<sup>(+1.54%)</sup> |
329
330
 
330
- **@mui/icons-material/Add.js**&emsp;**parsed:** 🔺+100B<sup>(+10.00%)</sup> **gzip:** 🔺+50B<sup>(+16.67%)</sup>
331
331
 
332
- </details>
333
332
 
334
333
  [Details of bundle changes](https://frontend-public.mui.com/size-comparison/mui/material-ui/diff?prNumber=42&baseRef=master&baseCommit=abc123&headCommit=def456)"
335
334
  `);
@@ -359,13 +358,12 @@ describe('renderMarkdownReport', () => {
359
358
  });
360
359
 
361
360
  expect(result).toMatchInlineSnapshot(`
362
- "**@mui/material/Button/index.js**&emsp;**parsed:** 🔺+500B<sup>(+3.33%)</sup> **gzip:** 🔺+150B<sup>(+3.33%)</sup>
363
- **@mui/material/TextField/index.js**&emsp;**parsed:** 🔺+300B<sup>(+1.36%)</sup> **gzip:** 🔺+150B<sup>(+2.31%)</sup><details>
364
- <summary>Show details for 1 more bundle</summary>
361
+ "| Bundle | Parsed Size | Gzip Size |
362
+ |----------|----------:|----------:|
363
+ | @mui/material/Button/index.js | 🔺+500B<sup>(+3.33%)</sup> | 🔺+150B<sup>(+3.33%)</sup> |
364
+ | @mui/material/TextField/index.js | 🔺+300B<sup>(+1.36%)</sup> | 🔺+150B<sup>(+2.31%)</sup> |
365
365
 
366
- **@mui/icons-material/Add.js**&emsp;**parsed:** 🔺+1KB<sup>(+100.00%)</sup> **gzip:** 🔺+300B<sup>(+100.00%)</sup>
367
366
 
368
- </details>
369
367
 
370
368
  [Details of bundle changes](https://frontend-public.mui.com/size-comparison/mui/material-ui/diff?prNumber=42&baseRef=master&baseCommit=abc123&headCommit=def456)"
371
369
  `);
@@ -395,13 +393,11 @@ describe('renderMarkdownReport', () => {
395
393
  });
396
394
 
397
395
  expect(result).toMatchInlineSnapshot(`
398
- "**@mui/material/Button/index.js**&emsp;**parsed:** 🔺+400B<sup>(+2.67%)</sup> **gzip:** 🔺+100B<sup>(+2.22%)</sup><details>
399
- <summary>Show details for 2 more bundles</summary>
396
+ "| Bundle | Parsed Size | Gzip Size |
397
+ |----------|----------:|----------:|
398
+ | @mui/material/Button/index.js | 🔺+400B<sup>(+2.67%)</sup> | 🔺+100B<sup>(+2.22%)</sup> |
400
399
 
401
- **@mui/icons-material/Add.js**&emsp;**parsed:** 🔺+100B<sup>(+10.00%)</sup> **gzip:** 🔺+50B<sup>(+16.67%)</sup>
402
- **@mui/icons-material/Delete.js**&emsp;**parsed:** 🔺+100B<sup>(+8.33%)</sup> **gzip:** 🔺+50B<sup>(+14.29%)</sup>
403
400
 
404
- </details>
405
401
 
406
402
  [Details of bundle changes](https://frontend-public.mui.com/size-comparison/mui/material-ui/diff?prNumber=42&baseRef=master&baseCommit=abc123&headCommit=def456)"
407
403
  `);
@@ -431,13 +427,12 @@ describe('renderMarkdownReport', () => {
431
427
  });
432
428
 
433
429
  expect(result).toMatchInlineSnapshot(`
434
- "**@mui/material/Button/index.js**&emsp;**parsed:** 0B<sup>(0.00%)</sup> **gzip:** 0B<sup>(0.00%)</sup>
435
- **@mui/material/TextField/index.js**&emsp;**parsed:** 0B<sup>(0.00%)</sup> **gzip:** 0B<sup>(0.00%)</sup><details>
436
- <summary>Show details for 1 more bundle</summary>
430
+ "| Bundle | Parsed Size | Gzip Size |
431
+ |----------|----------:|----------:|
432
+ | @mui/material/Button/index.js | 0B<sup>(0.00%)</sup> | 0B<sup>(0.00%)</sup> |
433
+ | @mui/material/TextField/index.js | 0B<sup>(0.00%)</sup> | 0B<sup>(0.00%)</sup> |
437
434
 
438
- **@mui/material/Icon/index.js**&emsp;**parsed:** 🔺+100B<sup>(+1.25%)</sup> **gzip:** 🔺+50B<sup>(+2.00%)</sup>
439
435
 
440
- </details>
441
436
 
442
437
  [Details of bundle changes](https://frontend-public.mui.com/size-comparison/mui/material-ui/diff?prNumber=42&baseRef=master&baseCommit=abc123&headCommit=def456)"
443
438
  `);
@@ -465,12 +460,11 @@ describe('renderMarkdownReport', () => {
465
460
  });
466
461
 
467
462
  expect(result).toMatchInlineSnapshot(`
468
- "**@mui/material/Button/index.js**&emsp;**parsed:** 🔺+400B<sup>(+2.67%)</sup> **gzip:** 🔺+100B<sup>(+2.22%)</sup><details>
469
- <summary>Show details for 1 more bundle</summary>
463
+ "| Bundle | Parsed Size | Gzip Size |
464
+ |----------|----------:|----------:|
465
+ | @mui/material/Button/index.js | 🔺+400B<sup>(+2.67%)</sup> | 🔺+100B<sup>(+2.22%)</sup> |
470
466
 
471
- **@mui/material/TextField/index.js**&emsp;**parsed:** 0B<sup>(0.00%)</sup> **gzip:** 0B<sup>(0.00%)</sup>
472
467
 
473
- </details>
474
468
 
475
469
  [Details of bundle changes](https://frontend-public.mui.com/size-comparison/mui/material-ui/diff?prNumber=42&baseRef=master&baseCommit=abc123&headCommit=def456)"
476
470
  `);
@@ -1,9 +1,12 @@
1
1
  import path from 'path';
2
2
  import fs from 'fs/promises';
3
- import { gzipSync } from 'zlib';
3
+ import * as zlib from 'zlib';
4
+ import { promisify } from 'util';
4
5
  import { build, transformWithEsbuild } from 'vite';
5
6
  import { visualizer } from 'rollup-plugin-visualizer';
6
7
 
8
+ const gzipAsync = promisify(zlib.gzip);
9
+
7
10
  const rootDir = process.cwd();
8
11
 
9
12
  /**
@@ -199,11 +202,12 @@ async function processBundleSizes(outDir, entryName) {
199
202
 
200
203
  // Calculate sizes
201
204
  const parsed = Buffer.byteLength(fileContent);
202
- const gzip = Buffer.byteLength(gzipSync(fileContent));
205
+ const gzipBuffer = await gzipAsync(fileContent, { level: zlib.constants.Z_BEST_COMPRESSION });
206
+ const gzipSize = Buffer.byteLength(gzipBuffer);
203
207
 
204
208
  // Use chunk key as the name, or fallback to entry name for main chunk
205
209
  const chunkName = chunkKey === 'virtual:entry.tsx' ? entryName : chunkKey;
206
- return /** @type {const} */ ([chunkName, { parsed, gzip }]);
210
+ return /** @type {const} */ ([chunkName, { parsed, gzip: gzipSize }]);
207
211
  });
208
212
 
209
213
  const chunkEntries = await Promise.all(chunkPromises);