@vercel/microfrontends 1.0.1-canary.3 → 1.0.1-canary.4
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 +113 -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 +79 -72
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +79 -72
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +82 -75
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +82 -75
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +79 -45
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.js +79 -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 +79 -72
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +79 -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 +83 -49
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +83 -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
|
}
|
|
@@ -1038,6 +1041,9 @@ function isMonorepo({
|
|
|
1038
1041
|
if (fs2.existsSync(path2.join(repositoryRoot, "vlt-workspaces.json"))) {
|
|
1039
1042
|
return true;
|
|
1040
1043
|
}
|
|
1044
|
+
if (process.env.NX_WORKSPACE_ROOT === path2.resolve(repositoryRoot)) {
|
|
1045
|
+
return true;
|
|
1046
|
+
}
|
|
1041
1047
|
const packageJsonPath = path2.join(repositoryRoot, "package.json");
|
|
1042
1048
|
if (!fs2.existsSync(packageJsonPath)) {
|
|
1043
1049
|
return false;
|
|
@@ -1083,8 +1089,42 @@ function findConfig({ dir }) {
|
|
|
1083
1089
|
return null;
|
|
1084
1090
|
}
|
|
1085
1091
|
|
|
1086
|
-
// src/config/microfrontends/
|
|
1092
|
+
// src/config/microfrontends/utils/get-application-context.ts
|
|
1093
|
+
import fs5 from "node:fs";
|
|
1087
1094
|
import path4 from "node:path";
|
|
1095
|
+
function getApplicationContext(opts) {
|
|
1096
|
+
if (opts?.appName) {
|
|
1097
|
+
return { name: opts.appName };
|
|
1098
|
+
}
|
|
1099
|
+
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
1100
|
+
return { name: process.env.NX_TASK_TARGET_PROJECT };
|
|
1101
|
+
}
|
|
1102
|
+
try {
|
|
1103
|
+
const packageJsonString = fs5.readFileSync(
|
|
1104
|
+
path4.join(opts?.packageRoot || ".", "package.json"),
|
|
1105
|
+
"utf-8"
|
|
1106
|
+
);
|
|
1107
|
+
const packageJson = JSON.parse(packageJsonString);
|
|
1108
|
+
if (!packageJson.name) {
|
|
1109
|
+
throw new MicrofrontendError(
|
|
1110
|
+
`package.json file missing required field "name"`,
|
|
1111
|
+
{
|
|
1112
|
+
type: "packageJson",
|
|
1113
|
+
subtype: "missing_field_name",
|
|
1114
|
+
source: "@vercel/microfrontends/next"
|
|
1115
|
+
}
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
return { name: packageJson.name };
|
|
1119
|
+
} catch (err) {
|
|
1120
|
+
throw MicrofrontendError.handle(err, {
|
|
1121
|
+
fileName: "package.json"
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/config/microfrontends/server/utils/get-output-file-path.ts
|
|
1127
|
+
import path5 from "node:path";
|
|
1088
1128
|
|
|
1089
1129
|
// src/config/microfrontends/server/constants.ts
|
|
1090
1130
|
var MFE_CONFIG_DEFAULT_FILE_PATH = "microfrontends";
|
|
@@ -1092,7 +1132,7 @@ var MFE_CONFIG_DEFAULT_FILE_NAME = "microfrontends.json";
|
|
|
1092
1132
|
|
|
1093
1133
|
// src/config/microfrontends/server/utils/get-output-file-path.ts
|
|
1094
1134
|
function getOutputFilePath() {
|
|
1095
|
-
return
|
|
1135
|
+
return path5.join(MFE_CONFIG_DEFAULT_FILE_PATH, MFE_CONFIG_DEFAULT_FILE_NAME);
|
|
1096
1136
|
}
|
|
1097
1137
|
|
|
1098
1138
|
// src/config/microfrontends/server/validation.ts
|
|
@@ -1431,8 +1471,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1431
1471
|
pretty: true
|
|
1432
1472
|
}) {
|
|
1433
1473
|
const outputPath = getOutputFilePath();
|
|
1434
|
-
|
|
1435
|
-
|
|
1474
|
+
fs6.mkdirSync(dirname3(outputPath), { recursive: true });
|
|
1475
|
+
fs6.writeFileSync(
|
|
1436
1476
|
outputPath,
|
|
1437
1477
|
JSON.stringify(
|
|
1438
1478
|
this.config.toSchemaJson(),
|
|
@@ -1518,14 +1558,8 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1518
1558
|
}
|
|
1519
1559
|
try {
|
|
1520
1560
|
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 };
|
|
1561
|
+
const { name: appName } = getApplicationContext({ packageRoot });
|
|
1562
|
+
const configMeta = meta ?? { fromApp: appName };
|
|
1529
1563
|
const maybeConfig = findConfig({ dir: packageRoot });
|
|
1530
1564
|
if (maybeConfig) {
|
|
1531
1565
|
return MicrofrontendsServer.fromFile({
|
|
@@ -1540,7 +1574,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1540
1574
|
if (isMonorepo2) {
|
|
1541
1575
|
const defaultPackage = findDefaultMicrofrontendsPackage({
|
|
1542
1576
|
repositoryRoot,
|
|
1543
|
-
applicationName:
|
|
1577
|
+
applicationName: appName
|
|
1544
1578
|
});
|
|
1545
1579
|
const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
|
|
1546
1580
|
if (maybeConfigFromDefault) {
|
|
@@ -1570,7 +1604,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1570
1604
|
options
|
|
1571
1605
|
}) {
|
|
1572
1606
|
try {
|
|
1573
|
-
const configJson =
|
|
1607
|
+
const configJson = fs6.readFileSync(filePath, "utf-8");
|
|
1574
1608
|
const config = MicrofrontendsServer.validate(configJson);
|
|
1575
1609
|
if (!isMainConfig(config) && options?.resolveMainConfig) {
|
|
1576
1610
|
const repositoryRoot = findRepositoryRoot();
|
|
@@ -1618,7 +1652,7 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1618
1652
|
overrides
|
|
1619
1653
|
}) {
|
|
1620
1654
|
try {
|
|
1621
|
-
const config =
|
|
1655
|
+
const config = fs6.readFileSync(filePath, "utf-8");
|
|
1622
1656
|
const validatedConfig = MicrofrontendsServer.validate(config);
|
|
1623
1657
|
if (!isMainConfig(validatedConfig)) {
|
|
1624
1658
|
throw new MicrofrontendError(
|
|
@@ -1649,33 +1683,6 @@ var MicrofrontendsServer = class extends Microfrontends {
|
|
|
1649
1683
|
}
|
|
1650
1684
|
};
|
|
1651
1685
|
|
|
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
1686
|
// src/sveltekit/config/index.ts
|
|
1680
1687
|
function withMicrofrontends(config, opts) {
|
|
1681
1688
|
const { name: fromApp } = getApplicationContext(opts);
|