@vercel/microfrontends 1.0.1-canary.3 → 1.0.1-canary.5
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/dist/bin/cli.cjs +116 -79
- package/dist/config.cjs +3 -0
- package/dist/config.cjs.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +82 -72
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +82 -72
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +85 -75
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +85 -75
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +82 -45
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.js +82 -45
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/microfrontends.cjs +3 -0
- package/dist/microfrontends.cjs.map +1 -1
- package/dist/microfrontends.js +3 -0
- package/dist/microfrontends.js.map +1 -1
- package/dist/next/config.cjs +82 -72
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +82 -72
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +3 -0
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +3 -0
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +3 -0
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.js +3 -0
- package/dist/next/testing.js.map +1 -1
- package/dist/utils/mfe-port.cjs +86 -49
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +86 -49
- package/dist/utils/mfe-port.js.map +1 -1
- package/package.json +2 -2
|
@@ -8,8 +8,8 @@ function displayLocalProxyInfo(port) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
// src/config/microfrontends/server/index.ts
|
|
11
|
-
import
|
|
12
|
-
import { dirname as dirname3
|
|
11
|
+
import fs6 from "node:fs";
|
|
12
|
+
import { dirname as dirname3 } from "node:path";
|
|
13
13
|
|
|
14
14
|
// src/config/overrides/constants.ts
|
|
15
15
|
var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
|
|
@@ -192,21 +192,21 @@ var MicrofrontendConfigClient = class {
|
|
|
192
192
|
isEqual(other) {
|
|
193
193
|
return JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
194
194
|
}
|
|
195
|
-
getApplicationNameForPath(
|
|
196
|
-
if (!
|
|
195
|
+
getApplicationNameForPath(path6) {
|
|
196
|
+
if (!path6.startsWith("/")) {
|
|
197
197
|
throw new Error(`Path must start with a /`);
|
|
198
198
|
}
|
|
199
|
-
if (this.pathCache[
|
|
200
|
-
return this.pathCache[
|
|
199
|
+
if (this.pathCache[path6]) {
|
|
200
|
+
return this.pathCache[path6];
|
|
201
201
|
}
|
|
202
|
-
const pathname = new URL(
|
|
202
|
+
const pathname = new URL(path6, "https://example.com").pathname;
|
|
203
203
|
for (const [name, application] of Object.entries(this.applications)) {
|
|
204
204
|
if (application.routing) {
|
|
205
205
|
for (const group of application.routing) {
|
|
206
206
|
for (const childPath of group.paths) {
|
|
207
207
|
const regexp = pathToRegexp(childPath);
|
|
208
208
|
if (regexp.test(pathname)) {
|
|
209
|
-
this.pathCache[
|
|
209
|
+
this.pathCache[path6] = name;
|
|
210
210
|
return name;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
@@ -219,7 +219,7 @@ var MicrofrontendConfigClient = class {
|
|
|
219
219
|
if (!defaultApplication) {
|
|
220
220
|
return null;
|
|
221
221
|
}
|
|
222
|
-
this.pathCache[
|
|
222
|
+
this.pathCache[path6] = defaultApplication[0];
|
|
223
223
|
return defaultApplication[0];
|
|
224
224
|
}
|
|
225
225
|
serialize() {
|
|
@@ -241,18 +241,18 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
241
241
|
}
|
|
242
242
|
const childApp = app;
|
|
243
243
|
for (const pathMatch of childApp.routing) {
|
|
244
|
-
for (const
|
|
245
|
-
const maybeError = validatePathExpression(
|
|
244
|
+
for (const path6 of pathMatch.paths) {
|
|
245
|
+
const maybeError = validatePathExpression(path6);
|
|
246
246
|
if (maybeError) {
|
|
247
247
|
errors.push(maybeError);
|
|
248
248
|
} else {
|
|
249
|
-
const existing = pathsByApplicationId.get(
|
|
249
|
+
const existing = pathsByApplicationId.get(path6);
|
|
250
250
|
if (existing) {
|
|
251
251
|
existing.applications.push(id);
|
|
252
252
|
} else {
|
|
253
|
-
pathsByApplicationId.set(
|
|
253
|
+
pathsByApplicationId.set(path6, {
|
|
254
254
|
applications: [id],
|
|
255
|
-
matcher: pathToRegexp2(
|
|
255
|
+
matcher: pathToRegexp2(path6),
|
|
256
256
|
applicationId: id
|
|
257
257
|
});
|
|
258
258
|
}
|
|
@@ -261,24 +261,24 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
const entries = Array.from(pathsByApplicationId.entries());
|
|
264
|
-
for (const [
|
|
264
|
+
for (const [path6, { applications: ids, matcher, applicationId }] of entries) {
|
|
265
265
|
if (ids.length > 1) {
|
|
266
266
|
errors.push(
|
|
267
|
-
`Duplicate path "${
|
|
267
|
+
`Duplicate path "${path6}" for applications "${ids.join(", ")}"`
|
|
268
268
|
);
|
|
269
269
|
}
|
|
270
270
|
for (const [
|
|
271
271
|
matchPath,
|
|
272
272
|
{ applications: matchIds, applicationId: matchApplicationId }
|
|
273
273
|
] of entries) {
|
|
274
|
-
if (
|
|
274
|
+
if (path6 === matchPath) {
|
|
275
275
|
continue;
|
|
276
276
|
}
|
|
277
277
|
if (applicationId === matchApplicationId) {
|
|
278
278
|
continue;
|
|
279
279
|
}
|
|
280
280
|
if (matcher.test(matchPath)) {
|
|
281
|
-
const source = `"${
|
|
281
|
+
const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
|
|
282
282
|
const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
|
|
283
283
|
errors.push(
|
|
284
284
|
`Overlapping path detected between ${source} and ${destination}`
|
|
@@ -294,39 +294,42 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
294
294
|
}
|
|
295
295
|
};
|
|
296
296
|
var PATH_DEFAULT_PATTERN = "[^\\/#\\?]+?";
|
|
297
|
-
function validatePathExpression(
|
|
297
|
+
function validatePathExpression(path6) {
|
|
298
298
|
try {
|
|
299
|
-
const tokens = parsePathRegexp(
|
|
300
|
-
if (/(?<!\\)\{/.test(
|
|
301
|
-
return `Optional paths are not supported: ${
|
|
299
|
+
const tokens = parsePathRegexp(path6);
|
|
300
|
+
if (/(?<!\\)\{/.test(path6)) {
|
|
301
|
+
return `Optional paths are not supported: ${path6}`;
|
|
302
302
|
}
|
|
303
|
-
if (/(?<!\\|\()\?/.test(
|
|
304
|
-
return `Optional paths are not supported: ${
|
|
303
|
+
if (/(?<!\\|\()\?/.test(path6)) {
|
|
304
|
+
return `Optional paths are not supported: ${path6}`;
|
|
305
305
|
}
|
|
306
|
-
if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(
|
|
307
|
-
return `Only one wildcard is allowed per path segment: ${
|
|
306
|
+
if (/\/[^/]*(?<!\\):[^/]*(?<!\\):[^/]*/.test(path6)) {
|
|
307
|
+
return `Only one wildcard is allowed per path segment: ${path6}`;
|
|
308
308
|
}
|
|
309
309
|
for (let i = 0; i < tokens.length; i++) {
|
|
310
310
|
const token = tokens[i];
|
|
311
311
|
if (token === void 0) {
|
|
312
|
-
return `token ${i} in ${
|
|
312
|
+
return `token ${i} in ${path6} is undefined, this shouldn't happen`;
|
|
313
313
|
}
|
|
314
314
|
if (typeof token !== "string") {
|
|
315
|
+
if (!token.name) {
|
|
316
|
+
return `Only named wildcards are allowed: ${path6} (hint: add ":path" to the wildcard)`;
|
|
317
|
+
}
|
|
315
318
|
if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
|
|
316
319
|
// Only limited regex is supported for now, due to performance considerations
|
|
317
320
|
!/^(?<allowed>[\w]+(?:\|[^|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^|()]+)+)\)\.\*$/.test(
|
|
318
321
|
token.pattern
|
|
319
322
|
)) {
|
|
320
|
-
return `Path ${
|
|
323
|
+
return `Path ${path6} cannot use unsupported regular expression wildcard`;
|
|
321
324
|
}
|
|
322
325
|
if (token.modifier && i !== tokens.length - 1) {
|
|
323
|
-
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${
|
|
326
|
+
return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
|
|
324
327
|
}
|
|
325
328
|
}
|
|
326
329
|
}
|
|
327
330
|
} catch (e) {
|
|
328
331
|
const message = e instanceof Error ? e.message : String(e);
|
|
329
|
-
return `Path ${
|
|
332
|
+
return `Path ${path6} could not be parsed into regexp: ${message}`;
|
|
330
333
|
}
|
|
331
334
|
return void 0;
|
|
332
335
|
}
|
|
@@ -881,6 +884,9 @@ import fs from "node:fs";
|
|
|
881
884
|
import path from "node:path";
|
|
882
885
|
var GIT_DIRECTORY = ".git";
|
|
883
886
|
function findRepositoryRoot(startDir) {
|
|
887
|
+
if (process.env.NX_WORKSPACE_ROOT) {
|
|
888
|
+
return process.env.NX_WORKSPACE_ROOT;
|
|
889
|
+
}
|
|
884
890
|
let currentDir = startDir || process.cwd();
|
|
885
891
|
while (currentDir !== path.parse(currentDir).root) {
|
|
886
892
|
const gitPath = path.join(currentDir, GIT_DIRECTORY);
|
|
@@ -1038,6 +1044,9 @@ function isMonorepo({
|
|
|
1038
1044
|
if (fs2.existsSync(path2.join(repositoryRoot, "vlt-workspaces.json"))) {
|
|
1039
1045
|
return true;
|
|
1040
1046
|
}
|
|
1047
|
+
if (process.env.NX_WORKSPACE_ROOT === path2.resolve(repositoryRoot)) {
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1041
1050
|
const packageJsonPath = path2.join(repositoryRoot, "package.json");
|
|
1042
1051
|
if (!fs2.existsSync(packageJsonPath)) {
|
|
1043
1052
|
return false;
|
|
@@ -1083,8 +1092,42 @@ function findConfig({ dir }) {
|
|
|
1083
1092
|
return null;
|
|
1084
1093
|
}
|
|
1085
1094
|
|
|
1086
|
-
// src/config/microfrontends/
|
|
1095
|
+
// src/config/microfrontends/utils/get-application-context.ts
|
|
1096
|
+
import fs5 from "node:fs";
|
|
1087
1097
|
import path4 from "node:path";
|
|
1098
|
+
function getApplicationContext(opts) {
|
|
1099
|
+
if (opts?.appName) {
|
|
1100
|
+
return { name: opts.appName };
|
|
1101
|
+
}
|
|
1102
|
+
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
1103
|
+
return { name: process.env.NX_TASK_TARGET_PROJECT };
|
|
1104
|
+
}
|
|
1105
|
+
try {
|
|
1106
|
+
const packageJsonString = fs5.readFileSync(
|
|
1107
|
+
path4.join(opts?.packageRoot || ".", "package.json"),
|
|
1108
|
+
"utf-8"
|
|
1109
|
+
);
|
|
1110
|
+
const packageJson = JSON.parse(packageJsonString);
|
|
1111
|
+
if (!packageJson.name) {
|
|
1112
|
+
throw new MicrofrontendError(
|
|
1113
|
+
`package.json file missing required field "name"`,
|
|
1114
|
+
{
|
|
1115
|
+
type: "packageJson",
|
|
1116
|
+
subtype: "missing_field_name",
|
|
1117
|
+
source: "@vercel/microfrontends/next"
|
|
1118
|
+
}
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
return { name: packageJson.name };
|
|
1122
|
+
} catch (err) {
|
|
1123
|
+
throw MicrofrontendError.handle(err, {
|
|
1124
|
+
fileName: "package.json"
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/config/microfrontends/server/utils/get-output-file-path.ts
|
|
1130
|
+
import path5 from "node:path";
|
|
1088
1131
|
|
|
1089
1132
|
// src/config/microfrontends/server/constants.ts
|
|
1090
1133
|
var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
|
|
@@ -1092,7 +1135,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
|
|
|
1092
1135
|
|
|
1093
1136
|
// src/config/microfrontends/server/utils/get-output-file-path.ts
|
|
1094
1137
|
function getOutputFilePath() {
|
|
1095
|
-
return
|
|
1138
|
+
return path5.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
|
|
1096
1139
|
}
|
|
1097
1140
|
|
|
1098
1141
|
// src/config/microfrontends/server/validation.ts
|
|
@@ -1431,8 +1474,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1431
1474
|
pretty: true
|
|
1432
1475
|
}) {
|
|
1433
1476
|
const outputPath = getOutputFilePath();
|
|
1434
|
-
|
|
1435
|
-
|
|
1477
|
+
fs6.mkdirSync(dirname3(outputPath), { recursive: true });
|
|
1478
|
+
fs6.writeFileSync(
|
|
1436
1479
|
outputPath,
|
|
1437
1480
|
JSON.stringify(
|
|
1438
1481
|
this.config.toSchemaJson(),
|
|
@@ -1518,14 +1561,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1518
1561
|
}
|
|
1519
1562
|
try {
|
|
1520
1563
|
const packageRoot = findPackageRoot(directory);
|
|
1521
|
-
const
|
|
1522
|
-
const
|
|
1523
|
-
fs5.readFileSync(packageJsonPath, "utf-8")
|
|
1524
|
-
);
|
|
1525
|
-
if (!packageJson.name) {
|
|
1526
|
-
throw new Error(`No name found in package.json at ${packageJsonPath}`);
|
|
1527
|
-
}
|
|
1528
|
-
const configMeta = meta ?? { fromApp: packageJson.name };
|
|
1564
|
+
const { name: appName } = getApplicationContext({ packageRoot });
|
|
1565
|
+
const configMeta = meta ?? { fromApp: appName };
|
|
1529
1566
|
const maybeConfig = findConfig({ dir: packageRoot });
|
|
1530
1567
|
if (maybeConfig) {
|
|
1531
1568
|
return MicrofrontendsServer.fromFile({
|
|
@@ -1540,7 +1577,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1540
1577
|
if (isMonorepo2) {
|
|
1541
1578
|
const defaultPackage = findDefaultMicrofrontendsPackage({
|
|
1542
1579
|
repositoryRoot,
|
|
1543
|
-
applicationName:
|
|
1580
|
+
applicationName: appName
|
|
1544
1581
|
});
|
|
1545
1582
|
const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
|
|
1546
1583
|
if (maybeConfigFromDefault) {
|
|
@@ -1570,7 +1607,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1570
1607
|
options
|
|
1571
1608
|
}) {
|
|
1572
1609
|
try {
|
|
1573
|
-
const configJson =
|
|
1610
|
+
const configJson = fs6.readFileSync(filePath, "utf-8");
|
|
1574
1611
|
const config = MicrofrontendsServer.validate(configJson);
|
|
1575
1612
|
if (!isMainConfig(config) && options?.resolveMainConfig) {
|
|
1576
1613
|
const repositoryRoot = findRepositoryRoot();
|
|
@@ -1618,7 +1655,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1618
1655
|
overrides
|
|
1619
1656
|
}) {
|
|
1620
1657
|
try {
|
|
1621
|
-
const config =
|
|
1658
|
+
const config = fs6.readFileSync(filePath, "utf-8");
|
|
1622
1659
|
const validatedConfig = MicrofrontendsServer.validate(config);
|
|
1623
1660
|
if (!isMainConfig(validatedConfig)) {
|
|
1624
1661
|
throw new MicrofrontendError(
|
|
@@ -1649,33 +1686,6 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1649
1686
|
}
|
|
1650
1687
|
};
|
|
1651
1688
|
|
|
1652
|
-
// src/config/microfrontends/utils/get-application-context.ts
|
|
1653
|
-
import fs6 from "node:fs";
|
|
1654
|
-
function getApplicationContext(opts) {
|
|
1655
|
-
if (opts?.appName) {
|
|
1656
|
-
return { name: opts.appName };
|
|
1657
|
-
}
|
|
1658
|
-
try {
|
|
1659
|
-
const packageJsonString = fs6.readFileSync("./package.json", "utf-8");
|
|
1660
|
-
const packageJson = JSON.parse(packageJsonString);
|
|
1661
|
-
if (!packageJson.name) {
|
|
1662
|
-
throw new MicrofrontendError(
|
|
1663
|
-
`package.json file missing required field "name"`,
|
|
1664
|
-
{
|
|
1665
|
-
type: "packageJson",
|
|
1666
|
-
subtype: "missing_field_name",
|
|
1667
|
-
source: "@vercel/microfrontends/next"
|
|
1668
|
-
}
|
|
1669
|
-
);
|
|
1670
|
-
}
|
|
1671
|
-
return { name: packageJson.name };
|
|
1672
|
-
} catch (err) {
|
|
1673
|
-
throw MicrofrontendError.handle(err, {
|
|
1674
|
-
fileName: "package.json"
|
|
1675
|
-
});
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
1689
|
// src/sveltekit/config/index.ts
|
|
1680
1690
|
function withMicrofrontends(config, opts) {
|
|
1681
1691
|
const { name: fromApp } = getApplicationContext(opts);
|