@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
@@ -196,22 +196,38 @@ import { readFileSync } from "node:fs";
196
196
  import { parse } from "jsonc-parser";
197
197
  import fg from "fast-glob";
198
198
 
199
- // src/config/constants.ts
200
- var CONFIGURATION_FILENAMES = [
199
+ // src/config/microfrontends/utils/get-config-file-name.ts
200
+ var DEFAULT_CONFIGURATION_FILENAMES = [
201
201
  "microfrontends.jsonc",
202
202
  "microfrontends.json"
203
203
  ];
204
+ function getPossibleConfigurationFilenames({
205
+ customConfigFilename
206
+ }) {
207
+ if (customConfigFilename) {
208
+ if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
209
+ throw new Error(
210
+ `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
211
+ );
212
+ }
213
+ return Array.from(
214
+ /* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
215
+ );
216
+ }
217
+ return DEFAULT_CONFIGURATION_FILENAMES;
218
+ }
204
219
 
205
220
  // src/config/microfrontends/utils/infer-microfrontends-location.ts
206
221
  var configCache = {};
207
222
  function findPackageWithMicrofrontendsConfig({
208
223
  repositoryRoot,
209
- applicationContext
224
+ applicationContext,
225
+ customConfigFilename
210
226
  }) {
211
227
  const applicationName = applicationContext.name;
212
228
  try {
213
229
  const microfrontendsJsonPaths = fg.globSync(
214
- `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
230
+ `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
215
231
  {
216
232
  cwd: repositoryRoot,
217
233
  absolute: true,
@@ -267,6 +283,8 @@ Names of applications in \`microfrontends.json\` must match the Vercel Project n
267
283
 
268
284
  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.
269
285
 
286
+ 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.
287
+
270
288
  If you suspect this is thrown in error, please reach out to the Vercel team.`,
271
289
  { type: "config", subtype: "inference_failed" }
272
290
  );
@@ -281,7 +299,7 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
281
299
  }
282
300
  }
283
301
  function inferMicrofrontendsLocation(opts) {
284
- const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}`;
302
+ const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}${opts.customConfigFilename ? `-${opts.customConfigFilename}` : ""}`;
285
303
  if (configCache[cacheKey]) {
286
304
  return configCache[cacheKey];
287
305
  }
@@ -347,8 +365,13 @@ function findPackageRoot(startDir) {
347
365
  // src/config/microfrontends/utils/find-config.ts
348
366
  import fs4 from "node:fs";
349
367
  import { join } from "node:path";
350
- function findConfig({ dir }) {
351
- for (const filename of CONFIGURATION_FILENAMES) {
368
+ function findConfig({
369
+ dir,
370
+ customConfigFilename
371
+ }) {
372
+ for (const filename of getPossibleConfigurationFilenames({
373
+ customConfigFilename
374
+ })) {
352
375
  const maybeConfig = join(dir, filename);
353
376
  if (fs4.existsSync(maybeConfig)) {
354
377
  return maybeConfig;
@@ -415,7 +438,7 @@ var MicrofrontendConfigClient = class {
415
438
  static fromEnv(config) {
416
439
  if (!config) {
417
440
  throw new Error(
418
- "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
441
+ "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"
419
442
  );
420
443
  }
421
444
  return new MicrofrontendConfigClient(JSON.parse(config));
@@ -555,10 +578,11 @@ function validatePathExpression(path6) {
555
578
  }
556
579
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
557
580
  // Only limited regex is supported for now, due to performance considerations
558
- !/^(?<allowed>[\w]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^:|()]+)*)\)\.\*$/.test(
559
- token.pattern
581
+ // Allows all letters, numbers, and hyphens. Other characters must be escaped.
582
+ !/^(?<allowed>[\w-~]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w-~]+(?:\|[^:|()]+)*)\)\.\*$/.test(
583
+ token.pattern.replace(/\\./g, "")
560
584
  )) {
561
- return `Path ${path6} cannot use unsupported regular expression wildcard`;
585
+ return `Path ${path6} cannot use unsupported regular expression wildcard. If the path includes special characters, they must be escaped with backslash (e.g. '\\(')`;
562
586
  }
563
587
  if (token.modifier && i !== tokens.length - 1) {
564
588
  return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
@@ -1450,7 +1474,11 @@ var MicrofrontendsServer = class {
1450
1474
  appName,
1451
1475
  packageRoot
1452
1476
  });
1453
- const maybeConfig = findConfig({ dir: packageRoot });
1477
+ const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1478
+ const maybeConfig = findConfig({
1479
+ dir: packageRoot,
1480
+ customConfigFilename
1481
+ });
1454
1482
  if (maybeConfig) {
1455
1483
  return MicrofrontendsServer.fromFile({
1456
1484
  filePath: maybeConfig,
@@ -1459,11 +1487,9 @@ var MicrofrontendsServer = class {
1459
1487
  }
1460
1488
  const repositoryRoot = findRepositoryRoot();
1461
1489
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1462
- if (typeof process.env.VC_MICROFRONTENDS_CONFIG === "string") {
1463
- const maybeConfigFromEnv = resolve(
1464
- packageRoot,
1465
- process.env.VC_MICROFRONTENDS_CONFIG
1466
- );
1490
+ const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1491
+ if (typeof configFromEnv === "string") {
1492
+ const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1467
1493
  if (maybeConfigFromEnv) {
1468
1494
  return MicrofrontendsServer.fromFile({
1469
1495
  filePath: maybeConfigFromEnv,
@@ -1472,7 +1498,8 @@ var MicrofrontendsServer = class {
1472
1498
  }
1473
1499
  } else {
1474
1500
  const maybeConfigFromVercel = findConfig({
1475
- dir: join2(packageRoot, ".vercel")
1501
+ dir: join2(packageRoot, ".vercel"),
1502
+ customConfigFilename
1476
1503
  });
1477
1504
  if (maybeConfigFromVercel) {
1478
1505
  return MicrofrontendsServer.fromFile({
@@ -1483,9 +1510,13 @@ var MicrofrontendsServer = class {
1483
1510
  if (isMonorepo2) {
1484
1511
  const defaultPackage = inferMicrofrontendsLocation({
1485
1512
  repositoryRoot,
1486
- applicationContext
1513
+ applicationContext,
1514
+ customConfigFilename
1515
+ });
1516
+ const maybeConfigFromDefault = findConfig({
1517
+ dir: defaultPackage,
1518
+ customConfigFilename
1487
1519
  });
1488
- const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1489
1520
  if (maybeConfigFromDefault) {
1490
1521
  return MicrofrontendsServer.fromFile({
1491
1522
  filePath: maybeConfigFromDefault,