@vercel/microfrontends 2.0.0 → 2.1.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 (46) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -5
  3. package/dist/bin/cli.cjs +226 -79
  4. package/dist/config.cjs +5 -4
  5. package/dist/config.cjs.map +1 -1
  6. package/dist/config.js +5 -4
  7. package/dist/config.js.map +1 -1
  8. package/dist/experimental/sveltekit.cjs +51 -20
  9. package/dist/experimental/sveltekit.cjs.map +1 -1
  10. package/dist/experimental/sveltekit.js +51 -20
  11. package/dist/experimental/sveltekit.js.map +1 -1
  12. package/dist/experimental/vite.cjs +51 -20
  13. package/dist/experimental/vite.cjs.map +1 -1
  14. package/dist/experimental/vite.js +51 -20
  15. package/dist/experimental/vite.js.map +1 -1
  16. package/dist/microfrontends/server.cjs +51 -20
  17. package/dist/microfrontends/server.cjs.map +1 -1
  18. package/dist/microfrontends/server.js +51 -20
  19. package/dist/microfrontends/server.js.map +1 -1
  20. package/dist/microfrontends/utils.cjs +32 -7
  21. package/dist/microfrontends/utils.cjs.map +1 -1
  22. package/dist/microfrontends/utils.d.ts +8 -2
  23. package/dist/microfrontends/utils.js +31 -7
  24. package/dist/microfrontends/utils.js.map +1 -1
  25. package/dist/next/client.cjs +1 -1
  26. package/dist/next/client.cjs.map +1 -1
  27. package/dist/next/client.d.ts +15 -1
  28. package/dist/next/client.js +1 -1
  29. package/dist/next/client.js.map +1 -1
  30. package/dist/next/config.cjs +62 -20
  31. package/dist/next/config.cjs.map +1 -1
  32. package/dist/next/config.js +62 -20
  33. package/dist/next/config.js.map +1 -1
  34. package/dist/next/middleware.cjs +5 -4
  35. package/dist/next/middleware.cjs.map +1 -1
  36. package/dist/next/middleware.js +5 -4
  37. package/dist/next/middleware.js.map +1 -1
  38. package/dist/next/testing.cjs +5 -4
  39. package/dist/next/testing.cjs.map +1 -1
  40. package/dist/next/testing.js +5 -4
  41. package/dist/next/testing.js.map +1 -1
  42. package/dist/utils/mfe-port.cjs +66 -40
  43. package/dist/utils/mfe-port.cjs.map +1 -1
  44. package/dist/utils/mfe-port.js +66 -40
  45. package/dist/utils/mfe-port.js.map +1 -1
  46. package/package.json +4 -4
@@ -187,22 +187,38 @@ import { readFileSync } from "node:fs";
187
187
  import { parse } from "jsonc-parser";
188
188
  import fg from "fast-glob";
189
189
 
190
- // src/config/constants.ts
191
- var CONFIGURATION_FILENAMES = [
190
+ // src/config/microfrontends/utils/get-config-file-name.ts
191
+ var DEFAULT_CONFIGURATION_FILENAMES = [
192
192
  "microfrontends.jsonc",
193
193
  "microfrontends.json"
194
194
  ];
195
+ function getPossibleConfigurationFilenames({
196
+ customConfigFilename
197
+ }) {
198
+ if (customConfigFilename) {
199
+ if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
200
+ throw new Error(
201
+ `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
202
+ );
203
+ }
204
+ return Array.from(
205
+ /* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
206
+ );
207
+ }
208
+ return DEFAULT_CONFIGURATION_FILENAMES;
209
+ }
195
210
 
196
211
  // src/config/microfrontends/utils/infer-microfrontends-location.ts
197
212
  var configCache = {};
198
213
  function findPackageWithMicrofrontendsConfig({
199
214
  repositoryRoot,
200
- applicationContext
215
+ applicationContext,
216
+ customConfigFilename
201
217
  }) {
202
218
  const applicationName = applicationContext.name;
203
219
  try {
204
220
  const microfrontendsJsonPaths = fg.globSync(
205
- `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
221
+ `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
206
222
  {
207
223
  cwd: repositoryRoot,
208
224
  absolute: true,
@@ -258,6 +274,8 @@ Names of applications in \`microfrontends.json\` must match the Vercel Project n
258
274
 
259
275
  If your Vercel Microfrontends configuration is not in this repository, you can use the Vercel CLI to pull the Vercel Microfrontends configuration using the "vercel microfrontends pull" command, or you can specify the path manually using the VC_MICROFRONTENDS_CONFIG environment variable.
260
276
 
277
+ If your Vercel Microfrontends configuration has a custom name, ensure the VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable is set, you can pull the vercel project environment variables using the "vercel env pull" command.
278
+
261
279
  If you suspect this is thrown in error, please reach out to the Vercel team.`,
262
280
  { type: "config", subtype: "inference_failed" }
263
281
  );
@@ -272,7 +290,7 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
272
290
  }
273
291
  }
274
292
  function inferMicrofrontendsLocation(opts) {
275
- const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}`;
293
+ const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}${opts.customConfigFilename ? `-${opts.customConfigFilename}` : ""}`;
276
294
  if (configCache[cacheKey]) {
277
295
  return configCache[cacheKey];
278
296
  }
@@ -338,8 +356,13 @@ function findPackageRoot(startDir) {
338
356
  // src/config/microfrontends/utils/find-config.ts
339
357
  import fs4 from "node:fs";
340
358
  import { join } from "node:path";
341
- function findConfig({ dir }) {
342
- for (const filename of CONFIGURATION_FILENAMES) {
359
+ function findConfig({
360
+ dir,
361
+ customConfigFilename
362
+ }) {
363
+ for (const filename of getPossibleConfigurationFilenames({
364
+ customConfigFilename
365
+ })) {
343
366
  const maybeConfig = join(dir, filename);
344
367
  if (fs4.existsSync(maybeConfig)) {
345
368
  return maybeConfig;
@@ -406,7 +429,7 @@ var MicrofrontendConfigClient = class {
406
429
  static fromEnv(config) {
407
430
  if (!config) {
408
431
  throw new Error(
409
- "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
432
+ "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`? Is the local proxy running and this application is being accessed via the proxy port? See https://vercel.com/docs/microfrontends/local-development#setting-up-microfrontends-proxy"
410
433
  );
411
434
  }
412
435
  return new MicrofrontendConfigClient(JSON.parse(config));
@@ -546,10 +569,11 @@ function validatePathExpression(path6) {
546
569
  }
547
570
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
548
571
  // Only limited regex is supported for now, due to performance considerations
549
- !/^(?<allowed>[\w]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^:|()]+)*)\)\.\*$/.test(
550
- token.pattern
572
+ // Allows all letters, numbers, and hyphens. Other characters must be escaped.
573
+ !/^(?<allowed>[\w-~]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w-~]+(?:\|[^:|()]+)*)\)\.\*$/.test(
574
+ token.pattern.replace(/\\./g, "")
551
575
  )) {
552
- return `Path ${path6} cannot use unsupported regular expression wildcard`;
576
+ return `Path ${path6} cannot use unsupported regular expression wildcard. If the path includes special characters, they must be escaped with backslash (e.g. '\\(')`;
553
577
  }
554
578
  if (token.modifier && i !== tokens.length - 1) {
555
579
  return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
@@ -1441,7 +1465,11 @@ var MicrofrontendsServer = class {
1441
1465
  appName,
1442
1466
  packageRoot
1443
1467
  });
1444
- const maybeConfig = findConfig({ dir: packageRoot });
1468
+ const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1469
+ const maybeConfig = findConfig({
1470
+ dir: packageRoot,
1471
+ customConfigFilename
1472
+ });
1445
1473
  if (maybeConfig) {
1446
1474
  return MicrofrontendsServer.fromFile({
1447
1475
  filePath: maybeConfig,
@@ -1450,11 +1478,9 @@ var MicrofrontendsServer = class {
1450
1478
  }
1451
1479
  const repositoryRoot = findRepositoryRoot();
1452
1480
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1453
- if (typeof process.env.VC_MICROFRONTENDS_CONFIG === "string") {
1454
- const maybeConfigFromEnv = resolve(
1455
- packageRoot,
1456
- process.env.VC_MICROFRONTENDS_CONFIG
1457
- );
1481
+ const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1482
+ if (typeof configFromEnv === "string") {
1483
+ const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1458
1484
  if (maybeConfigFromEnv) {
1459
1485
  return MicrofrontendsServer.fromFile({
1460
1486
  filePath: maybeConfigFromEnv,
@@ -1463,7 +1489,8 @@ var MicrofrontendsServer = class {
1463
1489
  }
1464
1490
  } else {
1465
1491
  const maybeConfigFromVercel = findConfig({
1466
- dir: join2(packageRoot, ".vercel")
1492
+ dir: join2(packageRoot, ".vercel"),
1493
+ customConfigFilename
1467
1494
  });
1468
1495
  if (maybeConfigFromVercel) {
1469
1496
  return MicrofrontendsServer.fromFile({
@@ -1474,9 +1501,13 @@ var MicrofrontendsServer = class {
1474
1501
  if (isMonorepo2) {
1475
1502
  const defaultPackage = inferMicrofrontendsLocation({
1476
1503
  repositoryRoot,
1477
- applicationContext
1504
+ applicationContext,
1505
+ customConfigFilename
1506
+ });
1507
+ const maybeConfigFromDefault = findConfig({
1508
+ dir: defaultPackage,
1509
+ customConfigFilename
1478
1510
  });
1479
- const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1480
1511
  if (maybeConfigFromDefault) {
1481
1512
  return MicrofrontendsServer.fromFile({
1482
1513
  filePath: maybeConfigFromDefault,