@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
@@ -187,10 +187,32 @@ import { readFileSync } from "node:fs";
187
187
  import { parse } from "jsonc-parser";
188
188
  import fg from "fast-glob";
189
189
 
190
+ // src/bin/logger.ts
191
+ function debug(...args) {
192
+ if (process.env.MFE_DEBUG) {
193
+ console.log(...args);
194
+ }
195
+ }
196
+ function info(...args) {
197
+ console.log(...args);
198
+ }
199
+ function warn(...args) {
200
+ console.warn(...args);
201
+ }
202
+ function error(...args) {
203
+ console.error(...args);
204
+ }
205
+ var logger = {
206
+ debug,
207
+ info,
208
+ warn,
209
+ error
210
+ };
211
+
190
212
  // src/config/microfrontends/utils/get-config-file-name.ts
191
213
  var DEFAULT_CONFIGURATION_FILENAMES = [
192
- "microfrontends.jsonc",
193
- "microfrontends.json"
214
+ "microfrontends.json",
215
+ "microfrontends.jsonc"
194
216
  ];
195
217
  function getPossibleConfigurationFilenames({
196
218
  customConfigFilename
@@ -198,7 +220,7 @@ function getPossibleConfigurationFilenames({
198
220
  if (customConfigFilename) {
199
221
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
200
222
  throw new Error(
201
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
223
+ `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.`
202
224
  );
203
225
  }
204
226
  return Array.from(
@@ -216,6 +238,10 @@ function findPackageWithMicrofrontendsConfig({
216
238
  customConfigFilename
217
239
  }) {
218
240
  const applicationName = applicationContext.name;
241
+ logger.debug(
242
+ "[MFE Config] Searching repository for configs containing application:",
243
+ applicationName
244
+ );
219
245
  try {
220
246
  const microfrontendsJsonPaths = fg.globSync(
221
247
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -227,6 +253,11 @@ function findPackageWithMicrofrontendsConfig({
227
253
  ignore: ["**/node_modules/**", "**/.git/**"]
228
254
  }
229
255
  );
256
+ logger.debug(
257
+ "[MFE Config] Found",
258
+ microfrontendsJsonPaths.length,
259
+ "config file(s) in repository"
260
+ );
230
261
  const matchingPaths = [];
231
262
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
232
263
  try {
@@ -236,19 +267,31 @@ function findPackageWithMicrofrontendsConfig({
236
267
  );
237
268
  const microfrontendsJson = parse(microfrontendsJsonContent);
238
269
  if (microfrontendsJson.applications[applicationName]) {
270
+ logger.debug(
271
+ "[MFE Config] Found application in config:",
272
+ microfrontendsJsonPath
273
+ );
239
274
  matchingPaths.push(microfrontendsJsonPath);
240
275
  } else {
241
276
  for (const [_, app] of Object.entries(
242
277
  microfrontendsJson.applications
243
278
  )) {
244
279
  if (app.packageName === applicationName) {
280
+ logger.debug(
281
+ "[MFE Config] Found application via packageName in config:",
282
+ microfrontendsJsonPath
283
+ );
245
284
  matchingPaths.push(microfrontendsJsonPath);
246
285
  }
247
286
  }
248
287
  }
249
- } catch (error) {
288
+ } catch (error2) {
250
289
  }
251
290
  }
291
+ logger.debug(
292
+ "[MFE Config] Total matching config files:",
293
+ matchingPaths.length
294
+ );
252
295
  if (matchingPaths.length > 1) {
253
296
  throw new MicrofrontendError(
254
297
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -282,9 +325,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
282
325
  }
283
326
  const [packageJsonPath] = matchingPaths;
284
327
  return dirname(packageJsonPath);
285
- } catch (error) {
286
- if (error instanceof MicrofrontendError) {
287
- throw error;
328
+ } catch (error2) {
329
+ if (error2 instanceof MicrofrontendError) {
330
+ throw error2;
288
331
  }
289
332
  return null;
290
333
  }
@@ -329,8 +372,8 @@ function isMonorepo({
329
372
  fs2.readFileSync(packageJsonPath, "utf-8")
330
373
  );
331
374
  return packageJson.workspaces !== void 0;
332
- } catch (error) {
333
- console.error("Error determining if repository is a monorepo", error);
375
+ } catch (error2) {
376
+ logger.error("Error determining if repository is a monorepo", error2);
334
377
  return false;
335
378
  }
336
379
  }
@@ -1047,15 +1090,18 @@ import fs5 from "node:fs";
1047
1090
  import path4 from "node:path";
1048
1091
  function getApplicationContext(opts) {
1049
1092
  if (opts?.appName) {
1093
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1050
1094
  return { name: opts.appName };
1051
1095
  }
1052
1096
  if (process.env.VERCEL_PROJECT_NAME) {
1097
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1053
1098
  return {
1054
1099
  name: process.env.VERCEL_PROJECT_NAME,
1055
1100
  projectName: process.env.VERCEL_PROJECT_NAME
1056
1101
  };
1057
1102
  }
1058
1103
  if (process.env.NX_TASK_TARGET_PROJECT) {
1104
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1059
1105
  return {
1060
1106
  name: process.env.NX_TASK_TARGET_PROJECT,
1061
1107
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1068,6 +1114,7 @@ function getApplicationContext(opts) {
1068
1114
  );
1069
1115
  const projectJson = JSON.parse(vercelProjectJsonPath);
1070
1116
  if (projectJson.projectName) {
1117
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1071
1118
  return {
1072
1119
  name: projectJson.projectName,
1073
1120
  projectName: projectJson.projectName
@@ -1091,6 +1138,7 @@ function getApplicationContext(opts) {
1091
1138
  }
1092
1139
  );
1093
1140
  }
1141
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1094
1142
  return { name: packageJson.name, packageJsonName: packageJson.name };
1095
1143
  } catch (err) {
1096
1144
  throw MicrofrontendError.handle(err, {
@@ -1124,38 +1172,28 @@ var schema_default = {
1124
1172
  type: "object",
1125
1173
  properties: {
1126
1174
  $schema: {
1127
- type: "string"
1175
+ type: "string",
1176
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1128
1177
  },
1129
1178
  version: {
1130
1179
  type: "string",
1131
- const: "1"
1132
- },
1133
- options: {
1134
- $ref: "#/definitions/Options"
1180
+ const: "1",
1181
+ description: "The version of the microfrontends config schema."
1135
1182
  },
1136
1183
  applications: {
1137
1184
  $ref: "#/definitions/ApplicationRouting",
1138
- 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"
1185
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1186
+ },
1187
+ options: {
1188
+ $ref: "#/definitions/Options",
1189
+ description: "Optional configuration options for the microfrontend."
1139
1190
  }
1140
1191
  },
1141
1192
  required: [
1142
1193
  "applications"
1143
1194
  ],
1144
- additionalProperties: false
1145
- },
1146
- Options: {
1147
- type: "object",
1148
- properties: {
1149
- disableOverrides: {
1150
- type: "boolean",
1151
- 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."
1152
- },
1153
- localProxyPort: {
1154
- type: "number",
1155
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1156
- }
1157
- },
1158
- additionalProperties: false
1195
+ additionalProperties: false,
1196
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1159
1197
  },
1160
1198
  ApplicationRouting: {
1161
1199
  type: "object",
@@ -1163,8 +1201,9 @@ var schema_default = {
1163
1201
  $ref: "#/definitions/Application"
1164
1202
  },
1165
1203
  propertyNames: {
1166
- 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."
1167
- }
1204
+ 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."
1205
+ },
1206
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1168
1207
  },
1169
1208
  Application: {
1170
1209
  anyOf: [
@@ -1174,14 +1213,15 @@ var schema_default = {
1174
1213
  {
1175
1214
  $ref: "#/definitions/ChildApplication"
1176
1215
  }
1177
- ]
1216
+ ],
1217
+ description: "The configuration for a microfrontend application. There must always be one default application."
1178
1218
  },
1179
1219
  DefaultApplication: {
1180
1220
  type: "object",
1181
1221
  properties: {
1182
1222
  packageName: {
1183
1223
  type: "string",
1184
- 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`."
1224
+ 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."
1185
1225
  },
1186
1226
  development: {
1187
1227
  $ref: "#/definitions/DefaultDevelopment",
@@ -1201,15 +1241,15 @@ var schema_default = {
1201
1241
  "number",
1202
1242
  "string"
1203
1243
  ],
1204
- 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"
1244
+ 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."
1205
1245
  },
1206
1246
  task: {
1207
1247
  type: "string",
1208
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1248
+ 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.'
1209
1249
  },
1210
1250
  fallback: {
1211
1251
  type: "string",
1212
- 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."
1252
+ 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."
1213
1253
  }
1214
1254
  },
1215
1255
  required: [
@@ -1222,7 +1262,7 @@ var schema_default = {
1222
1262
  properties: {
1223
1263
  packageName: {
1224
1264
  type: "string",
1225
- 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`."
1265
+ 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."
1226
1266
  },
1227
1267
  development: {
1228
1268
  $ref: "#/definitions/ChildDevelopment",
@@ -1230,11 +1270,11 @@ var schema_default = {
1230
1270
  },
1231
1271
  routing: {
1232
1272
  $ref: "#/definitions/Routing",
1233
- description: "Groups of path expressions that are routed to this application."
1273
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1234
1274
  },
1235
1275
  assetPrefix: {
1236
1276
  type: "string",
1237
- 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."
1277
+ 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."
1238
1278
  }
1239
1279
  },
1240
1280
  required: [
@@ -1250,15 +1290,15 @@ var schema_default = {
1250
1290
  "number",
1251
1291
  "string"
1252
1292
  ],
1253
- 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"
1293
+ 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."
1254
1294
  },
1255
1295
  task: {
1256
1296
  type: "string",
1257
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1297
+ 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.'
1258
1298
  },
1259
1299
  fallback: {
1260
1300
  type: "string",
1261
- 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."
1301
+ 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."
1262
1302
  }
1263
1303
  },
1264
1304
  additionalProperties: false
@@ -1267,29 +1307,46 @@ var schema_default = {
1267
1307
  type: "array",
1268
1308
  items: {
1269
1309
  $ref: "#/definitions/PathGroup"
1270
- }
1310
+ },
1311
+ description: "A list of path groups that are routed to this application."
1271
1312
  },
1272
1313
  PathGroup: {
1273
1314
  type: "object",
1274
1315
  properties: {
1275
1316
  group: {
1276
1317
  type: "string",
1277
- description: "Optional group name for the paths"
1318
+ description: "Group name for the paths."
1278
1319
  },
1279
1320
  flag: {
1280
1321
  type: "string",
1281
- description: "flag name that can be used to enable/disable all paths in the group"
1322
+ 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."
1282
1323
  },
1283
1324
  paths: {
1284
1325
  type: "array",
1285
1326
  items: {
1286
1327
  type: "string"
1287
- }
1328
+ },
1329
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1288
1330
  }
1289
1331
  },
1290
1332
  required: [
1291
1333
  "paths"
1292
1334
  ],
1335
+ additionalProperties: false,
1336
+ description: "A group of paths that is routed to this application."
1337
+ },
1338
+ Options: {
1339
+ type: "object",
1340
+ properties: {
1341
+ disableOverrides: {
1342
+ type: "boolean",
1343
+ 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."
1344
+ },
1345
+ localProxyPort: {
1346
+ type: "number",
1347
+ 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."
1348
+ }
1349
+ },
1293
1350
  additionalProperties: false
1294
1351
  }
1295
1352
  }
@@ -1308,19 +1365,19 @@ function formatAjvErrors(errors) {
1308
1365
  return [];
1309
1366
  }
1310
1367
  const errorMessages = [];
1311
- for (const error of errors) {
1312
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1368
+ for (const error2 of errors) {
1369
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1313
1370
  continue;
1314
1371
  }
1315
- const instancePath = error.instancePath.slice(1);
1372
+ const instancePath = error2.instancePath.slice(1);
1316
1373
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1317
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1374
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1318
1375
  errorMessages.push(
1319
1376
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1320
1377
  );
1321
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1378
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1322
1379
  const anyOfErrors = errors.filter(
1323
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1380
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1324
1381
  );
1325
1382
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1326
1383
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1336,13 +1393,13 @@ function formatAjvErrors(errors) {
1336
1393
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1337
1394
  );
1338
1395
  }
1339
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1396
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1340
1397
  errorMessages.push(
1341
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1398
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1342
1399
  );
1343
- } else if (error.keyword === "required") {
1400
+ } else if (error2.keyword === "required") {
1344
1401
  errorMessages.push(
1345
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1402
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1346
1403
  );
1347
1404
  }
1348
1405
  }
@@ -1355,8 +1412,8 @@ function validateSchema(configString) {
1355
1412
  const isValid = validate(parsedConfig);
1356
1413
  if (!isValid) {
1357
1414
  throw new MicrofrontendError(
1358
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1359
- - ${error}`).join(
1415
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1416
+ - ${error2}`).join(
1360
1417
  ""
1361
1418
  )}
1362
1419
 
@@ -1453,7 +1510,13 @@ var MicrofrontendsServer = class {
1453
1510
  filePath,
1454
1511
  cookies
1455
1512
  } = {}) {
1513
+ logger.debug("[MFE Config] Starting config inference", {
1514
+ appName,
1515
+ directory: directory || process.cwd(),
1516
+ filePath
1517
+ });
1456
1518
  if (filePath) {
1519
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1457
1520
  return MicrofrontendsServer.fromFile({
1458
1521
  filePath,
1459
1522
  cookies
@@ -1461,16 +1524,25 @@ var MicrofrontendsServer = class {
1461
1524
  }
1462
1525
  try {
1463
1526
  const packageRoot = findPackageRoot(directory);
1527
+ logger.debug("[MFE Config] Package root:", packageRoot);
1464
1528
  const applicationContext = getApplicationContext({
1465
1529
  appName,
1466
1530
  packageRoot
1467
1531
  });
1532
+ logger.debug("[MFE Config] Application context:", applicationContext);
1468
1533
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1534
+ if (customConfigFilename) {
1535
+ logger.debug(
1536
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1537
+ customConfigFilename
1538
+ );
1539
+ }
1469
1540
  const maybeConfig = findConfig({
1470
1541
  dir: packageRoot,
1471
1542
  customConfigFilename
1472
1543
  });
1473
1544
  if (maybeConfig) {
1545
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1474
1546
  return MicrofrontendsServer.fromFile({
1475
1547
  filePath: maybeConfig,
1476
1548
  cookies
@@ -1478,42 +1550,78 @@ var MicrofrontendsServer = class {
1478
1550
  }
1479
1551
  const repositoryRoot = findRepositoryRoot();
1480
1552
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1553
+ logger.debug(
1554
+ "[MFE Config] Repository root:",
1555
+ repositoryRoot,
1556
+ "Is monorepo:",
1557
+ isMonorepo2
1558
+ );
1481
1559
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1482
1560
  if (typeof configFromEnv === "string") {
1561
+ logger.debug(
1562
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1563
+ configFromEnv
1564
+ );
1483
1565
  const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1484
1566
  if (maybeConfigFromEnv) {
1567
+ logger.debug(
1568
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1569
+ maybeConfigFromEnv
1570
+ );
1485
1571
  return MicrofrontendsServer.fromFile({
1486
1572
  filePath: maybeConfigFromEnv,
1487
1573
  cookies
1488
1574
  });
1489
1575
  }
1490
1576
  } else {
1577
+ const vercelDir = join2(packageRoot, ".vercel");
1578
+ logger.debug(
1579
+ "[MFE Config] Searching for config in .vercel directory:",
1580
+ vercelDir
1581
+ );
1491
1582
  const maybeConfigFromVercel = findConfig({
1492
- dir: join2(packageRoot, ".vercel"),
1583
+ dir: vercelDir,
1493
1584
  customConfigFilename
1494
1585
  });
1495
1586
  if (maybeConfigFromVercel) {
1587
+ logger.debug(
1588
+ "[MFE Config] Config found in .vercel directory:",
1589
+ maybeConfigFromVercel
1590
+ );
1496
1591
  return MicrofrontendsServer.fromFile({
1497
1592
  filePath: maybeConfigFromVercel,
1498
1593
  cookies
1499
1594
  });
1500
1595
  }
1501
1596
  if (isMonorepo2) {
1597
+ logger.debug(
1598
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1599
+ applicationContext.name
1600
+ );
1502
1601
  const defaultPackage = inferMicrofrontendsLocation({
1503
1602
  repositoryRoot,
1504
1603
  applicationContext,
1505
1604
  customConfigFilename
1506
1605
  });
1606
+ logger.debug(
1607
+ "[MFE Config] Inferred package location:",
1608
+ defaultPackage
1609
+ );
1507
1610
  const maybeConfigFromDefault = findConfig({
1508
1611
  dir: defaultPackage,
1509
1612
  customConfigFilename
1510
1613
  });
1511
1614
  if (maybeConfigFromDefault) {
1615
+ logger.debug(
1616
+ "[MFE Config] Config found in inferred package:",
1617
+ maybeConfigFromDefault
1618
+ );
1512
1619
  return MicrofrontendsServer.fromFile({
1513
1620
  filePath: maybeConfigFromDefault,
1514
1621
  cookies
1515
1622
  });
1516
1623
  }
1624
+ logger.debug("[MFE Config] No config found in inferred package");
1517
1625
  }
1518
1626
  }
1519
1627
  throw new MicrofrontendError(
@@ -1539,8 +1647,13 @@ var MicrofrontendsServer = class {
1539
1647
  cookies
1540
1648
  }) {
1541
1649
  try {
1650
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1542
1651
  const configJson = fs6.readFileSync(filePath, "utf-8");
1543
1652
  const config = MicrofrontendsServer.validate(configJson);
1653
+ logger.debug(
1654
+ "[MFE Config] Config loaded with applications:",
1655
+ Object.keys(config.applications)
1656
+ );
1544
1657
  return new MicrofrontendsServer({
1545
1658
  config,
1546
1659
  overrides: cookies ? parseOverrides(cookies) : void 0
@@ -1641,12 +1754,10 @@ function microfrontends(opts) {
1641
1754
  port: app.development.local.port
1642
1755
  };
1643
1756
  }
1644
- if (process.env.MFE_DEBUG) {
1645
- console.log(
1646
- "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1647
- additionalConfigOptions
1648
- );
1649
- }
1757
+ logger.debug(
1758
+ "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1759
+ additionalConfigOptions
1760
+ );
1650
1761
  return {
1651
1762
  name: "vite-plugin-vercel-microfrontends",
1652
1763
  config: () => {