@vercel/microfrontends 2.1.3 → 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 +14 -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 +125 -112
  25. package/dist/next/config.cjs.map +1 -1
  26. package/dist/next/config.d.ts +11 -1
  27. package/dist/next/config.js +125 -112
  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
@@ -189,8 +189,8 @@ import fg from "fast-glob";
189
189
 
190
190
  // src/config/microfrontends/utils/get-config-file-name.ts
191
191
  var DEFAULT_CONFIGURATION_FILENAMES = [
192
- "microfrontends.jsonc",
193
- "microfrontends.json"
192
+ "microfrontends.json",
193
+ "microfrontends.jsonc"
194
194
  ];
195
195
  function getPossibleConfigurationFilenames({
196
196
  customConfigFilename
@@ -198,7 +198,7 @@ function getPossibleConfigurationFilenames({
198
198
  if (customConfigFilename) {
199
199
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
200
200
  throw new Error(
201
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
201
+ `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
202
  );
203
203
  }
204
204
  return Array.from(
@@ -246,7 +246,7 @@ function findPackageWithMicrofrontendsConfig({
246
246
  }
247
247
  }
248
248
  }
249
- } catch (error) {
249
+ } catch (error2) {
250
250
  }
251
251
  }
252
252
  if (matchingPaths.length > 1) {
@@ -282,9 +282,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
282
282
  }
283
283
  const [packageJsonPath] = matchingPaths;
284
284
  return dirname(packageJsonPath);
285
- } catch (error) {
286
- if (error instanceof MicrofrontendError) {
287
- throw error;
285
+ } catch (error2) {
286
+ if (error2 instanceof MicrofrontendError) {
287
+ throw error2;
288
288
  }
289
289
  return null;
290
290
  }
@@ -308,6 +308,30 @@ function inferMicrofrontendsLocation(opts) {
308
308
  // src/config/microfrontends/utils/is-monorepo.ts
309
309
  import fs2 from "node:fs";
310
310
  import path2 from "node:path";
311
+
312
+ // src/bin/logger.ts
313
+ function debug(...args) {
314
+ if (process.env.MFE_DEBUG) {
315
+ console.log(...args);
316
+ }
317
+ }
318
+ function info(...args) {
319
+ console.log(...args);
320
+ }
321
+ function warn(...args) {
322
+ console.warn(...args);
323
+ }
324
+ function error(...args) {
325
+ console.error(...args);
326
+ }
327
+ var logger = {
328
+ debug,
329
+ info,
330
+ warn,
331
+ error
332
+ };
333
+
334
+ // src/config/microfrontends/utils/is-monorepo.ts
311
335
  function isMonorepo({
312
336
  repositoryRoot
313
337
  }) {
@@ -329,8 +353,8 @@ function isMonorepo({
329
353
  fs2.readFileSync(packageJsonPath, "utf-8")
330
354
  );
331
355
  return packageJson.workspaces !== void 0;
332
- } catch (error) {
333
- console.error("Error determining if repository is a monorepo", error);
356
+ } catch (error2) {
357
+ logger.error("Error determining if repository is a monorepo", error2);
334
358
  return false;
335
359
  }
336
360
  }
@@ -1124,38 +1148,28 @@ var schema_default = {
1124
1148
  type: "object",
1125
1149
  properties: {
1126
1150
  $schema: {
1127
- type: "string"
1151
+ type: "string",
1152
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1128
1153
  },
1129
1154
  version: {
1130
1155
  type: "string",
1131
- const: "1"
1132
- },
1133
- options: {
1134
- $ref: "#/definitions/Options"
1156
+ const: "1",
1157
+ description: "The version of the microfrontends config schema."
1135
1158
  },
1136
1159
  applications: {
1137
1160
  $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"
1161
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1162
+ },
1163
+ options: {
1164
+ $ref: "#/definitions/Options",
1165
+ description: "Optional configuration options for the microfrontend."
1139
1166
  }
1140
1167
  },
1141
1168
  required: [
1142
1169
  "applications"
1143
1170
  ],
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
1171
+ additionalProperties: false,
1172
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1159
1173
  },
1160
1174
  ApplicationRouting: {
1161
1175
  type: "object",
@@ -1163,8 +1177,9 @@ var schema_default = {
1163
1177
  $ref: "#/definitions/Application"
1164
1178
  },
1165
1179
  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
- }
1180
+ 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."
1181
+ },
1182
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1168
1183
  },
1169
1184
  Application: {
1170
1185
  anyOf: [
@@ -1174,14 +1189,15 @@ var schema_default = {
1174
1189
  {
1175
1190
  $ref: "#/definitions/ChildApplication"
1176
1191
  }
1177
- ]
1192
+ ],
1193
+ description: "The configuration for a microfrontend application. There must always be one default application."
1178
1194
  },
1179
1195
  DefaultApplication: {
1180
1196
  type: "object",
1181
1197
  properties: {
1182
1198
  packageName: {
1183
1199
  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`."
1200
+ 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
1201
  },
1186
1202
  development: {
1187
1203
  $ref: "#/definitions/DefaultDevelopment",
@@ -1201,15 +1217,15 @@ var schema_default = {
1201
1217
  "number",
1202
1218
  "string"
1203
1219
  ],
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"
1220
+ 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
1221
  },
1206
1222
  task: {
1207
1223
  type: "string",
1208
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1224
+ 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
1225
  },
1210
1226
  fallback: {
1211
1227
  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."
1228
+ 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
1229
  }
1214
1230
  },
1215
1231
  required: [
@@ -1222,7 +1238,7 @@ var schema_default = {
1222
1238
  properties: {
1223
1239
  packageName: {
1224
1240
  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`."
1241
+ 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
1242
  },
1227
1243
  development: {
1228
1244
  $ref: "#/definitions/ChildDevelopment",
@@ -1230,11 +1246,11 @@ var schema_default = {
1230
1246
  },
1231
1247
  routing: {
1232
1248
  $ref: "#/definitions/Routing",
1233
- description: "Groups of path expressions that are routed to this application."
1249
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1234
1250
  },
1235
1251
  assetPrefix: {
1236
1252
  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."
1253
+ 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
1254
  }
1239
1255
  },
1240
1256
  required: [
@@ -1250,15 +1266,15 @@ var schema_default = {
1250
1266
  "number",
1251
1267
  "string"
1252
1268
  ],
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"
1269
+ 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
1270
  },
1255
1271
  task: {
1256
1272
  type: "string",
1257
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1273
+ 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
1274
  },
1259
1275
  fallback: {
1260
1276
  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."
1277
+ 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
1278
  }
1263
1279
  },
1264
1280
  additionalProperties: false
@@ -1267,29 +1283,46 @@ var schema_default = {
1267
1283
  type: "array",
1268
1284
  items: {
1269
1285
  $ref: "#/definitions/PathGroup"
1270
- }
1286
+ },
1287
+ description: "A list of path groups that are routed to this application."
1271
1288
  },
1272
1289
  PathGroup: {
1273
1290
  type: "object",
1274
1291
  properties: {
1275
1292
  group: {
1276
1293
  type: "string",
1277
- description: "Optional group name for the paths"
1294
+ description: "Group name for the paths."
1278
1295
  },
1279
1296
  flag: {
1280
1297
  type: "string",
1281
- description: "flag name that can be used to enable/disable all paths in the group"
1298
+ 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
1299
  },
1283
1300
  paths: {
1284
1301
  type: "array",
1285
1302
  items: {
1286
1303
  type: "string"
1287
- }
1304
+ },
1305
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1288
1306
  }
1289
1307
  },
1290
1308
  required: [
1291
1309
  "paths"
1292
1310
  ],
1311
+ additionalProperties: false,
1312
+ description: "A group of paths that is routed to this application."
1313
+ },
1314
+ Options: {
1315
+ type: "object",
1316
+ properties: {
1317
+ disableOverrides: {
1318
+ type: "boolean",
1319
+ 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."
1320
+ },
1321
+ localProxyPort: {
1322
+ type: "number",
1323
+ 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."
1324
+ }
1325
+ },
1293
1326
  additionalProperties: false
1294
1327
  }
1295
1328
  }
@@ -1308,19 +1341,19 @@ function formatAjvErrors(errors) {
1308
1341
  return [];
1309
1342
  }
1310
1343
  const errorMessages = [];
1311
- for (const error of errors) {
1312
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1344
+ for (const error2 of errors) {
1345
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1313
1346
  continue;
1314
1347
  }
1315
- const instancePath = error.instancePath.slice(1);
1348
+ const instancePath = error2.instancePath.slice(1);
1316
1349
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1317
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1350
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1318
1351
  errorMessages.push(
1319
1352
  `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
1353
  );
1321
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1354
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1322
1355
  const anyOfErrors = errors.filter(
1323
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1356
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1324
1357
  );
1325
1358
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1326
1359
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1336,13 +1369,13 @@ function formatAjvErrors(errors) {
1336
1369
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1337
1370
  );
1338
1371
  }
1339
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1372
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1340
1373
  errorMessages.push(
1341
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1374
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1342
1375
  );
1343
- } else if (error.keyword === "required") {
1376
+ } else if (error2.keyword === "required") {
1344
1377
  errorMessages.push(
1345
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1378
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1346
1379
  );
1347
1380
  }
1348
1381
  }
@@ -1355,8 +1388,8 @@ function validateSchema(configString) {
1355
1388
  const isValid = validate(parsedConfig);
1356
1389
  if (!isValid) {
1357
1390
  throw new MicrofrontendError(
1358
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1359
- - ${error}`).join(
1391
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1392
+ - ${error2}`).join(
1360
1393
  ""
1361
1394
  )}
1362
1395
 
@@ -1641,12 +1674,10 @@ function microfrontends(opts) {
1641
1674
  port: app.development.local.port
1642
1675
  };
1643
1676
  }
1644
- if (process.env.MFE_DEBUG) {
1645
- console.log(
1646
- "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1647
- additionalConfigOptions
1648
- );
1649
- }
1677
+ logger.debug(
1678
+ "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1679
+ additionalConfigOptions
1680
+ );
1650
1681
  return {
1651
1682
  name: "vite-plugin-vercel-microfrontends",
1652
1683
  config: () => {