@vercel/microfrontends 2.2.2 → 2.3.1
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.
- package/CHANGELOG.md +12 -0
- package/dist/bin/cli.cjs +263 -263
- package/dist/config.cjs +23 -23
- package/dist/config.cjs.map +1 -1
- package/dist/config.js +23 -23
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +260 -260
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +240 -240
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +260 -260
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +240 -240
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +260 -260
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.js +240 -240
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/microfrontends/utils.cjs +22 -0
- package/dist/microfrontends/utils.cjs.map +1 -1
- package/dist/microfrontends/utils.d.ts +5 -1
- package/dist/microfrontends/utils.js +21 -0
- package/dist/microfrontends/utils.js.map +1 -1
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js.map +1 -1
- package/dist/next/config.cjs +260 -260
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +240 -240
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +23 -23
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +23 -23
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +23 -23
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.js +23 -23
- package/dist/next/testing.js.map +1 -1
- package/dist/utils/mfe-port.cjs +260 -260
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +240 -240
- package/dist/utils/mfe-port.js.map +1 -1
- package/package.json +2 -2
|
@@ -117,7 +117,16 @@ var MicrofrontendError = class extends Error {
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
// src/config/microfrontends-config/isomorphic/index.ts
|
|
120
|
-
import { parse } from "jsonc-parser";
|
|
120
|
+
import { parse as parse2 } from "jsonc-parser";
|
|
121
|
+
|
|
122
|
+
// src/config/microfrontends/utils/hash-application-name.ts
|
|
123
|
+
import md5 from "md5";
|
|
124
|
+
function hashApplicationName(name) {
|
|
125
|
+
if (!name) {
|
|
126
|
+
throw new Error("Application name is required to generate hash");
|
|
127
|
+
}
|
|
128
|
+
return md5(name).substring(0, 6).padStart(6, "0");
|
|
129
|
+
}
|
|
121
130
|
|
|
122
131
|
// src/config/overrides/constants.ts
|
|
123
132
|
var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
|
|
@@ -267,6 +276,231 @@ function getConfigStringFromEnv() {
|
|
|
267
276
|
return config;
|
|
268
277
|
}
|
|
269
278
|
|
|
279
|
+
// src/config/microfrontends/utils/find-config.ts
|
|
280
|
+
import fs from "node:fs";
|
|
281
|
+
import { join } from "node:path";
|
|
282
|
+
|
|
283
|
+
// src/config/microfrontends/utils/get-config-file-name.ts
|
|
284
|
+
var DEFAULT_CONFIGURATION_FILENAMES = [
|
|
285
|
+
"microfrontends.json",
|
|
286
|
+
"microfrontends.jsonc"
|
|
287
|
+
];
|
|
288
|
+
function getPossibleConfigurationFilenames({
|
|
289
|
+
customConfigFilename
|
|
290
|
+
}) {
|
|
291
|
+
if (customConfigFilename) {
|
|
292
|
+
if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
`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.`
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
return Array.from(
|
|
298
|
+
/* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
return DEFAULT_CONFIGURATION_FILENAMES;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/config/microfrontends/utils/find-config.ts
|
|
305
|
+
function findConfig({
|
|
306
|
+
dir,
|
|
307
|
+
customConfigFilename
|
|
308
|
+
}) {
|
|
309
|
+
for (const filename of getPossibleConfigurationFilenames({
|
|
310
|
+
customConfigFilename
|
|
311
|
+
})) {
|
|
312
|
+
const maybeConfig = join(dir, filename);
|
|
313
|
+
if (fs.existsSync(maybeConfig)) {
|
|
314
|
+
return maybeConfig;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/config/microfrontends/utils/generate-default-asset-prefix.ts
|
|
321
|
+
var PREFIX = "vc-ap";
|
|
322
|
+
function generateDefaultAssetPrefixFromName({
|
|
323
|
+
name
|
|
324
|
+
}) {
|
|
325
|
+
if (!name) {
|
|
326
|
+
throw new Error("Name is required to generate an asset prefix");
|
|
327
|
+
}
|
|
328
|
+
return `${PREFIX}-${hashApplicationName(name)}`;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// src/config/microfrontends/utils/infer-microfrontends-location.ts
|
|
332
|
+
import { readFileSync, statSync } from "node:fs";
|
|
333
|
+
import { dirname, join as join2 } from "node:path";
|
|
334
|
+
import fg from "fast-glob";
|
|
335
|
+
import { parse } from "jsonc-parser";
|
|
336
|
+
var configCache = {};
|
|
337
|
+
function findPackageWithMicrofrontendsConfig({
|
|
338
|
+
repositoryRoot,
|
|
339
|
+
applicationContext,
|
|
340
|
+
customConfigFilename
|
|
341
|
+
}) {
|
|
342
|
+
const applicationName = applicationContext.name;
|
|
343
|
+
logger.debug(
|
|
344
|
+
"[MFE Config] Searching repository for configs containing application:",
|
|
345
|
+
applicationName
|
|
346
|
+
);
|
|
347
|
+
try {
|
|
348
|
+
const microfrontendsJsonPaths = fg.globSync(
|
|
349
|
+
`**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
|
|
350
|
+
{
|
|
351
|
+
cwd: repositoryRoot,
|
|
352
|
+
absolute: true,
|
|
353
|
+
onlyFiles: true,
|
|
354
|
+
followSymbolicLinks: false,
|
|
355
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
logger.debug(
|
|
359
|
+
"[MFE Config] Found",
|
|
360
|
+
microfrontendsJsonPaths.length,
|
|
361
|
+
"config file(s) in repository"
|
|
362
|
+
);
|
|
363
|
+
const matchingPaths = [];
|
|
364
|
+
for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
|
|
365
|
+
if (doesApplicationExistInConfig(microfrontendsJsonPath, applicationName)) {
|
|
366
|
+
matchingPaths.push(microfrontendsJsonPath);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
logger.debug(
|
|
370
|
+
"[MFE Config] Total matching config files:",
|
|
371
|
+
matchingPaths.length
|
|
372
|
+
);
|
|
373
|
+
if (matchingPaths.length > 1) {
|
|
374
|
+
throw new MicrofrontendError(
|
|
375
|
+
`Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
|
|
376
|
+
${matchingPaths.join("\n \u2022 ")}`,
|
|
377
|
+
{ type: "config", subtype: "inference_failed" }
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
if (matchingPaths.length === 0) {
|
|
381
|
+
if (repositoryRoot && doesMisplacedConfigExist(
|
|
382
|
+
repositoryRoot,
|
|
383
|
+
applicationName,
|
|
384
|
+
customConfigFilename
|
|
385
|
+
)) {
|
|
386
|
+
logger.debug(
|
|
387
|
+
"[MFE Config] Found misplaced config in wrong .vercel directory in repository"
|
|
388
|
+
);
|
|
389
|
+
const misplacedConfigPath = join2(
|
|
390
|
+
repositoryRoot,
|
|
391
|
+
".vercel",
|
|
392
|
+
customConfigFilename || "microfrontends.json"
|
|
393
|
+
);
|
|
394
|
+
throw new MicrofrontendError(
|
|
395
|
+
`Unable to automatically infer the location of the \`microfrontends.json\` file.
|
|
396
|
+
|
|
397
|
+
A microfrontends config was found in the \`.vercel\` directory at the repository root: ${misplacedConfigPath}
|
|
398
|
+
However, in a monorepo, the config file should be placed in the \`.vercel\` directory in your application directory instead.
|
|
399
|
+
|
|
400
|
+
To fix this:
|
|
401
|
+
1. If using \`vercel link\`, run it with \`vercel link --repo\` to handle monorepos, or run \`vercel microfrontends pull --cwd=<application-directory>\` to make sure it pulls the \`microfrontends.json\` file to the correct location
|
|
402
|
+
2. If manually defined, move the config file to the \`.vercel\` directory in your application
|
|
403
|
+
3. Alternatively, set the VC_MICROFRONTENDS_CONFIG environment variable to the correct path
|
|
404
|
+
|
|
405
|
+
For more information, see: https://vercel.com/docs/cli/project-linking`,
|
|
406
|
+
{ type: "config", subtype: "inference_failed" }
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
let additionalErrorMessage = "";
|
|
410
|
+
if (microfrontendsJsonPaths.length > 0) {
|
|
411
|
+
if (!applicationContext.projectName) {
|
|
412
|
+
additionalErrorMessage = `
|
|
413
|
+
|
|
414
|
+
If the name in package.json (${applicationContext.packageJsonName}) differs from your Vercel Project name, set the \`packageName\` field for the application in \`microfrontends.json\` to ensure that the configuration can be found locally.`;
|
|
415
|
+
} else {
|
|
416
|
+
additionalErrorMessage = `
|
|
417
|
+
|
|
418
|
+
Names of applications in \`microfrontends.json\` must match the Vercel Project name (${applicationContext.projectName}).`;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
throw new MicrofrontendError(
|
|
422
|
+
`Could not find a \`microfrontends.json\` file in the repository that contains the "${applicationName}" application.${additionalErrorMessage}
|
|
423
|
+
|
|
424
|
+
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.
|
|
425
|
+
|
|
426
|
+
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.
|
|
427
|
+
|
|
428
|
+
If you suspect this is thrown in error, please reach out to the Vercel team.`,
|
|
429
|
+
{ type: "config", subtype: "inference_failed" }
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
const [packageJsonPath] = matchingPaths;
|
|
433
|
+
return dirname(packageJsonPath);
|
|
434
|
+
} catch (error2) {
|
|
435
|
+
if (error2 instanceof MicrofrontendError) {
|
|
436
|
+
throw error2;
|
|
437
|
+
}
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function inferMicrofrontendsLocation(opts) {
|
|
442
|
+
const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}${opts.customConfigFilename ? `-${opts.customConfigFilename}` : ""}`;
|
|
443
|
+
if (configCache[cacheKey]) {
|
|
444
|
+
return configCache[cacheKey];
|
|
445
|
+
}
|
|
446
|
+
const result = findPackageWithMicrofrontendsConfig(opts);
|
|
447
|
+
if (!result) {
|
|
448
|
+
throw new MicrofrontendError(
|
|
449
|
+
`Could not infer the location of the \`microfrontends.json\` file for application "${opts.applicationContext.name}" starting in directory "${opts.repositoryRoot}".`,
|
|
450
|
+
{ type: "config", subtype: "inference_failed" }
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
configCache[cacheKey] = result;
|
|
454
|
+
return result;
|
|
455
|
+
}
|
|
456
|
+
function existsSync(path6) {
|
|
457
|
+
try {
|
|
458
|
+
statSync(path6);
|
|
459
|
+
return true;
|
|
460
|
+
} catch (_) {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function doesMisplacedConfigExist(repositoryRoot, applicationName, customConfigFilename) {
|
|
465
|
+
logger.debug(
|
|
466
|
+
"[MFE Config] Looking for misplaced config in wrong .vercel directory"
|
|
467
|
+
);
|
|
468
|
+
const misplacedConfigPath = join2(
|
|
469
|
+
repositoryRoot,
|
|
470
|
+
".vercel",
|
|
471
|
+
customConfigFilename || "microfrontends.json"
|
|
472
|
+
);
|
|
473
|
+
return existsSync(misplacedConfigPath) && doesApplicationExistInConfig(misplacedConfigPath, applicationName);
|
|
474
|
+
}
|
|
475
|
+
function doesApplicationExistInConfig(microfrontendsJsonPath, applicationName) {
|
|
476
|
+
try {
|
|
477
|
+
const microfrontendsJsonContent = readFileSync(
|
|
478
|
+
microfrontendsJsonPath,
|
|
479
|
+
"utf-8"
|
|
480
|
+
);
|
|
481
|
+
const microfrontendsJson = parse(microfrontendsJsonContent);
|
|
482
|
+
if (microfrontendsJson.applications[applicationName]) {
|
|
483
|
+
logger.debug(
|
|
484
|
+
"[MFE Config] Found application in config:",
|
|
485
|
+
microfrontendsJsonPath
|
|
486
|
+
);
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
for (const [_, app] of Object.entries(microfrontendsJson.applications)) {
|
|
490
|
+
if (app.packageName === applicationName) {
|
|
491
|
+
logger.debug(
|
|
492
|
+
"[MFE Config] Found application via packageName in config:",
|
|
493
|
+
microfrontendsJsonPath
|
|
494
|
+
);
|
|
495
|
+
return true;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
} catch (error2) {
|
|
499
|
+
logger.debug("[MFE Config] Error checking application in config:", error2);
|
|
500
|
+
}
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
|
|
270
504
|
// src/config/microfrontends-config/isomorphic/constants.ts
|
|
271
505
|
var DEFAULT_LOCAL_PROXY_PORT = 3024;
|
|
272
506
|
var MFE_APP_PORT_ENV = "MFE_APP_PORT";
|
|
@@ -405,26 +639,6 @@ var LocalHost = class extends Host {
|
|
|
405
639
|
}
|
|
406
640
|
};
|
|
407
641
|
|
|
408
|
-
// src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
|
|
409
|
-
import md5 from "md5";
|
|
410
|
-
function hashApplicationName(name) {
|
|
411
|
-
if (!name) {
|
|
412
|
-
throw new Error("Application name is required to generate hash");
|
|
413
|
-
}
|
|
414
|
-
return md5(name).substring(0, 6).padStart(6, "0");
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
|
|
418
|
-
var PREFIX = "vc-ap";
|
|
419
|
-
function generateAssetPrefixFromName({
|
|
420
|
-
name
|
|
421
|
-
}) {
|
|
422
|
-
if (!name) {
|
|
423
|
-
throw new Error("Name is required to generate an asset prefix");
|
|
424
|
-
}
|
|
425
|
-
return `${PREFIX}-${hashApplicationName(name)}`;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
642
|
// src/config/microfrontends-config/isomorphic/utils/generate-automation-bypass-env-var-name.ts
|
|
429
643
|
function generateAutomationBypassEnvVarName({
|
|
430
644
|
name
|
|
@@ -505,7 +719,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
505
719
|
);
|
|
506
720
|
}
|
|
507
721
|
};
|
|
508
|
-
var
|
|
722
|
+
var PATH_DEFAULT_PATTERNS = ["[^\\/#\\?]+?", "(?:(?!\\.)[^\\/#\\?])+?"];
|
|
509
723
|
function validatePathExpression(path6) {
|
|
510
724
|
try {
|
|
511
725
|
const tokens = parsePathRegexp(path6);
|
|
@@ -527,7 +741,7 @@ function validatePathExpression(path6) {
|
|
|
527
741
|
if (!token.name) {
|
|
528
742
|
return `Only named wildcards are allowed: ${path6} (hint: add ":path" to the wildcard)`;
|
|
529
743
|
}
|
|
530
|
-
if (token.pattern
|
|
744
|
+
if (!PATH_DEFAULT_PATTERNS.includes(token.pattern) && // Allows (a|b|c) and ((?!a|b|c).*) regex
|
|
531
745
|
// Only limited regex is supported for now, due to performance considerations
|
|
532
746
|
// Allows all letters, numbers, and hyphens. Other characters must be escaped.
|
|
533
747
|
!/^(?<allowed>[\w-~]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w-~]+(?:\|[^:|()]+)*)\)\.\*$/.test(
|
|
@@ -642,7 +856,7 @@ var Application = class {
|
|
|
642
856
|
return this.default;
|
|
643
857
|
}
|
|
644
858
|
getAssetPrefix() {
|
|
645
|
-
const generatedAssetPrefix =
|
|
859
|
+
const generatedAssetPrefix = generateDefaultAssetPrefixFromName({
|
|
646
860
|
name: this.name
|
|
647
861
|
});
|
|
648
862
|
if ("assetPrefix" in this.serialized) {
|
|
@@ -736,7 +950,7 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
736
950
|
};
|
|
737
951
|
}
|
|
738
952
|
static validate(config) {
|
|
739
|
-
const c = typeof config === "string" ?
|
|
953
|
+
const c = typeof config === "string" ? parse2(config) : config;
|
|
740
954
|
validateConfigPaths(c.applications);
|
|
741
955
|
validateConfigDefaultApplication(c.applications);
|
|
742
956
|
return c;
|
|
@@ -745,7 +959,7 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
745
959
|
cookies
|
|
746
960
|
}) {
|
|
747
961
|
return new MicrofrontendConfigIsomorphic({
|
|
748
|
-
config:
|
|
962
|
+
config: parse2(getConfigStringFromEnv()),
|
|
749
963
|
overrides: parseOverrides(cookies ?? [])
|
|
750
964
|
});
|
|
751
965
|
}
|
|
@@ -859,47 +1073,6 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
859
1073
|
}
|
|
860
1074
|
};
|
|
861
1075
|
|
|
862
|
-
// src/config/microfrontends/utils/find-config.ts
|
|
863
|
-
import fs from "node:fs";
|
|
864
|
-
import { join } from "node:path";
|
|
865
|
-
|
|
866
|
-
// src/config/microfrontends/utils/get-config-file-name.ts
|
|
867
|
-
var DEFAULT_CONFIGURATION_FILENAMES = [
|
|
868
|
-
"microfrontends.json",
|
|
869
|
-
"microfrontends.jsonc"
|
|
870
|
-
];
|
|
871
|
-
function getPossibleConfigurationFilenames({
|
|
872
|
-
customConfigFilename
|
|
873
|
-
}) {
|
|
874
|
-
if (customConfigFilename) {
|
|
875
|
-
if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
|
|
876
|
-
throw new Error(
|
|
877
|
-
`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.`
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
return Array.from(
|
|
881
|
-
/* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
|
|
882
|
-
);
|
|
883
|
-
}
|
|
884
|
-
return DEFAULT_CONFIGURATION_FILENAMES;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
// src/config/microfrontends/utils/find-config.ts
|
|
888
|
-
function findConfig({
|
|
889
|
-
dir,
|
|
890
|
-
customConfigFilename
|
|
891
|
-
}) {
|
|
892
|
-
for (const filename of getPossibleConfigurationFilenames({
|
|
893
|
-
customConfigFilename
|
|
894
|
-
})) {
|
|
895
|
-
const maybeConfig = join(dir, filename);
|
|
896
|
-
if (fs.existsSync(maybeConfig)) {
|
|
897
|
-
return maybeConfig;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
return null;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
1076
|
// src/config/microfrontends/utils/find-package-root.ts
|
|
904
1077
|
import fs2 from "node:fs";
|
|
905
1078
|
import path from "node:path";
|
|
@@ -1032,179 +1205,6 @@ function getApplicationContext(opts) {
|
|
|
1032
1205
|
}
|
|
1033
1206
|
}
|
|
1034
1207
|
|
|
1035
|
-
// src/config/microfrontends/utils/infer-microfrontends-location.ts
|
|
1036
|
-
import { readFileSync, statSync } from "node:fs";
|
|
1037
|
-
import { dirname, join as join2 } from "node:path";
|
|
1038
|
-
import fg from "fast-glob";
|
|
1039
|
-
import { parse as parse2 } from "jsonc-parser";
|
|
1040
|
-
var configCache = {};
|
|
1041
|
-
function findPackageWithMicrofrontendsConfig({
|
|
1042
|
-
repositoryRoot,
|
|
1043
|
-
applicationContext,
|
|
1044
|
-
customConfigFilename
|
|
1045
|
-
}) {
|
|
1046
|
-
const applicationName = applicationContext.name;
|
|
1047
|
-
logger.debug(
|
|
1048
|
-
"[MFE Config] Searching repository for configs containing application:",
|
|
1049
|
-
applicationName
|
|
1050
|
-
);
|
|
1051
|
-
try {
|
|
1052
|
-
const microfrontendsJsonPaths = fg.globSync(
|
|
1053
|
-
`**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
|
|
1054
|
-
{
|
|
1055
|
-
cwd: repositoryRoot,
|
|
1056
|
-
absolute: true,
|
|
1057
|
-
onlyFiles: true,
|
|
1058
|
-
followSymbolicLinks: false,
|
|
1059
|
-
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
1060
|
-
}
|
|
1061
|
-
);
|
|
1062
|
-
logger.debug(
|
|
1063
|
-
"[MFE Config] Found",
|
|
1064
|
-
microfrontendsJsonPaths.length,
|
|
1065
|
-
"config file(s) in repository"
|
|
1066
|
-
);
|
|
1067
|
-
const matchingPaths = [];
|
|
1068
|
-
for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
|
|
1069
|
-
if (doesApplicationExistInConfig(microfrontendsJsonPath, applicationName)) {
|
|
1070
|
-
matchingPaths.push(microfrontendsJsonPath);
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
logger.debug(
|
|
1074
|
-
"[MFE Config] Total matching config files:",
|
|
1075
|
-
matchingPaths.length
|
|
1076
|
-
);
|
|
1077
|
-
if (matchingPaths.length > 1) {
|
|
1078
|
-
throw new MicrofrontendError(
|
|
1079
|
-
`Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
|
|
1080
|
-
${matchingPaths.join("\n \u2022 ")}`,
|
|
1081
|
-
{ type: "config", subtype: "inference_failed" }
|
|
1082
|
-
);
|
|
1083
|
-
}
|
|
1084
|
-
if (matchingPaths.length === 0) {
|
|
1085
|
-
if (repositoryRoot && doesMisplacedConfigExist(
|
|
1086
|
-
repositoryRoot,
|
|
1087
|
-
applicationName,
|
|
1088
|
-
customConfigFilename
|
|
1089
|
-
)) {
|
|
1090
|
-
logger.debug(
|
|
1091
|
-
"[MFE Config] Found misplaced config in wrong .vercel directory in repository"
|
|
1092
|
-
);
|
|
1093
|
-
const misplacedConfigPath = join2(
|
|
1094
|
-
repositoryRoot,
|
|
1095
|
-
".vercel",
|
|
1096
|
-
customConfigFilename || "microfrontends.json"
|
|
1097
|
-
);
|
|
1098
|
-
throw new MicrofrontendError(
|
|
1099
|
-
`Unable to automatically infer the location of the \`microfrontends.json\` file.
|
|
1100
|
-
|
|
1101
|
-
A microfrontends config was found in the \`.vercel\` directory at the repository root: ${misplacedConfigPath}
|
|
1102
|
-
However, in a monorepo, the config file should be placed in the \`.vercel\` directory in your application directory instead.
|
|
1103
|
-
|
|
1104
|
-
To fix this:
|
|
1105
|
-
1. If using \`vercel link\`, run it with \`vercel link --repo\` to handle monorepos, or run \`vercel microfrontends pull --cwd=<application-directory>\` to make sure it pulls the \`microfrontends.json\` file to the correct location
|
|
1106
|
-
2. If manually defined, move the config file to the \`.vercel\` directory in your application
|
|
1107
|
-
3. Alternatively, set the VC_MICROFRONTENDS_CONFIG environment variable to the correct path
|
|
1108
|
-
|
|
1109
|
-
For more information, see: https://vercel.com/docs/cli/project-linking`,
|
|
1110
|
-
{ type: "config", subtype: "inference_failed" }
|
|
1111
|
-
);
|
|
1112
|
-
}
|
|
1113
|
-
let additionalErrorMessage = "";
|
|
1114
|
-
if (microfrontendsJsonPaths.length > 0) {
|
|
1115
|
-
if (!applicationContext.projectName) {
|
|
1116
|
-
additionalErrorMessage = `
|
|
1117
|
-
|
|
1118
|
-
If the name in package.json (${applicationContext.packageJsonName}) differs from your Vercel Project name, set the \`packageName\` field for the application in \`microfrontends.json\` to ensure that the configuration can be found locally.`;
|
|
1119
|
-
} else {
|
|
1120
|
-
additionalErrorMessage = `
|
|
1121
|
-
|
|
1122
|
-
Names of applications in \`microfrontends.json\` must match the Vercel Project name (${applicationContext.projectName}).`;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
throw new MicrofrontendError(
|
|
1126
|
-
`Could not find a \`microfrontends.json\` file in the repository that contains the "${applicationName}" application.${additionalErrorMessage}
|
|
1127
|
-
|
|
1128
|
-
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.
|
|
1129
|
-
|
|
1130
|
-
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.
|
|
1131
|
-
|
|
1132
|
-
If you suspect this is thrown in error, please reach out to the Vercel team.`,
|
|
1133
|
-
{ type: "config", subtype: "inference_failed" }
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
|
-
const [packageJsonPath] = matchingPaths;
|
|
1137
|
-
return dirname(packageJsonPath);
|
|
1138
|
-
} catch (error2) {
|
|
1139
|
-
if (error2 instanceof MicrofrontendError) {
|
|
1140
|
-
throw error2;
|
|
1141
|
-
}
|
|
1142
|
-
return null;
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
function inferMicrofrontendsLocation(opts) {
|
|
1146
|
-
const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}${opts.customConfigFilename ? `-${opts.customConfigFilename}` : ""}`;
|
|
1147
|
-
if (configCache[cacheKey]) {
|
|
1148
|
-
return configCache[cacheKey];
|
|
1149
|
-
}
|
|
1150
|
-
const result = findPackageWithMicrofrontendsConfig(opts);
|
|
1151
|
-
if (!result) {
|
|
1152
|
-
throw new MicrofrontendError(
|
|
1153
|
-
`Could not infer the location of the \`microfrontends.json\` file for application "${opts.applicationContext.name}" starting in directory "${opts.repositoryRoot}".`,
|
|
1154
|
-
{ type: "config", subtype: "inference_failed" }
|
|
1155
|
-
);
|
|
1156
|
-
}
|
|
1157
|
-
configCache[cacheKey] = result;
|
|
1158
|
-
return result;
|
|
1159
|
-
}
|
|
1160
|
-
function existsSync(path6) {
|
|
1161
|
-
try {
|
|
1162
|
-
statSync(path6);
|
|
1163
|
-
return true;
|
|
1164
|
-
} catch (_) {
|
|
1165
|
-
return false;
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
function doesMisplacedConfigExist(repositoryRoot, applicationName, customConfigFilename) {
|
|
1169
|
-
logger.debug(
|
|
1170
|
-
"[MFE Config] Looking for misplaced config in wrong .vercel directory"
|
|
1171
|
-
);
|
|
1172
|
-
const misplacedConfigPath = join2(
|
|
1173
|
-
repositoryRoot,
|
|
1174
|
-
".vercel",
|
|
1175
|
-
customConfigFilename || "microfrontends.json"
|
|
1176
|
-
);
|
|
1177
|
-
return existsSync(misplacedConfigPath) && doesApplicationExistInConfig(misplacedConfigPath, applicationName);
|
|
1178
|
-
}
|
|
1179
|
-
function doesApplicationExistInConfig(microfrontendsJsonPath, applicationName) {
|
|
1180
|
-
try {
|
|
1181
|
-
const microfrontendsJsonContent = readFileSync(
|
|
1182
|
-
microfrontendsJsonPath,
|
|
1183
|
-
"utf-8"
|
|
1184
|
-
);
|
|
1185
|
-
const microfrontendsJson = parse2(microfrontendsJsonContent);
|
|
1186
|
-
if (microfrontendsJson.applications[applicationName]) {
|
|
1187
|
-
logger.debug(
|
|
1188
|
-
"[MFE Config] Found application in config:",
|
|
1189
|
-
microfrontendsJsonPath
|
|
1190
|
-
);
|
|
1191
|
-
return true;
|
|
1192
|
-
}
|
|
1193
|
-
for (const [_, app] of Object.entries(microfrontendsJson.applications)) {
|
|
1194
|
-
if (app.packageName === applicationName) {
|
|
1195
|
-
logger.debug(
|
|
1196
|
-
"[MFE Config] Found application via packageName in config:",
|
|
1197
|
-
microfrontendsJsonPath
|
|
1198
|
-
);
|
|
1199
|
-
return true;
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
} catch (error2) {
|
|
1203
|
-
logger.debug("[MFE Config] Error checking application in config:", error2);
|
|
1204
|
-
}
|
|
1205
|
-
return false;
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
1208
|
// src/config/microfrontends/utils/is-monorepo.ts
|
|
1209
1209
|
import fs5 from "node:fs";
|
|
1210
1210
|
import path4 from "node:path";
|