@vercel/microfrontends 2.1.3 → 2.2.1

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 (48) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +4 -0
  3. package/dist/bin/cli.cjs +207 -90
  4. package/dist/config.d.ts +2 -2
  5. package/dist/experimental/sveltekit.cjs +180 -63
  6. package/dist/experimental/sveltekit.cjs.map +1 -1
  7. package/dist/experimental/sveltekit.d.ts +6 -0
  8. package/dist/experimental/sveltekit.js +180 -63
  9. package/dist/experimental/sveltekit.js.map +1 -1
  10. package/dist/experimental/vite.cjs +177 -66
  11. package/dist/experimental/vite.cjs.map +1 -1
  12. package/dist/experimental/vite.js +177 -66
  13. package/dist/experimental/vite.js.map +1 -1
  14. package/dist/microfrontends/server.cjs +173 -60
  15. package/dist/microfrontends/server.cjs.map +1 -1
  16. package/dist/microfrontends/server.d.ts +2 -2
  17. package/dist/microfrontends/server.js +173 -60
  18. package/dist/microfrontends/server.js.map +1 -1
  19. package/dist/microfrontends/utils.cjs +50 -7
  20. package/dist/microfrontends/utils.cjs.map +1 -1
  21. package/dist/microfrontends/utils.d.ts +1 -1
  22. package/dist/microfrontends/utils.js +50 -7
  23. package/dist/microfrontends/utils.js.map +1 -1
  24. package/dist/next/config.cjs +208 -113
  25. package/dist/next/config.cjs.map +1 -1
  26. package/dist/next/config.d.ts +11 -1
  27. package/dist/next/config.js +208 -113
  28. package/dist/next/config.js.map +1 -1
  29. package/dist/next/middleware.cjs +35 -17
  30. package/dist/next/middleware.cjs.map +1 -1
  31. package/dist/next/middleware.js +35 -17
  32. package/dist/next/middleware.js.map +1 -1
  33. package/dist/next/testing.d.ts +2 -2
  34. package/dist/overrides.d.ts +3 -3
  35. package/dist/schema.d.ts +2 -2
  36. package/dist/{types-88602303.d.ts → types-b9ea41b2.d.ts} +1 -1
  37. package/dist/{types-e7523e61.d.ts → types-dcd8b17a.d.ts} +71 -24
  38. package/dist/utils/mfe-port.cjs +173 -60
  39. package/dist/utils/mfe-port.cjs.map +1 -1
  40. package/dist/utils/mfe-port.js +173 -60
  41. package/dist/utils/mfe-port.js.map +1 -1
  42. package/dist/validation.cjs +47 -38
  43. package/dist/validation.cjs.map +1 -1
  44. package/dist/validation.d.ts +1 -1
  45. package/dist/validation.js +47 -38
  46. package/dist/validation.js.map +1 -1
  47. package/package.json +1 -1
  48. package/schema/schema.json +47 -38
@@ -223,10 +223,32 @@ var import_node_fs2 = require("fs");
223
223
  var import_jsonc_parser = require("jsonc-parser");
224
224
  var import_fast_glob = __toESM(require("fast-glob"), 1);
225
225
 
226
+ // src/bin/logger.ts
227
+ function debug(...args) {
228
+ if (process.env.MFE_DEBUG) {
229
+ console.log(...args);
230
+ }
231
+ }
232
+ function info(...args) {
233
+ console.log(...args);
234
+ }
235
+ function warn(...args) {
236
+ console.warn(...args);
237
+ }
238
+ function error(...args) {
239
+ console.error(...args);
240
+ }
241
+ var logger = {
242
+ debug,
243
+ info,
244
+ warn,
245
+ error
246
+ };
247
+
226
248
  // src/config/microfrontends/utils/get-config-file-name.ts
227
249
  var DEFAULT_CONFIGURATION_FILENAMES = [
228
- "microfrontends.jsonc",
229
- "microfrontends.json"
250
+ "microfrontends.json",
251
+ "microfrontends.jsonc"
230
252
  ];
231
253
  function getPossibleConfigurationFilenames({
232
254
  customConfigFilename
@@ -234,7 +256,7 @@ function getPossibleConfigurationFilenames({
234
256
  if (customConfigFilename) {
235
257
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
236
258
  throw new Error(
237
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
259
+ `Found VC_MICROFRONTENDS_CONFIG_FILE_NAME but the name is invalid. Received: ${customConfigFilename}. The file name must end with '.json' or '.jsonc'. It's also possible for the env var to include the path, eg microfrontends-dev.json or /path/to/microfrontends-dev.json.`
238
260
  );
239
261
  }
240
262
  return Array.from(
@@ -252,6 +274,10 @@ function findPackageWithMicrofrontendsConfig({
252
274
  customConfigFilename
253
275
  }) {
254
276
  const applicationName = applicationContext.name;
277
+ logger.debug(
278
+ "[MFE Config] Searching repository for configs containing application:",
279
+ applicationName
280
+ );
255
281
  try {
256
282
  const microfrontendsJsonPaths = import_fast_glob.default.globSync(
257
283
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -263,6 +289,11 @@ function findPackageWithMicrofrontendsConfig({
263
289
  ignore: ["**/node_modules/**", "**/.git/**"]
264
290
  }
265
291
  );
292
+ logger.debug(
293
+ "[MFE Config] Found",
294
+ microfrontendsJsonPaths.length,
295
+ "config file(s) in repository"
296
+ );
266
297
  const matchingPaths = [];
267
298
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
268
299
  try {
@@ -272,19 +303,31 @@ function findPackageWithMicrofrontendsConfig({
272
303
  );
273
304
  const microfrontendsJson = (0, import_jsonc_parser.parse)(microfrontendsJsonContent);
274
305
  if (microfrontendsJson.applications[applicationName]) {
306
+ logger.debug(
307
+ "[MFE Config] Found application in config:",
308
+ microfrontendsJsonPath
309
+ );
275
310
  matchingPaths.push(microfrontendsJsonPath);
276
311
  } else {
277
312
  for (const [_, app] of Object.entries(
278
313
  microfrontendsJson.applications
279
314
  )) {
280
315
  if (app.packageName === applicationName) {
316
+ logger.debug(
317
+ "[MFE Config] Found application via packageName in config:",
318
+ microfrontendsJsonPath
319
+ );
281
320
  matchingPaths.push(microfrontendsJsonPath);
282
321
  }
283
322
  }
284
323
  }
285
- } catch (error) {
324
+ } catch (error2) {
286
325
  }
287
326
  }
327
+ logger.debug(
328
+ "[MFE Config] Total matching config files:",
329
+ matchingPaths.length
330
+ );
288
331
  if (matchingPaths.length > 1) {
289
332
  throw new MicrofrontendError(
290
333
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -318,9 +361,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
318
361
  }
319
362
  const [packageJsonPath] = matchingPaths;
320
363
  return (0, import_node_path2.dirname)(packageJsonPath);
321
- } catch (error) {
322
- if (error instanceof MicrofrontendError) {
323
- throw error;
364
+ } catch (error2) {
365
+ if (error2 instanceof MicrofrontendError) {
366
+ throw error2;
324
367
  }
325
368
  return null;
326
369
  }
@@ -365,8 +408,8 @@ function isMonorepo({
365
408
  import_node_fs3.default.readFileSync(packageJsonPath, "utf-8")
366
409
  );
367
410
  return packageJson.workspaces !== void 0;
368
- } catch (error) {
369
- console.error("Error determining if repository is a monorepo", error);
411
+ } catch (error2) {
412
+ logger.error("Error determining if repository is a monorepo", error2);
370
413
  return false;
371
414
  }
372
415
  }
@@ -1083,15 +1126,18 @@ var import_node_fs6 = __toESM(require("fs"), 1);
1083
1126
  var import_node_path6 = __toESM(require("path"), 1);
1084
1127
  function getApplicationContext(opts) {
1085
1128
  if (opts?.appName) {
1129
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1086
1130
  return { name: opts.appName };
1087
1131
  }
1088
1132
  if (process.env.VERCEL_PROJECT_NAME) {
1133
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1089
1134
  return {
1090
1135
  name: process.env.VERCEL_PROJECT_NAME,
1091
1136
  projectName: process.env.VERCEL_PROJECT_NAME
1092
1137
  };
1093
1138
  }
1094
1139
  if (process.env.NX_TASK_TARGET_PROJECT) {
1140
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1095
1141
  return {
1096
1142
  name: process.env.NX_TASK_TARGET_PROJECT,
1097
1143
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1104,6 +1150,7 @@ function getApplicationContext(opts) {
1104
1150
  );
1105
1151
  const projectJson = JSON.parse(vercelProjectJsonPath);
1106
1152
  if (projectJson.projectName) {
1153
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1107
1154
  return {
1108
1155
  name: projectJson.projectName,
1109
1156
  projectName: projectJson.projectName
@@ -1127,6 +1174,7 @@ function getApplicationContext(opts) {
1127
1174
  }
1128
1175
  );
1129
1176
  }
1177
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1130
1178
  return { name: packageJson.name, packageJsonName: packageJson.name };
1131
1179
  } catch (err) {
1132
1180
  throw MicrofrontendError.handle(err, {
@@ -1160,38 +1208,28 @@ var schema_default = {
1160
1208
  type: "object",
1161
1209
  properties: {
1162
1210
  $schema: {
1163
- type: "string"
1211
+ type: "string",
1212
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1164
1213
  },
1165
1214
  version: {
1166
1215
  type: "string",
1167
- const: "1"
1168
- },
1169
- options: {
1170
- $ref: "#/definitions/Options"
1216
+ const: "1",
1217
+ description: "The version of the microfrontends config schema."
1171
1218
  },
1172
1219
  applications: {
1173
1220
  $ref: "#/definitions/ApplicationRouting",
1174
- description: "Mapping of application names to the routes that they host. Only needs to be defined in the application that owns the primary microfrontend domain"
1221
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1222
+ },
1223
+ options: {
1224
+ $ref: "#/definitions/Options",
1225
+ description: "Optional configuration options for the microfrontend."
1175
1226
  }
1176
1227
  },
1177
1228
  required: [
1178
1229
  "applications"
1179
1230
  ],
1180
- additionalProperties: false
1181
- },
1182
- Options: {
1183
- type: "object",
1184
- properties: {
1185
- disableOverrides: {
1186
- type: "boolean",
1187
- description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect."
1188
- },
1189
- localProxyPort: {
1190
- type: "number",
1191
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1192
- }
1193
- },
1194
- additionalProperties: false
1231
+ additionalProperties: false,
1232
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1195
1233
  },
1196
1234
  ApplicationRouting: {
1197
1235
  type: "object",
@@ -1199,8 +1237,9 @@ var schema_default = {
1199
1237
  $ref: "#/definitions/Application"
1200
1238
  },
1201
1239
  propertyNames: {
1202
- description: "The unique identifier for a Microfrontend Application.\n\nMust match the Vercel project name.\n\nNote: If this name does not also match the name used to run the application, (e.g. the `name` from the `package.json`), then the `packageName` field should be set."
1203
- }
1240
+ description: "The Vercel project name of the microfrontend application.\n\nNote: If this name does not also match the name `name` from the `package.json`, set `packageName` with the name used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1241
+ },
1242
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1204
1243
  },
1205
1244
  Application: {
1206
1245
  anyOf: [
@@ -1210,14 +1249,15 @@ var schema_default = {
1210
1249
  {
1211
1250
  $ref: "#/definitions/ChildApplication"
1212
1251
  }
1213
- ]
1252
+ ],
1253
+ description: "The configuration for a microfrontend application. There must always be one default application."
1214
1254
  },
1215
1255
  DefaultApplication: {
1216
1256
  type: "object",
1217
1257
  properties: {
1218
1258
  packageName: {
1219
1259
  type: "string",
1220
- description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`."
1260
+ description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1221
1261
  },
1222
1262
  development: {
1223
1263
  $ref: "#/definitions/DefaultDevelopment",
@@ -1237,15 +1277,15 @@ var schema_default = {
1237
1277
  "number",
1238
1278
  "string"
1239
1279
  ],
1240
- description: "A local port number or host string that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTP. If omitted, the port defaults to a unique, but stable (based on the application name) number.\n\nExamples of valid values:\n- 8080\n- my.localhost.me\n- my.localhost.me:8080\n- https://my.localhost.me\n- https://my.localhost.me:8080"
1280
+ description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
1241
1281
  },
1242
1282
  task: {
1243
1283
  type: "string",
1244
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1284
+ description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
1245
1285
  },
1246
1286
  fallback: {
1247
1287
  type: "string",
1248
- description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS."
1288
+ description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1249
1289
  }
1250
1290
  },
1251
1291
  required: [
@@ -1258,7 +1298,7 @@ var schema_default = {
1258
1298
  properties: {
1259
1299
  packageName: {
1260
1300
  type: "string",
1261
- description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`."
1301
+ description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1262
1302
  },
1263
1303
  development: {
1264
1304
  $ref: "#/definitions/ChildDevelopment",
@@ -1266,11 +1306,11 @@ var schema_default = {
1266
1306
  },
1267
1307
  routing: {
1268
1308
  $ref: "#/definitions/Routing",
1269
- description: "Groups of path expressions that are routed to this application."
1309
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1270
1310
  },
1271
1311
  assetPrefix: {
1272
1312
  type: "string",
1273
- description: "The name of the asset prefix to use instead of the auto-generated name.\n\nThe asset prefix is used to prefix all paths to static assets, such as JS, CSS, or images that are served by a specific application. It is necessary to ensure there are no conflicts with other applications on the same domain.\n\nAn auto-generated asset prefix of the form `vc-ap-<hash>` is used when this field is not provided.\n\nWhen this field is provided, `/${assetPrefix}/:path*` must also be added to the list of paths in the `routing` field. Changing the asset prefix after a microfrontend application has already been deployed is not a forwards and backwards compatible change, and the asset prefix should be added to the `routing` field and deployed before setting the `assetPrefix` field."
1313
+ description: "The name of the asset prefix to use instead of the auto-generated name.\n\nThe asset prefix is used to prefix all paths to static assets, such as JS, CSS, or images that are served by a specific application. It is necessary to ensure there are no conflicts with other applications on the same domain.\n\nAn auto-generated asset prefix of the form `vc-ap-<hash>` is used when this field is not provided.\n\nWhen this field is provided, `/${assetPrefix}/:path*` must also be added to the list of paths in the `routing` field. Changing the asset prefix after a microfrontend application has already been deployed is not a forwards and backwards compatible change, and the asset prefix should be added to the `routing` field and deployed before setting the `assetPrefix` field.\n\nThe default value is the auto-generated asset prefix of the form `vc-ap-<hash>`.\n\nSee https://vercel.com/docs/microfrontends/path-routing#asset-prefix."
1274
1314
  }
1275
1315
  },
1276
1316
  required: [
@@ -1286,15 +1326,15 @@ var schema_default = {
1286
1326
  "number",
1287
1327
  "string"
1288
1328
  ],
1289
- description: "A local port number or host string that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTP. If omitted, the port defaults to a unique, but stable (based on the application name) number.\n\nExamples of valid values:\n- 8080\n- my.localhost.me\n- my.localhost.me:8080\n- https://my.localhost.me\n- https://my.localhost.me:8080"
1329
+ description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
1290
1330
  },
1291
1331
  task: {
1292
1332
  type: "string",
1293
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1333
+ description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
1294
1334
  },
1295
1335
  fallback: {
1296
1336
  type: "string",
1297
- description: "Fallback for local development, could point to any environment. This is optional for child apps. If not provided, the fallback of the default app will be used.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS."
1337
+ description: "Fallback for local development, could point to any environment. If not provided for child apps, the fallback of the default app will be used.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1298
1338
  }
1299
1339
  },
1300
1340
  additionalProperties: false
@@ -1303,29 +1343,46 @@ var schema_default = {
1303
1343
  type: "array",
1304
1344
  items: {
1305
1345
  $ref: "#/definitions/PathGroup"
1306
- }
1346
+ },
1347
+ description: "A list of path groups that are routed to this application."
1307
1348
  },
1308
1349
  PathGroup: {
1309
1350
  type: "object",
1310
1351
  properties: {
1311
1352
  group: {
1312
1353
  type: "string",
1313
- description: "Optional group name for the paths"
1354
+ description: "Group name for the paths."
1314
1355
  },
1315
1356
  flag: {
1316
1357
  type: "string",
1317
- description: "flag name that can be used to enable/disable all paths in the group"
1358
+ description: "The name of the feature flag that controls routing for this group of paths. See https://vercel.com/docs/microfrontends/path-routing#routing-changes-safely-with-flags."
1318
1359
  },
1319
1360
  paths: {
1320
1361
  type: "array",
1321
1362
  items: {
1322
1363
  type: "string"
1323
- }
1364
+ },
1365
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1324
1366
  }
1325
1367
  },
1326
1368
  required: [
1327
1369
  "paths"
1328
1370
  ],
1371
+ additionalProperties: false,
1372
+ description: "A group of paths that is routed to this application."
1373
+ },
1374
+ Options: {
1375
+ type: "object",
1376
+ properties: {
1377
+ disableOverrides: {
1378
+ type: "boolean",
1379
+ description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect.\n\nSee https://vercel.com/docs/microfrontends/managing-microfrontends/vercel-toolbar#routing-overrides."
1380
+ },
1381
+ localProxyPort: {
1382
+ type: "number",
1383
+ description: "The port number used by the local proxy server.\n\nThe default value is 3024.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1384
+ }
1385
+ },
1329
1386
  additionalProperties: false
1330
1387
  }
1331
1388
  }
@@ -1344,19 +1401,19 @@ function formatAjvErrors(errors) {
1344
1401
  return [];
1345
1402
  }
1346
1403
  const errorMessages = [];
1347
- for (const error of errors) {
1348
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1404
+ for (const error2 of errors) {
1405
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1349
1406
  continue;
1350
1407
  }
1351
- const instancePath = error.instancePath.slice(1);
1408
+ const instancePath = error2.instancePath.slice(1);
1352
1409
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1353
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1410
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1354
1411
  errorMessages.push(
1355
1412
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1356
1413
  );
1357
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1414
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1358
1415
  const anyOfErrors = errors.filter(
1359
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1416
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1360
1417
  );
1361
1418
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1362
1419
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1372,13 +1429,13 @@ function formatAjvErrors(errors) {
1372
1429
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1373
1430
  );
1374
1431
  }
1375
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1432
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1376
1433
  errorMessages.push(
1377
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1434
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1378
1435
  );
1379
- } else if (error.keyword === "required") {
1436
+ } else if (error2.keyword === "required") {
1380
1437
  errorMessages.push(
1381
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1438
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1382
1439
  );
1383
1440
  }
1384
1441
  }
@@ -1391,8 +1448,8 @@ function validateSchema(configString) {
1391
1448
  const isValid = validate(parsedConfig);
1392
1449
  if (!isValid) {
1393
1450
  throw new MicrofrontendError(
1394
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1395
- - ${error}`).join(
1451
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1452
+ - ${error2}`).join(
1396
1453
  ""
1397
1454
  )}
1398
1455
 
@@ -1489,7 +1546,13 @@ var MicrofrontendsServer = class {
1489
1546
  filePath,
1490
1547
  cookies
1491
1548
  } = {}) {
1549
+ logger.debug("[MFE Config] Starting config inference", {
1550
+ appName,
1551
+ directory: directory || process.cwd(),
1552
+ filePath
1553
+ });
1492
1554
  if (filePath) {
1555
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1493
1556
  return MicrofrontendsServer.fromFile({
1494
1557
  filePath,
1495
1558
  cookies
@@ -1497,16 +1560,25 @@ var MicrofrontendsServer = class {
1497
1560
  }
1498
1561
  try {
1499
1562
  const packageRoot = findPackageRoot(directory);
1563
+ logger.debug("[MFE Config] Package root:", packageRoot);
1500
1564
  const applicationContext = getApplicationContext({
1501
1565
  appName,
1502
1566
  packageRoot
1503
1567
  });
1568
+ logger.debug("[MFE Config] Application context:", applicationContext);
1504
1569
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1570
+ if (customConfigFilename) {
1571
+ logger.debug(
1572
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1573
+ customConfigFilename
1574
+ );
1575
+ }
1505
1576
  const maybeConfig = findConfig({
1506
1577
  dir: packageRoot,
1507
1578
  customConfigFilename
1508
1579
  });
1509
1580
  if (maybeConfig) {
1581
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1510
1582
  return MicrofrontendsServer.fromFile({
1511
1583
  filePath: maybeConfig,
1512
1584
  cookies
@@ -1514,42 +1586,78 @@ var MicrofrontendsServer = class {
1514
1586
  }
1515
1587
  const repositoryRoot = findRepositoryRoot();
1516
1588
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1589
+ logger.debug(
1590
+ "[MFE Config] Repository root:",
1591
+ repositoryRoot,
1592
+ "Is monorepo:",
1593
+ isMonorepo2
1594
+ );
1517
1595
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1518
1596
  if (typeof configFromEnv === "string") {
1597
+ logger.debug(
1598
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1599
+ configFromEnv
1600
+ );
1519
1601
  const maybeConfigFromEnv = (0, import_node_path8.resolve)(packageRoot, configFromEnv);
1520
1602
  if (maybeConfigFromEnv) {
1603
+ logger.debug(
1604
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1605
+ maybeConfigFromEnv
1606
+ );
1521
1607
  return MicrofrontendsServer.fromFile({
1522
1608
  filePath: maybeConfigFromEnv,
1523
1609
  cookies
1524
1610
  });
1525
1611
  }
1526
1612
  } else {
1613
+ const vercelDir = (0, import_node_path8.join)(packageRoot, ".vercel");
1614
+ logger.debug(
1615
+ "[MFE Config] Searching for config in .vercel directory:",
1616
+ vercelDir
1617
+ );
1527
1618
  const maybeConfigFromVercel = findConfig({
1528
- dir: (0, import_node_path8.join)(packageRoot, ".vercel"),
1619
+ dir: vercelDir,
1529
1620
  customConfigFilename
1530
1621
  });
1531
1622
  if (maybeConfigFromVercel) {
1623
+ logger.debug(
1624
+ "[MFE Config] Config found in .vercel directory:",
1625
+ maybeConfigFromVercel
1626
+ );
1532
1627
  return MicrofrontendsServer.fromFile({
1533
1628
  filePath: maybeConfigFromVercel,
1534
1629
  cookies
1535
1630
  });
1536
1631
  }
1537
1632
  if (isMonorepo2) {
1633
+ logger.debug(
1634
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1635
+ applicationContext.name
1636
+ );
1538
1637
  const defaultPackage = inferMicrofrontendsLocation({
1539
1638
  repositoryRoot,
1540
1639
  applicationContext,
1541
1640
  customConfigFilename
1542
1641
  });
1642
+ logger.debug(
1643
+ "[MFE Config] Inferred package location:",
1644
+ defaultPackage
1645
+ );
1543
1646
  const maybeConfigFromDefault = findConfig({
1544
1647
  dir: defaultPackage,
1545
1648
  customConfigFilename
1546
1649
  });
1547
1650
  if (maybeConfigFromDefault) {
1651
+ logger.debug(
1652
+ "[MFE Config] Config found in inferred package:",
1653
+ maybeConfigFromDefault
1654
+ );
1548
1655
  return MicrofrontendsServer.fromFile({
1549
1656
  filePath: maybeConfigFromDefault,
1550
1657
  cookies
1551
1658
  });
1552
1659
  }
1660
+ logger.debug("[MFE Config] No config found in inferred package");
1553
1661
  }
1554
1662
  }
1555
1663
  throw new MicrofrontendError(
@@ -1575,8 +1683,13 @@ var MicrofrontendsServer = class {
1575
1683
  cookies
1576
1684
  }) {
1577
1685
  try {
1686
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1578
1687
  const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1579
1688
  const config = MicrofrontendsServer.validate(configJson);
1689
+ logger.debug(
1690
+ "[MFE Config] Config loaded with applications:",
1691
+ Object.keys(config.applications)
1692
+ );
1580
1693
  return new MicrofrontendsServer({
1581
1694
  config,
1582
1695
  overrides: cookies ? parseOverrides(cookies) : void 0
@@ -1677,12 +1790,10 @@ function microfrontends(opts) {
1677
1790
  port: app.development.local.port
1678
1791
  };
1679
1792
  }
1680
- if (process.env.MFE_DEBUG) {
1681
- console.log(
1682
- "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1683
- additionalConfigOptions
1684
- );
1685
- }
1793
+ logger.debug(
1794
+ "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1795
+ additionalConfigOptions
1796
+ );
1686
1797
  return {
1687
1798
  name: "vite-plugin-vercel-microfrontends",
1688
1799
  config: () => {