@mui/internal-bundle-size-checker 1.0.9-canary.45 → 1.0.9-canary.46

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.9-canary.45",
3
+ "version": "1.0.9-canary.46",
4
4
  "description": "Bundle size checker for MUI packages.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -37,7 +37,7 @@
37
37
  "@types/micromatch": "^4.0.9",
38
38
  "@types/yargs": "^17.0.33"
39
39
  },
40
- "gitSha": "110101a5bd808883977d6e52af0aeb8cb9ff701c",
40
+ "gitSha": "8112fd2d7929c7e1b5f7475d1a4da16b62ba07cd",
41
41
  "scripts": {
42
42
  "typescript": "tsc -p tsconfig.json",
43
43
  "test": "pnpm -w test --project @mui/internal-bundle-size-checker"
package/src/builder.js CHANGED
@@ -25,13 +25,32 @@ const rootDir = process.cwd();
25
25
  * @typedef {Record<string, ManifestChunk>} Manifest
26
26
  */
27
27
 
28
+ /**
29
+ * Creates a simple string replacement plugin
30
+ * @param {Record<string, string>} replacements - Object with string replacements
31
+ * @returns {import('vite').Plugin}
32
+ */
33
+ function createReplacePlugin(replacements) {
34
+ return {
35
+ name: 'string-replace',
36
+ transform(code) {
37
+ let transformedCode = code;
38
+ for (const [search, replace] of Object.entries(replacements)) {
39
+ transformedCode = transformedCode.replaceAll(search, replace);
40
+ }
41
+ return transformedCode !== code ? transformedCode : null;
42
+ },
43
+ };
44
+ }
45
+
28
46
  /**
29
47
  * Creates vite configuration for bundle size checking
30
48
  * @param {ObjectEntry} entry - Entry point (string or object)
31
49
  * @param {CommandLineArgs} args
50
+ * @param {Record<string, string>} [replacements] - String replacements to apply
32
51
  * @returns {Promise<import('vite').InlineConfig>}
33
52
  */
34
- async function createViteConfig(entry, args) {
53
+ async function createViteConfig(entry, args, replacements = {}) {
35
54
  const entryName = entry.id;
36
55
  let entryContent;
37
56
 
@@ -61,6 +80,7 @@ async function createViteConfig(entry, args) {
61
80
  // Ensure build directory exists
62
81
  const outDir = path.join(rootDir, 'build', entryName);
63
82
  await fs.mkdir(outDir, { recursive: true });
83
+
64
84
  /**
65
85
  * @type {import('vite').InlineConfig}
66
86
  */
@@ -73,8 +93,19 @@ async function createViteConfig(entry, args) {
73
93
  minify: args.debug ? 'esbuild' : true,
74
94
  outDir,
75
95
  emptyOutDir: true,
96
+ modulePreload: false,
76
97
  rollupOptions: {
77
- input: '/index.tsx',
98
+ input: {
99
+ ignore: '/ignore.ts',
100
+ bundle: '/entry.tsx',
101
+ },
102
+ output: {
103
+ // The output is for debugging purposes only. Remove all hashes to make it easier to compare two folders
104
+ // of build output.
105
+ entryFileNames: `assets/[name].js`,
106
+ chunkFileNames: `assets/[name].js`,
107
+ assetFileNames: `assets/[name].[ext]`,
108
+ },
78
109
  external: (id) => externalsArray.some((ext) => id === ext || id.startsWith(`${ext}/`)),
79
110
  plugins: [
80
111
  ...(args.analyze
@@ -113,11 +144,12 @@ async function createViteConfig(entry, args) {
113
144
  logLevel: args.verbose ? 'info' : 'silent',
114
145
  // Add plugins to handle virtual entry points
115
146
  plugins: [
147
+ createReplacePlugin(replacements),
116
148
  {
117
149
  name: 'virtual-entry',
118
150
  resolveId(id) {
119
- if (id === '/index.tsx') {
120
- return `\0virtual:index.tsx`;
151
+ if (id === '/ignore.ts') {
152
+ return `\0virtual:ignore.ts`;
121
153
  }
122
154
  if (id === '/entry.tsx') {
123
155
  return `\0virtual:entry.tsx`;
@@ -125,7 +157,9 @@ async function createViteConfig(entry, args) {
125
157
  return null;
126
158
  },
127
159
  load(id) {
128
- if (id === `\0virtual:index.tsx`) {
160
+ if (id === `\0virtual:ignore.ts`) {
161
+ // ignore chunk will contain the vite preload code, we can ignore this chunk in the output
162
+ // See https://github.com/vitejs/vite/issues/18551
129
163
  return transformWithEsbuild(`import('/entry.tsx').then(console.log)`, id);
130
164
  }
131
165
  if (id === `\0virtual:entry.tsx`) {
@@ -200,7 +234,7 @@ async function processBundleSizes(output, entryName) {
200
234
  const manifest = JSON.parse(manifestContent);
201
235
 
202
236
  // Find the main entry point JS file in the manifest
203
- const mainEntry = Object.entries(manifest).find(([_, entry]) => entry.name === '_virtual_entry');
237
+ const mainEntry = Object.entries(manifest).find(([_, entry]) => entry.name === 'bundle');
204
238
 
205
239
  if (!mainEntry) {
206
240
  throw new Error(`No main entry found in manifest for ${entryName}`);
@@ -217,18 +251,18 @@ async function processBundleSizes(output, entryName) {
217
251
  throw new Error(`Output chunk not found for ${chunk.file}`);
218
252
  }
219
253
  const fileContent = outputChunk.code;
254
+ if (chunk.name === 'preload-helper') {
255
+ // Skip the preload-helper chunk as it is not relevant for bundle size
256
+ return null;
257
+ }
220
258
 
221
259
  // Calculate sizes
222
260
  const parsed = Buffer.byteLength(fileContent);
223
261
  const gzipBuffer = await gzipAsync(fileContent, { level: zlib.constants.Z_BEST_COMPRESSION });
224
262
  const gzipSize = Buffer.byteLength(gzipBuffer);
225
263
 
226
- if (chunk.isEntry) {
227
- return null;
228
- }
229
-
230
264
  // Use chunk key as the name, or fallback to entry name for main chunk
231
- const chunkName = chunk.name === '_virtual_entry' ? entryName : chunk.name || chunkKey;
265
+ const chunkName = chunk.name === 'bundle' ? entryName : chunk.name || chunkKey;
232
266
  return /** @type {const} */ ([chunkName, { parsed, gzip: gzipSize }]);
233
267
  });
234
268
 
@@ -240,11 +274,12 @@ async function processBundleSizes(output, entryName) {
240
274
  * Get sizes for a vite bundle
241
275
  * @param {ObjectEntry} entry - The entry configuration
242
276
  * @param {CommandLineArgs} args - Command line arguments
277
+ * @param {Record<string, string>} [replacements] - String replacements to apply
243
278
  * @returns {Promise<Map<string, SizeSnapshotEntry>>}
244
279
  */
245
- export async function getBundleSizes(entry, args) {
280
+ export async function getBundleSizes(entry, args, replacements) {
246
281
  // Create vite configuration
247
- const configuration = await createViteConfig(entry, args);
282
+ const configuration = await createViteConfig(entry, args, replacements);
248
283
 
249
284
  // Run vite build
250
285
  const { output } = /** @type {import('vite').Rollup.RollupOutput} */ (await build(configuration));
package/src/cli.js CHANGED
@@ -100,7 +100,7 @@ async function getBundleSizes(args, config) {
100
100
 
101
101
  const sizeArrays = await Promise.all(
102
102
  validEntries.map((entry, index) =>
103
- worker.run({ entry, args, index, total: validEntries.length }),
103
+ worker.run({ entry, args, index, total: validEntries.length, replace: config.replace }),
104
104
  ),
105
105
  );
106
106
 
@@ -225,6 +225,7 @@ async function applyConfigDefaults(config, configPath) {
225
225
  entrypoints: await normalizeEntries(config.entrypoints, configPath),
226
226
  upload: null, // Default to disabled
227
227
  comment: config.comment !== undefined ? config.comment : true, // Default to enabled
228
+ replace: config.replace || {}, // String replacements, default to empty object
228
229
  };
229
230
 
230
231
  // Handle different types of upload value
package/src/types.d.ts CHANGED
@@ -32,6 +32,7 @@ interface BundleSizeCheckerConfigObject {
32
32
  entrypoints: EntryPoint[];
33
33
  upload?: UploadConfig | boolean | null;
34
34
  comment?: boolean; // Whether to post PR comments (defaults to true)
35
+ replace?: Record<string, string>; // String replacements to apply during bundling
35
36
  }
36
37
 
37
38
  type BundleSizeCheckerConfig =
@@ -44,6 +45,7 @@ interface NormalizedBundleSizeCheckerConfig {
44
45
  entrypoints: ObjectEntry[];
45
46
  upload: NormalizedUploadConfig | null; // null means upload is disabled
46
47
  comment: boolean; // Whether to post PR comments
48
+ replace: Record<string, string>; // String replacements to apply during bundling
47
49
  }
48
50
 
49
51
  // Command line argument types
package/src/worker.js CHANGED
@@ -6,8 +6,6 @@ import * as module from 'node:module';
6
6
  import { byteSizeFormatter } from './formatUtils.js';
7
7
  import { getBundleSizes } from './builder.js';
8
8
 
9
- const require = module.createRequire(import.meta.url);
10
-
11
9
  const rootDir = process.cwd();
12
10
 
13
11
  /**
@@ -20,11 +18,14 @@ async function getPeerDependencies(packageName) {
20
18
  /** @type {string | undefined} */
21
19
  let packageJsonPath;
22
20
 
21
+ const rootDirUrl = pathToFileURL(rootDir);
22
+
23
23
  if (module.findPackageJSON) {
24
24
  // findPackageJSON was added in: v23.2.0, v22.14.0
25
- packageJsonPath = module.findPackageJSON(packageName, `${rootDir}/_.js`);
25
+ packageJsonPath = module.findPackageJSON(packageName, `${rootDirUrl}/index.mjs`);
26
26
  } else {
27
27
  // Try to resolve packageName/package.json
28
+ const require = module.createRequire(`${rootDirUrl}/index.mjs`);
28
29
  packageJsonPath = require.resolve(`${packageName}/package.json`, {
29
30
  paths: [rootDir],
30
31
  });
@@ -56,10 +57,10 @@ async function getPeerDependencies(packageName) {
56
57
 
57
58
  /**
58
59
  * Get sizes for a bundle
59
- * @param {{ entry: ObjectEntry, args: CommandLineArgs, index: number, total: number }} options
60
+ * @param {{ entry: ObjectEntry, args: CommandLineArgs, index: number, total: number, replace?: Record<string, string> }} options
60
61
  * @returns {Promise<Array<[string, SizeSnapshotEntry]>>}
61
62
  */
62
- export default async function getSizes({ entry, args, index, total }) {
63
+ export default async function getSizes({ entry, args, index, total, replace }) {
63
64
  // eslint-disable-next-line no-console -- process monitoring
64
65
  console.log(chalk.blue(`Compiling ${index + 1}/${total}: ${chalk.bold(`[${entry.id}]`)}`));
65
66
 
@@ -82,7 +83,7 @@ export default async function getSizes({ entry, args, index, total }) {
82
83
  }
83
84
 
84
85
  try {
85
- const sizeMap = await getBundleSizes(entry, args);
86
+ const sizeMap = await getBundleSizes(entry, args, replace);
86
87
 
87
88
  // Create a concise log message showing import details
88
89
  let entryDetails = '';