@vercel/microfrontends 1.5.0-canary.2 → 2.0.0-canary.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.
- package/CHANGELOG.md +10 -18
- package/dist/bin/cli.cjs +103 -117
- package/dist/config.cjs +48 -101
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +2 -29
- package/dist/config.js +37 -100
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +93 -109
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +92 -108
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +93 -109
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +92 -108
- package/dist/experimental/vite.js.map +1 -1
- package/dist/get-application-context-e8a5a0e2.d.ts +14 -0
- package/dist/microfrontends/server.cjs +93 -109
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.d.ts +4 -13
- package/dist/microfrontends/server.js +92 -108
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/microfrontends/utils.cjs +24 -4
- package/dist/microfrontends/utils.cjs.map +1 -1
- package/dist/microfrontends/utils.d.ts +3 -1
- package/dist/microfrontends/utils.js +24 -4
- package/dist/microfrontends/utils.js.map +1 -1
- package/dist/next/client.cjs +1 -1
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js +1 -1
- package/dist/next/client.js.map +1 -1
- package/dist/next/config.cjs +244 -117
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.d.ts +1 -1
- package/dist/next/config.js +243 -116
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +88 -44
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +78 -44
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +51 -104
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +2 -2
- package/dist/next/testing.js +39 -102
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.d.ts +3 -3
- package/dist/schema.d.ts +2 -2
- package/dist/{types-1cec43e6.d.ts → types-0deb756b.d.ts} +16 -1
- package/dist/{types-1fb60496.d.ts → types-4299bff1.d.ts} +1 -1
- package/dist/utils/mfe-port.cjs +93 -109
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +92 -108
- package/dist/utils/mfe-port.js.map +1 -1
- package/dist/validation.cjs +4 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/dist/validation.js +4 -0
- package/dist/validation.js.map +1 -1
- package/package.json +3 -1
- package/schema/schema.json +4 -0
package/dist/next/config.cjs
CHANGED
|
@@ -242,8 +242,9 @@ var CONFIGURATION_FILENAMES = [
|
|
|
242
242
|
var configCache = {};
|
|
243
243
|
function findPackageWithMicrofrontendsConfig({
|
|
244
244
|
repositoryRoot,
|
|
245
|
-
|
|
245
|
+
applicationContext
|
|
246
246
|
}) {
|
|
247
|
+
const applicationName = applicationContext.name;
|
|
247
248
|
try {
|
|
248
249
|
const microfrontendsJsonPaths = import_fast_glob.default.globSync(
|
|
249
250
|
`**/{${CONFIGURATION_FILENAMES.join(",")}}`,
|
|
@@ -285,26 +286,45 @@ ${matchingPaths.join("\n \u2022 ")}`,
|
|
|
285
286
|
);
|
|
286
287
|
}
|
|
287
288
|
if (matchingPaths.length === 0) {
|
|
289
|
+
let additionalErrorMessage = "";
|
|
290
|
+
if (microfrontendsJsonPaths.length > 0) {
|
|
291
|
+
if (!applicationContext.projectName) {
|
|
292
|
+
additionalErrorMessage = `
|
|
293
|
+
|
|
294
|
+
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.`;
|
|
295
|
+
} else {
|
|
296
|
+
additionalErrorMessage = `
|
|
297
|
+
|
|
298
|
+
Names of applications in \`microfrontends.json\` must match the Vercel Project name (${applicationContext.projectName}).`;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
288
301
|
throw new MicrofrontendError(
|
|
289
|
-
`Could not find a \`microfrontends.json\` file in the repository that contains "
|
|
302
|
+
`Could not find a \`microfrontends.json\` file in the repository that contains the "${applicationName}" application.${additionalErrorMessage}
|
|
303
|
+
|
|
304
|
+
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.
|
|
305
|
+
|
|
306
|
+
If you suspect this is thrown in error, please reach out to the Vercel team.`,
|
|
290
307
|
{ type: "config", subtype: "inference_failed" }
|
|
291
308
|
);
|
|
292
309
|
}
|
|
293
310
|
const [packageJsonPath] = matchingPaths;
|
|
294
311
|
return (0, import_node_path2.dirname)(packageJsonPath);
|
|
295
312
|
} catch (error) {
|
|
313
|
+
if (error instanceof MicrofrontendError) {
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
296
316
|
return null;
|
|
297
317
|
}
|
|
298
318
|
}
|
|
299
319
|
function inferMicrofrontendsLocation(opts) {
|
|
300
|
-
const cacheKey = `${opts.repositoryRoot}-${opts.
|
|
320
|
+
const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}`;
|
|
301
321
|
if (configCache[cacheKey]) {
|
|
302
322
|
return configCache[cacheKey];
|
|
303
323
|
}
|
|
304
324
|
const result = findPackageWithMicrofrontendsConfig(opts);
|
|
305
325
|
if (!result) {
|
|
306
326
|
throw new MicrofrontendError(
|
|
307
|
-
`Could not infer the location of the \`microfrontends.json\` file for application "${opts.
|
|
327
|
+
`Could not infer the location of the \`microfrontends.json\` file for application "${opts.applicationContext.name}" starting in directory "${opts.repositoryRoot}".`,
|
|
308
328
|
{ type: "config", subtype: "inference_failed" }
|
|
309
329
|
);
|
|
310
330
|
}
|
|
@@ -376,90 +396,13 @@ function findConfig({ dir }) {
|
|
|
376
396
|
// src/config/microfrontends-config/isomorphic/index.ts
|
|
377
397
|
var import_jsonc_parser2 = require("jsonc-parser");
|
|
378
398
|
|
|
379
|
-
// src/config/microfrontends-config/client/index.ts
|
|
380
|
-
var import_path_to_regexp = require("path-to-regexp");
|
|
381
|
-
var regexpCache = /* @__PURE__ */ new Map();
|
|
382
|
-
var getRegexp = (path6) => {
|
|
383
|
-
const existing = regexpCache.get(path6);
|
|
384
|
-
if (existing) {
|
|
385
|
-
return existing;
|
|
386
|
-
}
|
|
387
|
-
const regexp = (0, import_path_to_regexp.pathToRegexp)(path6);
|
|
388
|
-
regexpCache.set(path6, regexp);
|
|
389
|
-
return regexp;
|
|
390
|
-
};
|
|
391
|
-
var MicrofrontendConfigClient = class {
|
|
392
|
-
constructor(config, opts) {
|
|
393
|
-
this.pathCache = {};
|
|
394
|
-
this.serialized = config;
|
|
395
|
-
if (opts?.removeFlaggedPaths) {
|
|
396
|
-
for (const app of Object.values(config.applications)) {
|
|
397
|
-
if (app.routing) {
|
|
398
|
-
app.routing = app.routing.filter((match) => !match.flag);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
this.applications = config.applications;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
406
|
-
* Config must be passed in to remain framework agnostic
|
|
407
|
-
*/
|
|
408
|
-
static fromEnv(config, opts) {
|
|
409
|
-
if (!config) {
|
|
410
|
-
throw new Error(
|
|
411
|
-
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
412
|
-
);
|
|
413
|
-
}
|
|
414
|
-
return new MicrofrontendConfigClient(
|
|
415
|
-
JSON.parse(config),
|
|
416
|
-
opts
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
isEqual(other) {
|
|
420
|
-
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
421
|
-
}
|
|
422
|
-
getApplicationNameForPath(path6) {
|
|
423
|
-
if (!path6.startsWith("/")) {
|
|
424
|
-
throw new Error(`Path must start with a /`);
|
|
425
|
-
}
|
|
426
|
-
if (this.pathCache[path6]) {
|
|
427
|
-
return this.pathCache[path6];
|
|
428
|
-
}
|
|
429
|
-
const pathname = new URL(path6, "https://example.com").pathname;
|
|
430
|
-
for (const [name, application] of Object.entries(this.applications)) {
|
|
431
|
-
if (application.routing) {
|
|
432
|
-
for (const group of application.routing) {
|
|
433
|
-
for (const childPath of group.paths) {
|
|
434
|
-
const regexp = getRegexp(childPath);
|
|
435
|
-
if (regexp.test(pathname)) {
|
|
436
|
-
this.pathCache[path6] = name;
|
|
437
|
-
return name;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
const defaultApplication = Object.entries(this.applications).find(
|
|
444
|
-
([, application]) => application.default
|
|
445
|
-
);
|
|
446
|
-
if (!defaultApplication) {
|
|
447
|
-
return null;
|
|
448
|
-
}
|
|
449
|
-
this.pathCache[path6] = defaultApplication[0];
|
|
450
|
-
return defaultApplication[0];
|
|
451
|
-
}
|
|
452
|
-
serialize() {
|
|
453
|
-
return this.serialized;
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
|
|
457
399
|
// src/config/microfrontends-config/isomorphic/validation.ts
|
|
458
|
-
var
|
|
400
|
+
var import_path_to_regexp = require("path-to-regexp");
|
|
459
401
|
var LIST_FORMATTER = new Intl.ListFormat("en", {
|
|
460
402
|
style: "long",
|
|
461
403
|
type: "conjunction"
|
|
462
404
|
});
|
|
405
|
+
var VALID_ASSET_PREFIX_REGEXP = /^[a-z](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
463
406
|
var validateConfigPaths = (applicationConfigsById) => {
|
|
464
407
|
if (!applicationConfigsById) {
|
|
465
408
|
return;
|
|
@@ -482,7 +425,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
482
425
|
} else {
|
|
483
426
|
pathsByApplicationId.set(path6, {
|
|
484
427
|
applications: [id],
|
|
485
|
-
matcher: (0,
|
|
428
|
+
matcher: (0, import_path_to_regexp.pathToRegexp)(path6),
|
|
486
429
|
applicationId: id
|
|
487
430
|
});
|
|
488
431
|
}
|
|
@@ -529,7 +472,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
529
472
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
530
473
|
function validatePathExpression(path6) {
|
|
531
474
|
try {
|
|
532
|
-
const tokens = (0,
|
|
475
|
+
const tokens = (0, import_path_to_regexp.parse)(path6);
|
|
533
476
|
if (/(?<!\\)\{/.test(path6)) {
|
|
534
477
|
return `Optional paths are not supported: ${path6}`;
|
|
535
478
|
}
|
|
@@ -586,6 +529,22 @@ var validateAppPaths = (name, app) => {
|
|
|
586
529
|
}
|
|
587
530
|
}
|
|
588
531
|
}
|
|
532
|
+
if (app.assetPrefix) {
|
|
533
|
+
if (!VALID_ASSET_PREFIX_REGEXP.test(app.assetPrefix)) {
|
|
534
|
+
throw new MicrofrontendError(
|
|
535
|
+
`Invalid asset prefix for application "${name}". ${app.assetPrefix} must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.`,
|
|
536
|
+
{ type: "application", subtype: "invalid_asset_prefix" }
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
if (app.assetPrefix !== `vc-ap-${name}` && !app.routing.some(
|
|
540
|
+
(group) => group.paths.includes(`/${app.assetPrefix}/:path*`) && !group.flag
|
|
541
|
+
)) {
|
|
542
|
+
throw new MicrofrontendError(
|
|
543
|
+
`When \`assetPrefix\` is specified, \`/${app.assetPrefix}/:path*\` must be added the routing paths for the application. Changing the asset prefix is not a forwards and backwards compatible change, and the custom asset prefix should be added to \`paths\` and deployed before setting the \`assetPrefix\` field.`,
|
|
544
|
+
{ type: "application", subtype: "invalid_asset_prefix" }
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
589
548
|
};
|
|
590
549
|
var validateConfigDefaultApplication = (applicationConfigsById) => {
|
|
591
550
|
if (!applicationConfigsById) {
|
|
@@ -617,6 +576,15 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
|
|
|
617
576
|
}
|
|
618
577
|
};
|
|
619
578
|
|
|
579
|
+
// src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
|
|
580
|
+
var import_md5 = __toESM(require("md5"), 1);
|
|
581
|
+
function hashApplicationName(name) {
|
|
582
|
+
if (!name) {
|
|
583
|
+
throw new Error("Application name is required to generate hash");
|
|
584
|
+
}
|
|
585
|
+
return (0, import_md5.default)(name).substring(0, 6).padStart(6, "0");
|
|
586
|
+
}
|
|
587
|
+
|
|
620
588
|
// src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
|
|
621
589
|
var PREFIX = "vc-ap";
|
|
622
590
|
function generateAssetPrefixFromName({
|
|
@@ -625,7 +593,7 @@ function generateAssetPrefixFromName({
|
|
|
625
593
|
if (!name) {
|
|
626
594
|
throw new Error("Name is required to generate an asset prefix");
|
|
627
595
|
}
|
|
628
|
-
return `${PREFIX}-${name}`;
|
|
596
|
+
return `${PREFIX}-${hashApplicationName(name)}`;
|
|
629
597
|
}
|
|
630
598
|
|
|
631
599
|
// src/config/microfrontends-config/isomorphic/utils/generate-port.ts
|
|
@@ -785,7 +753,13 @@ var Application = class {
|
|
|
785
753
|
return this.default;
|
|
786
754
|
}
|
|
787
755
|
getAssetPrefix() {
|
|
788
|
-
|
|
756
|
+
const generatedAssetPrefix = generateAssetPrefixFromName({
|
|
757
|
+
name: this.name
|
|
758
|
+
});
|
|
759
|
+
if ("assetPrefix" in this.serialized) {
|
|
760
|
+
return this.serialized.assetPrefix ?? generatedAssetPrefix;
|
|
761
|
+
}
|
|
762
|
+
return generatedAssetPrefix;
|
|
789
763
|
}
|
|
790
764
|
getAutomationBypassEnvVarName() {
|
|
791
765
|
return generateAutomationBypassEnvVarName({ name: this.name });
|
|
@@ -919,7 +893,7 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
919
893
|
);
|
|
920
894
|
if (!app) {
|
|
921
895
|
throw new MicrofrontendError(
|
|
922
|
-
`Could not find microfrontends configuration for application "${name}"
|
|
896
|
+
`Could not find microfrontends configuration for application "${name}". If the name in package.json 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.`,
|
|
923
897
|
{
|
|
924
898
|
type: "application",
|
|
925
899
|
subtype: "not_found"
|
|
@@ -964,23 +938,6 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
964
938
|
toSchemaJson() {
|
|
965
939
|
return this.serialized.config;
|
|
966
940
|
}
|
|
967
|
-
toClientConfig() {
|
|
968
|
-
const applications = Object.fromEntries(
|
|
969
|
-
Object.entries(this.childApplications).map(([name, application]) => [
|
|
970
|
-
name,
|
|
971
|
-
{
|
|
972
|
-
default: false,
|
|
973
|
-
routing: application.routing
|
|
974
|
-
}
|
|
975
|
-
])
|
|
976
|
-
);
|
|
977
|
-
applications[this.defaultApplication.name] = {
|
|
978
|
-
default: true
|
|
979
|
-
};
|
|
980
|
-
return new MicrofrontendConfigClient({
|
|
981
|
-
applications
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
941
|
serialize() {
|
|
985
942
|
return this.serialized;
|
|
986
943
|
}
|
|
@@ -993,8 +950,31 @@ function getApplicationContext(opts) {
|
|
|
993
950
|
if (opts?.appName) {
|
|
994
951
|
return { name: opts.appName };
|
|
995
952
|
}
|
|
953
|
+
if (process.env.VERCEL_PROJECT_NAME) {
|
|
954
|
+
return {
|
|
955
|
+
name: process.env.VERCEL_PROJECT_NAME,
|
|
956
|
+
projectName: process.env.VERCEL_PROJECT_NAME
|
|
957
|
+
};
|
|
958
|
+
}
|
|
996
959
|
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
997
|
-
return {
|
|
960
|
+
return {
|
|
961
|
+
name: process.env.NX_TASK_TARGET_PROJECT,
|
|
962
|
+
packageJsonName: process.env.NX_TASK_TARGET_PROJECT
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
try {
|
|
966
|
+
const vercelProjectJsonPath = import_node_fs6.default.readFileSync(
|
|
967
|
+
import_node_path6.default.join(opts?.packageRoot || ".", ".vercel", "project.json"),
|
|
968
|
+
"utf-8"
|
|
969
|
+
);
|
|
970
|
+
const projectJson = JSON.parse(vercelProjectJsonPath);
|
|
971
|
+
if (projectJson.projectName) {
|
|
972
|
+
return {
|
|
973
|
+
name: projectJson.projectName,
|
|
974
|
+
projectName: projectJson.projectName
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
} catch (_) {
|
|
998
978
|
}
|
|
999
979
|
try {
|
|
1000
980
|
const packageJsonString = import_node_fs6.default.readFileSync(
|
|
@@ -1012,7 +992,7 @@ function getApplicationContext(opts) {
|
|
|
1012
992
|
}
|
|
1013
993
|
);
|
|
1014
994
|
}
|
|
1015
|
-
return { name: packageJson.name };
|
|
995
|
+
return { name: packageJson.name, packageJsonName: packageJson.name };
|
|
1016
996
|
} catch (err) {
|
|
1017
997
|
throw MicrofrontendError.handle(err, {
|
|
1018
998
|
fileName: "package.json"
|
|
@@ -1152,6 +1132,10 @@ var schema_default = {
|
|
|
1152
1132
|
routing: {
|
|
1153
1133
|
$ref: "#/definitions/Routing",
|
|
1154
1134
|
description: "Groups of path expressions that are routed to this application."
|
|
1135
|
+
},
|
|
1136
|
+
assetPrefix: {
|
|
1137
|
+
type: "string",
|
|
1138
|
+
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."
|
|
1155
1139
|
}
|
|
1156
1140
|
},
|
|
1157
1141
|
required: [
|
|
@@ -1377,7 +1361,7 @@ var MicrofrontendsServer = class {
|
|
|
1377
1361
|
}
|
|
1378
1362
|
try {
|
|
1379
1363
|
const packageRoot = findPackageRoot(directory);
|
|
1380
|
-
const
|
|
1364
|
+
const applicationContext = getApplicationContext({ packageRoot });
|
|
1381
1365
|
const maybeConfig = findConfig({ dir: packageRoot });
|
|
1382
1366
|
if (maybeConfig) {
|
|
1383
1367
|
return MicrofrontendsServer.fromFile({
|
|
@@ -1411,7 +1395,7 @@ var MicrofrontendsServer = class {
|
|
|
1411
1395
|
if (isMonorepo2) {
|
|
1412
1396
|
const defaultPackage = inferMicrofrontendsLocation({
|
|
1413
1397
|
repositoryRoot,
|
|
1414
|
-
|
|
1398
|
+
applicationContext
|
|
1415
1399
|
});
|
|
1416
1400
|
const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
|
|
1417
1401
|
if (maybeConfigFromDefault) {
|
|
@@ -1591,6 +1575,20 @@ ${indent} - Automatically redirecting all requests to local microfrontends proxy
|
|
|
1591
1575
|
return { next };
|
|
1592
1576
|
}
|
|
1593
1577
|
|
|
1578
|
+
// src/next/config/transforms/transpile-packages.ts
|
|
1579
|
+
function transform5(args) {
|
|
1580
|
+
const { next } = args;
|
|
1581
|
+
if (next.transpilePackages === void 0 || !next.transpilePackages.includes("@vercel/microfrontends")) {
|
|
1582
|
+
next.transpilePackages = [
|
|
1583
|
+
...next.transpilePackages || [],
|
|
1584
|
+
"@vercel/microfrontends"
|
|
1585
|
+
];
|
|
1586
|
+
}
|
|
1587
|
+
return {
|
|
1588
|
+
next
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1594
1592
|
// src/next/config/transforms/rewrites.ts
|
|
1595
1593
|
function debugRewrites(rewrites) {
|
|
1596
1594
|
if (process.env.MFE_DEBUG) {
|
|
@@ -1623,7 +1621,7 @@ function rewritesMapToArr(rewrites) {
|
|
|
1623
1621
|
];
|
|
1624
1622
|
});
|
|
1625
1623
|
}
|
|
1626
|
-
function
|
|
1624
|
+
function transform6(args) {
|
|
1627
1625
|
const { app, next } = args;
|
|
1628
1626
|
const buildBeforeFiles = () => {
|
|
1629
1627
|
const rewrites = /* @__PURE__ */ new Map();
|
|
@@ -1708,7 +1706,7 @@ var SortChunksPlugin = class {
|
|
|
1708
1706
|
// src/next/config/transforms/webpack.ts
|
|
1709
1707
|
var import_meta = {};
|
|
1710
1708
|
var nextVersion = getNextJsVersion();
|
|
1711
|
-
function
|
|
1709
|
+
function transform7(args) {
|
|
1712
1710
|
const useDefineServer = args.opts?.preferWebpackEnvironmentPlugin ? false : semver.gte(nextVersion, "15.4.0-canary.41");
|
|
1713
1711
|
const { next, microfrontend, opts } = args;
|
|
1714
1712
|
const configWithWebpack = {
|
|
@@ -1792,10 +1790,133 @@ var transforms = {
|
|
|
1792
1790
|
buildId: transform2,
|
|
1793
1791
|
draftMode: transform3,
|
|
1794
1792
|
redirects: transform4,
|
|
1795
|
-
rewrites:
|
|
1796
|
-
|
|
1793
|
+
rewrites: transform6,
|
|
1794
|
+
transpilePackages: transform5,
|
|
1795
|
+
webpack: transform7
|
|
1797
1796
|
};
|
|
1798
1797
|
|
|
1798
|
+
// src/config/microfrontends-config/client/index.ts
|
|
1799
|
+
var import_path_to_regexp2 = require("path-to-regexp");
|
|
1800
|
+
var regexpCache = /* @__PURE__ */ new Map();
|
|
1801
|
+
var getRegexp = (path6) => {
|
|
1802
|
+
const existing = regexpCache.get(path6);
|
|
1803
|
+
if (existing) {
|
|
1804
|
+
return existing;
|
|
1805
|
+
}
|
|
1806
|
+
const regexp = (0, import_path_to_regexp2.pathToRegexp)(path6);
|
|
1807
|
+
regexpCache.set(path6, regexp);
|
|
1808
|
+
return regexp;
|
|
1809
|
+
};
|
|
1810
|
+
var MicrofrontendConfigClient = class {
|
|
1811
|
+
constructor(config, opts) {
|
|
1812
|
+
this.pathCache = {};
|
|
1813
|
+
this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
|
|
1814
|
+
for (const app of Object.values(config.applications)) {
|
|
1815
|
+
if (app.routing) {
|
|
1816
|
+
if (app.routing.some((match) => match.flag)) {
|
|
1817
|
+
this.hasFlaggedPaths = true;
|
|
1818
|
+
}
|
|
1819
|
+
const newRouting = [];
|
|
1820
|
+
const pathsWithoutFlags = [];
|
|
1821
|
+
for (const group of app.routing) {
|
|
1822
|
+
if (group.flag) {
|
|
1823
|
+
if (opts?.removeFlaggedPaths) {
|
|
1824
|
+
continue;
|
|
1825
|
+
}
|
|
1826
|
+
if (group.group) {
|
|
1827
|
+
delete group.group;
|
|
1828
|
+
}
|
|
1829
|
+
newRouting.push(group);
|
|
1830
|
+
} else {
|
|
1831
|
+
pathsWithoutFlags.push(...group.paths);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
if (pathsWithoutFlags.length > 0) {
|
|
1835
|
+
newRouting.push({ paths: pathsWithoutFlags });
|
|
1836
|
+
}
|
|
1837
|
+
app.routing = newRouting;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
this.serialized = config;
|
|
1841
|
+
if (this.hasFlaggedPaths) {
|
|
1842
|
+
this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
|
|
1843
|
+
}
|
|
1844
|
+
this.applications = config.applications;
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
1848
|
+
* Config must be passed in to remain framework agnostic
|
|
1849
|
+
*/
|
|
1850
|
+
static fromEnv(config) {
|
|
1851
|
+
if (!config) {
|
|
1852
|
+
throw new Error(
|
|
1853
|
+
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
1854
|
+
);
|
|
1855
|
+
}
|
|
1856
|
+
return new MicrofrontendConfigClient(JSON.parse(config));
|
|
1857
|
+
}
|
|
1858
|
+
isEqual(other) {
|
|
1859
|
+
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
1860
|
+
}
|
|
1861
|
+
getApplicationNameForPath(path6) {
|
|
1862
|
+
if (!path6.startsWith("/")) {
|
|
1863
|
+
throw new Error(`Path must start with a /`);
|
|
1864
|
+
}
|
|
1865
|
+
if (this.pathCache[path6]) {
|
|
1866
|
+
return this.pathCache[path6];
|
|
1867
|
+
}
|
|
1868
|
+
const pathname = new URL(path6, "https://example.com").pathname;
|
|
1869
|
+
for (const [name, application] of Object.entries(this.applications)) {
|
|
1870
|
+
if (application.routing) {
|
|
1871
|
+
for (const group of application.routing) {
|
|
1872
|
+
for (const childPath of group.paths) {
|
|
1873
|
+
const regexp = getRegexp(childPath);
|
|
1874
|
+
if (regexp.test(pathname)) {
|
|
1875
|
+
this.pathCache[path6] = name;
|
|
1876
|
+
return name;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
const defaultApplication = Object.entries(this.applications).find(
|
|
1883
|
+
([, application]) => application.default
|
|
1884
|
+
);
|
|
1885
|
+
if (!defaultApplication) {
|
|
1886
|
+
return null;
|
|
1887
|
+
}
|
|
1888
|
+
this.pathCache[path6] = defaultApplication[0];
|
|
1889
|
+
return defaultApplication[0];
|
|
1890
|
+
}
|
|
1891
|
+
serialize() {
|
|
1892
|
+
return this.serialized;
|
|
1893
|
+
}
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1896
|
+
// src/config/microfrontends-config/client/from-isomorphic-config.ts
|
|
1897
|
+
function fromIsomorphicConfig(config, options) {
|
|
1898
|
+
const applications = Object.fromEntries(
|
|
1899
|
+
Object.entries(config.childApplications).map(([name, application]) => [
|
|
1900
|
+
hashApplicationName(name),
|
|
1901
|
+
{
|
|
1902
|
+
default: false,
|
|
1903
|
+
routing: application.routing
|
|
1904
|
+
}
|
|
1905
|
+
])
|
|
1906
|
+
);
|
|
1907
|
+
applications[hashApplicationName(config.defaultApplication.name)] = {
|
|
1908
|
+
default: true
|
|
1909
|
+
};
|
|
1910
|
+
return new MicrofrontendConfigClient(
|
|
1911
|
+
{
|
|
1912
|
+
applications
|
|
1913
|
+
},
|
|
1914
|
+
{
|
|
1915
|
+
removeFlaggedPaths: options?.removeFlaggedPaths
|
|
1916
|
+
}
|
|
1917
|
+
);
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1799
1920
|
// src/next/config/env.ts
|
|
1800
1921
|
function debugEnv(env) {
|
|
1801
1922
|
if (process.env.MFE_DEBUG) {
|
|
@@ -1819,8 +1940,11 @@ function setEnvironment({
|
|
|
1819
1940
|
}) {
|
|
1820
1941
|
const clientEnvs = {
|
|
1821
1942
|
NEXT_PUBLIC_MFE_CURRENT_APPLICATION: app.name,
|
|
1943
|
+
NEXT_PUBLIC_MFE_CURRENT_APPLICATION_HASH: hashApplicationName(app.name),
|
|
1822
1944
|
NEXT_PUBLIC_MFE_CLIENT_CONFIG: JSON.stringify(
|
|
1823
|
-
microfrontends.config
|
|
1945
|
+
fromIsomorphicConfig(microfrontends.config, {
|
|
1946
|
+
removeFlaggedPaths: true
|
|
1947
|
+
}).serialize()
|
|
1824
1948
|
),
|
|
1825
1949
|
...process.env.ROUTE_OBSERVABILITY_TO_THIS_PROJECT && app.getAssetPrefix() ? {
|
|
1826
1950
|
NEXT_PUBLIC_VERCEL_OBSERVABILITY_BASEPATH: `/${app.getAssetPrefix()}/_vercel`
|
|
@@ -1828,7 +1952,10 @@ function setEnvironment({
|
|
|
1828
1952
|
};
|
|
1829
1953
|
const serverEnvs = {
|
|
1830
1954
|
MFE_CURRENT_APPLICATION: app.name,
|
|
1831
|
-
MFE_CONFIG: JSON.stringify(microfrontends.config.getConfig())
|
|
1955
|
+
MFE_CONFIG: JSON.stringify(microfrontends.config.getConfig()),
|
|
1956
|
+
MFE_CLIENT_CONFIG_FULL: JSON.stringify(
|
|
1957
|
+
fromIsomorphicConfig(microfrontends.config).serialize()
|
|
1958
|
+
)
|
|
1832
1959
|
};
|
|
1833
1960
|
const allEnvs = { ...clientEnvs, ...serverEnvs };
|
|
1834
1961
|
for (const [key, value] of Object.entries(allEnvs)) {
|
|
@@ -1858,13 +1985,13 @@ function withMicrofrontends(nextConfig, opts) {
|
|
|
1858
1985
|
const app = microfrontends.config.getApplication(fromApp);
|
|
1859
1986
|
setEnvironment({ app, microfrontends });
|
|
1860
1987
|
let next = { ...nextConfig };
|
|
1861
|
-
for (const [key,
|
|
1988
|
+
for (const [key, transform8] of typedEntries(transforms)) {
|
|
1862
1989
|
if (opts?.skipTransforms?.includes(key)) {
|
|
1863
1990
|
console.log(`Skipping ${key} transform`);
|
|
1864
1991
|
continue;
|
|
1865
1992
|
}
|
|
1866
1993
|
try {
|
|
1867
|
-
const transformedConfig =
|
|
1994
|
+
const transformedConfig = transform8({
|
|
1868
1995
|
app,
|
|
1869
1996
|
next,
|
|
1870
1997
|
microfrontend: microfrontends.config,
|