@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
@@ -193,8 +193,8 @@ import fg from "fast-glob";
193
193
 
194
194
  // src/config/microfrontends/utils/get-config-file-name.ts
195
195
  var DEFAULT_CONFIGURATION_FILENAMES = [
196
- "microfrontends.jsonc",
197
- "microfrontends.json"
196
+ "microfrontends.json",
197
+ "microfrontends.jsonc"
198
198
  ];
199
199
  function getPossibleConfigurationFilenames({
200
200
  customConfigFilename
@@ -202,7 +202,7 @@ function getPossibleConfigurationFilenames({
202
202
  if (customConfigFilename) {
203
203
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
204
204
  throw new Error(
205
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
205
+ `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.`
206
206
  );
207
207
  }
208
208
  return Array.from(
@@ -250,7 +250,7 @@ function findPackageWithMicrofrontendsConfig({
250
250
  }
251
251
  }
252
252
  }
253
- } catch (error) {
253
+ } catch (error2) {
254
254
  }
255
255
  }
256
256
  if (matchingPaths.length > 1) {
@@ -286,9 +286,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
286
286
  }
287
287
  const [packageJsonPath] = matchingPaths;
288
288
  return dirname(packageJsonPath);
289
- } catch (error) {
290
- if (error instanceof MicrofrontendError) {
291
- throw error;
289
+ } catch (error2) {
290
+ if (error2 instanceof MicrofrontendError) {
291
+ throw error2;
292
292
  }
293
293
  return null;
294
294
  }
@@ -312,6 +312,30 @@ function inferMicrofrontendsLocation(opts) {
312
312
  // src/config/microfrontends/utils/is-monorepo.ts
313
313
  import fs2 from "node:fs";
314
314
  import path2 from "node:path";
315
+
316
+ // src/bin/logger.ts
317
+ function debug(...args) {
318
+ if (process.env.MFE_DEBUG) {
319
+ console.log(...args);
320
+ }
321
+ }
322
+ function info(...args) {
323
+ console.log(...args);
324
+ }
325
+ function warn(...args) {
326
+ console.warn(...args);
327
+ }
328
+ function error(...args) {
329
+ console.error(...args);
330
+ }
331
+ var logger = {
332
+ debug,
333
+ info,
334
+ warn,
335
+ error
336
+ };
337
+
338
+ // src/config/microfrontends/utils/is-monorepo.ts
315
339
  function isMonorepo({
316
340
  repositoryRoot
317
341
  }) {
@@ -333,8 +357,8 @@ function isMonorepo({
333
357
  fs2.readFileSync(packageJsonPath, "utf-8")
334
358
  );
335
359
  return packageJson.workspaces !== void 0;
336
- } catch (error) {
337
- console.error("Error determining if repository is a monorepo", error);
360
+ } catch (error2) {
361
+ logger.error("Error determining if repository is a monorepo", error2);
338
362
  return false;
339
363
  }
340
364
  }
@@ -1128,38 +1152,28 @@ var schema_default = {
1128
1152
  type: "object",
1129
1153
  properties: {
1130
1154
  $schema: {
1131
- type: "string"
1155
+ type: "string",
1156
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1132
1157
  },
1133
1158
  version: {
1134
1159
  type: "string",
1135
- const: "1"
1136
- },
1137
- options: {
1138
- $ref: "#/definitions/Options"
1160
+ const: "1",
1161
+ description: "The version of the microfrontends config schema."
1139
1162
  },
1140
1163
  applications: {
1141
1164
  $ref: "#/definitions/ApplicationRouting",
1142
- 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"
1165
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1166
+ },
1167
+ options: {
1168
+ $ref: "#/definitions/Options",
1169
+ description: "Optional configuration options for the microfrontend."
1143
1170
  }
1144
1171
  },
1145
1172
  required: [
1146
1173
  "applications"
1147
1174
  ],
1148
- additionalProperties: false
1149
- },
1150
- Options: {
1151
- type: "object",
1152
- properties: {
1153
- disableOverrides: {
1154
- type: "boolean",
1155
- 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."
1156
- },
1157
- localProxyPort: {
1158
- type: "number",
1159
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1160
- }
1161
- },
1162
- additionalProperties: false
1175
+ additionalProperties: false,
1176
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1163
1177
  },
1164
1178
  ApplicationRouting: {
1165
1179
  type: "object",
@@ -1167,8 +1181,9 @@ var schema_default = {
1167
1181
  $ref: "#/definitions/Application"
1168
1182
  },
1169
1183
  propertyNames: {
1170
- 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."
1171
- }
1184
+ 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."
1185
+ },
1186
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1172
1187
  },
1173
1188
  Application: {
1174
1189
  anyOf: [
@@ -1178,14 +1193,15 @@ var schema_default = {
1178
1193
  {
1179
1194
  $ref: "#/definitions/ChildApplication"
1180
1195
  }
1181
- ]
1196
+ ],
1197
+ description: "The configuration for a microfrontend application. There must always be one default application."
1182
1198
  },
1183
1199
  DefaultApplication: {
1184
1200
  type: "object",
1185
1201
  properties: {
1186
1202
  packageName: {
1187
1203
  type: "string",
1188
- 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`."
1204
+ 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."
1189
1205
  },
1190
1206
  development: {
1191
1207
  $ref: "#/definitions/DefaultDevelopment",
@@ -1205,15 +1221,15 @@ var schema_default = {
1205
1221
  "number",
1206
1222
  "string"
1207
1223
  ],
1208
- 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"
1224
+ 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."
1209
1225
  },
1210
1226
  task: {
1211
1227
  type: "string",
1212
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1228
+ 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.'
1213
1229
  },
1214
1230
  fallback: {
1215
1231
  type: "string",
1216
- 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."
1232
+ 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."
1217
1233
  }
1218
1234
  },
1219
1235
  required: [
@@ -1226,7 +1242,7 @@ var schema_default = {
1226
1242
  properties: {
1227
1243
  packageName: {
1228
1244
  type: "string",
1229
- 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`."
1245
+ 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."
1230
1246
  },
1231
1247
  development: {
1232
1248
  $ref: "#/definitions/ChildDevelopment",
@@ -1234,11 +1250,11 @@ var schema_default = {
1234
1250
  },
1235
1251
  routing: {
1236
1252
  $ref: "#/definitions/Routing",
1237
- description: "Groups of path expressions that are routed to this application."
1253
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1238
1254
  },
1239
1255
  assetPrefix: {
1240
1256
  type: "string",
1241
- 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."
1257
+ 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."
1242
1258
  }
1243
1259
  },
1244
1260
  required: [
@@ -1254,15 +1270,15 @@ var schema_default = {
1254
1270
  "number",
1255
1271
  "string"
1256
1272
  ],
1257
- 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"
1273
+ 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."
1258
1274
  },
1259
1275
  task: {
1260
1276
  type: "string",
1261
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1277
+ 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.'
1262
1278
  },
1263
1279
  fallback: {
1264
1280
  type: "string",
1265
- 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."
1281
+ 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."
1266
1282
  }
1267
1283
  },
1268
1284
  additionalProperties: false
@@ -1271,29 +1287,46 @@ var schema_default = {
1271
1287
  type: "array",
1272
1288
  items: {
1273
1289
  $ref: "#/definitions/PathGroup"
1274
- }
1290
+ },
1291
+ description: "A list of path groups that are routed to this application."
1275
1292
  },
1276
1293
  PathGroup: {
1277
1294
  type: "object",
1278
1295
  properties: {
1279
1296
  group: {
1280
1297
  type: "string",
1281
- description: "Optional group name for the paths"
1298
+ description: "Group name for the paths."
1282
1299
  },
1283
1300
  flag: {
1284
1301
  type: "string",
1285
- description: "flag name that can be used to enable/disable all paths in the group"
1302
+ 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."
1286
1303
  },
1287
1304
  paths: {
1288
1305
  type: "array",
1289
1306
  items: {
1290
1307
  type: "string"
1291
- }
1308
+ },
1309
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1292
1310
  }
1293
1311
  },
1294
1312
  required: [
1295
1313
  "paths"
1296
1314
  ],
1315
+ additionalProperties: false,
1316
+ description: "A group of paths that is routed to this application."
1317
+ },
1318
+ Options: {
1319
+ type: "object",
1320
+ properties: {
1321
+ disableOverrides: {
1322
+ type: "boolean",
1323
+ 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."
1324
+ },
1325
+ localProxyPort: {
1326
+ type: "number",
1327
+ 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."
1328
+ }
1329
+ },
1297
1330
  additionalProperties: false
1298
1331
  }
1299
1332
  }
@@ -1312,19 +1345,19 @@ function formatAjvErrors(errors) {
1312
1345
  return [];
1313
1346
  }
1314
1347
  const errorMessages = [];
1315
- for (const error of errors) {
1316
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1348
+ for (const error2 of errors) {
1349
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1317
1350
  continue;
1318
1351
  }
1319
- const instancePath = error.instancePath.slice(1);
1352
+ const instancePath = error2.instancePath.slice(1);
1320
1353
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1321
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1354
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1322
1355
  errorMessages.push(
1323
1356
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1324
1357
  );
1325
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1358
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1326
1359
  const anyOfErrors = errors.filter(
1327
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1360
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1328
1361
  );
1329
1362
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1330
1363
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1340,13 +1373,13 @@ function formatAjvErrors(errors) {
1340
1373
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1341
1374
  );
1342
1375
  }
1343
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1376
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1344
1377
  errorMessages.push(
1345
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1378
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1346
1379
  );
1347
- } else if (error.keyword === "required") {
1380
+ } else if (error2.keyword === "required") {
1348
1381
  errorMessages.push(
1349
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1382
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1350
1383
  );
1351
1384
  }
1352
1385
  }
@@ -1359,8 +1392,8 @@ function validateSchema(configString) {
1359
1392
  const isValid = validate(parsedConfig);
1360
1393
  if (!isValid) {
1361
1394
  throw new MicrofrontendError(
1362
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1363
- - ${error}`).join(
1395
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1396
+ - ${error2}`).join(
1364
1397
  ""
1365
1398
  )}
1366
1399