@vercel/microfrontends 2.1.2 → 2.2.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +4 -0
  3. package/dist/bin/cli.cjs +125 -89
  4. package/dist/config.d.ts +2 -2
  5. package/dist/experimental/sveltekit.cjs +97 -62
  6. package/dist/experimental/sveltekit.cjs.map +1 -1
  7. package/dist/experimental/sveltekit.d.ts +6 -0
  8. package/dist/experimental/sveltekit.js +97 -62
  9. package/dist/experimental/sveltekit.js.map +1 -1
  10. package/dist/experimental/vite.cjs +96 -65
  11. package/dist/experimental/vite.cjs.map +1 -1
  12. package/dist/experimental/vite.js +96 -65
  13. package/dist/experimental/vite.js.map +1 -1
  14. package/dist/microfrontends/server.cjs +92 -59
  15. package/dist/microfrontends/server.cjs.map +1 -1
  16. package/dist/microfrontends/server.d.ts +2 -2
  17. package/dist/microfrontends/server.js +92 -59
  18. package/dist/microfrontends/server.js.map +1 -1
  19. package/dist/microfrontends/utils.cjs +3 -3
  20. package/dist/microfrontends/utils.cjs.map +1 -1
  21. package/dist/microfrontends/utils.d.ts +1 -1
  22. package/dist/microfrontends/utils.js +3 -3
  23. package/dist/microfrontends/utils.js.map +1 -1
  24. package/dist/next/config.cjs +133 -115
  25. package/dist/next/config.cjs.map +1 -1
  26. package/dist/next/config.d.ts +11 -1
  27. package/dist/next/config.js +133 -115
  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 +92 -59
  39. package/dist/utils/mfe-port.cjs.map +1 -1
  40. package/dist/utils/mfe-port.js +92 -59
  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
@@ -227,8 +227,8 @@ var import_fast_glob = __toESM(require("fast-glob"), 1);
227
227
 
228
228
  // src/config/microfrontends/utils/get-config-file-name.ts
229
229
  var DEFAULT_CONFIGURATION_FILENAMES = [
230
- "microfrontends.jsonc",
231
- "microfrontends.json"
230
+ "microfrontends.json",
231
+ "microfrontends.jsonc"
232
232
  ];
233
233
  function getPossibleConfigurationFilenames({
234
234
  customConfigFilename
@@ -236,7 +236,7 @@ function getPossibleConfigurationFilenames({
236
236
  if (customConfigFilename) {
237
237
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
238
238
  throw new Error(
239
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
239
+ `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.`
240
240
  );
241
241
  }
242
242
  return Array.from(
@@ -284,7 +284,7 @@ function findPackageWithMicrofrontendsConfig({
284
284
  }
285
285
  }
286
286
  }
287
- } catch (error) {
287
+ } catch (error2) {
288
288
  }
289
289
  }
290
290
  if (matchingPaths.length > 1) {
@@ -320,9 +320,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
320
320
  }
321
321
  const [packageJsonPath] = matchingPaths;
322
322
  return (0, import_node_path2.dirname)(packageJsonPath);
323
- } catch (error) {
324
- if (error instanceof MicrofrontendError) {
325
- throw error;
323
+ } catch (error2) {
324
+ if (error2 instanceof MicrofrontendError) {
325
+ throw error2;
326
326
  }
327
327
  return null;
328
328
  }
@@ -346,6 +346,30 @@ function inferMicrofrontendsLocation(opts) {
346
346
  // src/config/microfrontends/utils/is-monorepo.ts
347
347
  var import_node_fs3 = __toESM(require("fs"), 1);
348
348
  var import_node_path3 = __toESM(require("path"), 1);
349
+
350
+ // src/bin/logger.ts
351
+ function debug(...args) {
352
+ if (process.env.MFE_DEBUG) {
353
+ console.log(...args);
354
+ }
355
+ }
356
+ function info(...args) {
357
+ console.log(...args);
358
+ }
359
+ function warn(...args) {
360
+ console.warn(...args);
361
+ }
362
+ function error(...args) {
363
+ console.error(...args);
364
+ }
365
+ var logger = {
366
+ debug,
367
+ info,
368
+ warn,
369
+ error
370
+ };
371
+
372
+ // src/config/microfrontends/utils/is-monorepo.ts
349
373
  function isMonorepo({
350
374
  repositoryRoot
351
375
  }) {
@@ -367,8 +391,8 @@ function isMonorepo({
367
391
  import_node_fs3.default.readFileSync(packageJsonPath, "utf-8")
368
392
  );
369
393
  return packageJson.workspaces !== void 0;
370
- } catch (error) {
371
- console.error("Error determining if repository is a monorepo", error);
394
+ } catch (error2) {
395
+ logger.error("Error determining if repository is a monorepo", error2);
372
396
  return false;
373
397
  }
374
398
  }
@@ -1162,38 +1186,28 @@ var schema_default = {
1162
1186
  type: "object",
1163
1187
  properties: {
1164
1188
  $schema: {
1165
- type: "string"
1189
+ type: "string",
1190
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1166
1191
  },
1167
1192
  version: {
1168
1193
  type: "string",
1169
- const: "1"
1170
- },
1171
- options: {
1172
- $ref: "#/definitions/Options"
1194
+ const: "1",
1195
+ description: "The version of the microfrontends config schema."
1173
1196
  },
1174
1197
  applications: {
1175
1198
  $ref: "#/definitions/ApplicationRouting",
1176
- 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"
1199
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1200
+ },
1201
+ options: {
1202
+ $ref: "#/definitions/Options",
1203
+ description: "Optional configuration options for the microfrontend."
1177
1204
  }
1178
1205
  },
1179
1206
  required: [
1180
1207
  "applications"
1181
1208
  ],
1182
- additionalProperties: false
1183
- },
1184
- Options: {
1185
- type: "object",
1186
- properties: {
1187
- disableOverrides: {
1188
- type: "boolean",
1189
- 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."
1190
- },
1191
- localProxyPort: {
1192
- type: "number",
1193
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1194
- }
1195
- },
1196
- additionalProperties: false
1209
+ additionalProperties: false,
1210
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1197
1211
  },
1198
1212
  ApplicationRouting: {
1199
1213
  type: "object",
@@ -1201,8 +1215,9 @@ var schema_default = {
1201
1215
  $ref: "#/definitions/Application"
1202
1216
  },
1203
1217
  propertyNames: {
1204
- 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."
1205
- }
1218
+ 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."
1219
+ },
1220
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1206
1221
  },
1207
1222
  Application: {
1208
1223
  anyOf: [
@@ -1212,14 +1227,15 @@ var schema_default = {
1212
1227
  {
1213
1228
  $ref: "#/definitions/ChildApplication"
1214
1229
  }
1215
- ]
1230
+ ],
1231
+ description: "The configuration for a microfrontend application. There must always be one default application."
1216
1232
  },
1217
1233
  DefaultApplication: {
1218
1234
  type: "object",
1219
1235
  properties: {
1220
1236
  packageName: {
1221
1237
  type: "string",
1222
- 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`."
1238
+ 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."
1223
1239
  },
1224
1240
  development: {
1225
1241
  $ref: "#/definitions/DefaultDevelopment",
@@ -1239,15 +1255,15 @@ var schema_default = {
1239
1255
  "number",
1240
1256
  "string"
1241
1257
  ],
1242
- 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"
1258
+ 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."
1243
1259
  },
1244
1260
  task: {
1245
1261
  type: "string",
1246
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1262
+ 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.'
1247
1263
  },
1248
1264
  fallback: {
1249
1265
  type: "string",
1250
- 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."
1266
+ 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."
1251
1267
  }
1252
1268
  },
1253
1269
  required: [
@@ -1260,7 +1276,7 @@ var schema_default = {
1260
1276
  properties: {
1261
1277
  packageName: {
1262
1278
  type: "string",
1263
- 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`."
1279
+ 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."
1264
1280
  },
1265
1281
  development: {
1266
1282
  $ref: "#/definitions/ChildDevelopment",
@@ -1268,11 +1284,11 @@ var schema_default = {
1268
1284
  },
1269
1285
  routing: {
1270
1286
  $ref: "#/definitions/Routing",
1271
- description: "Groups of path expressions that are routed to this application."
1287
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1272
1288
  },
1273
1289
  assetPrefix: {
1274
1290
  type: "string",
1275
- 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."
1291
+ 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."
1276
1292
  }
1277
1293
  },
1278
1294
  required: [
@@ -1288,15 +1304,15 @@ var schema_default = {
1288
1304
  "number",
1289
1305
  "string"
1290
1306
  ],
1291
- 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"
1307
+ 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."
1292
1308
  },
1293
1309
  task: {
1294
1310
  type: "string",
1295
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1311
+ 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.'
1296
1312
  },
1297
1313
  fallback: {
1298
1314
  type: "string",
1299
- 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."
1315
+ 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."
1300
1316
  }
1301
1317
  },
1302
1318
  additionalProperties: false
@@ -1305,29 +1321,46 @@ var schema_default = {
1305
1321
  type: "array",
1306
1322
  items: {
1307
1323
  $ref: "#/definitions/PathGroup"
1308
- }
1324
+ },
1325
+ description: "A list of path groups that are routed to this application."
1309
1326
  },
1310
1327
  PathGroup: {
1311
1328
  type: "object",
1312
1329
  properties: {
1313
1330
  group: {
1314
1331
  type: "string",
1315
- description: "Optional group name for the paths"
1332
+ description: "Group name for the paths."
1316
1333
  },
1317
1334
  flag: {
1318
1335
  type: "string",
1319
- description: "flag name that can be used to enable/disable all paths in the group"
1336
+ 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."
1320
1337
  },
1321
1338
  paths: {
1322
1339
  type: "array",
1323
1340
  items: {
1324
1341
  type: "string"
1325
- }
1342
+ },
1343
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1326
1344
  }
1327
1345
  },
1328
1346
  required: [
1329
1347
  "paths"
1330
1348
  ],
1349
+ additionalProperties: false,
1350
+ description: "A group of paths that is routed to this application."
1351
+ },
1352
+ Options: {
1353
+ type: "object",
1354
+ properties: {
1355
+ disableOverrides: {
1356
+ type: "boolean",
1357
+ 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."
1358
+ },
1359
+ localProxyPort: {
1360
+ type: "number",
1361
+ 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."
1362
+ }
1363
+ },
1331
1364
  additionalProperties: false
1332
1365
  }
1333
1366
  }
@@ -1346,19 +1379,19 @@ function formatAjvErrors(errors) {
1346
1379
  return [];
1347
1380
  }
1348
1381
  const errorMessages = [];
1349
- for (const error of errors) {
1350
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1382
+ for (const error2 of errors) {
1383
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1351
1384
  continue;
1352
1385
  }
1353
- const instancePath = error.instancePath.slice(1);
1386
+ const instancePath = error2.instancePath.slice(1);
1354
1387
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1355
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1388
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1356
1389
  errorMessages.push(
1357
1390
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1358
1391
  );
1359
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1392
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1360
1393
  const anyOfErrors = errors.filter(
1361
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1394
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1362
1395
  );
1363
1396
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1364
1397
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1374,13 +1407,13 @@ function formatAjvErrors(errors) {
1374
1407
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1375
1408
  );
1376
1409
  }
1377
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1410
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1378
1411
  errorMessages.push(
1379
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1412
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1380
1413
  );
1381
- } else if (error.keyword === "required") {
1414
+ } else if (error2.keyword === "required") {
1382
1415
  errorMessages.push(
1383
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1416
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1384
1417
  );
1385
1418
  }
1386
1419
  }
@@ -1393,8 +1426,8 @@ function validateSchema(configString) {
1393
1426
  const isValid = validate(parsedConfig);
1394
1427
  if (!isValid) {
1395
1428
  throw new MicrofrontendError(
1396
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1397
- - ${error}`).join(
1429
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1430
+ - ${error2}`).join(
1398
1431
  ""
1399
1432
  )}
1400
1433