@vercel/microfrontends 2.1.3 → 2.2.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 +20 -0
- package/README.md +4 -0
- package/dist/bin/cli.cjs +207 -90
- package/dist/config.d.ts +2 -2
- package/dist/experimental/sveltekit.cjs +180 -63
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.d.ts +6 -0
- package/dist/experimental/sveltekit.js +180 -63
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +177 -66
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +177 -66
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +173 -60
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.d.ts +2 -2
- package/dist/microfrontends/server.js +173 -60
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/microfrontends/utils.cjs +50 -7
- package/dist/microfrontends/utils.cjs.map +1 -1
- package/dist/microfrontends/utils.d.ts +1 -1
- package/dist/microfrontends/utils.js +50 -7
- package/dist/microfrontends/utils.js.map +1 -1
- package/dist/next/config.cjs +208 -113
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.d.ts +11 -1
- package/dist/next/config.js +208 -113
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +35 -17
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +35 -17
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.d.ts +2 -2
- package/dist/overrides.d.ts +3 -3
- package/dist/schema.d.ts +2 -2
- package/dist/{types-88602303.d.ts → types-b9ea41b2.d.ts} +1 -1
- package/dist/{types-e7523e61.d.ts → types-dcd8b17a.d.ts} +71 -24
- package/dist/utils/mfe-port.cjs +173 -60
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +173 -60
- package/dist/utils/mfe-port.js.map +1 -1
- package/dist/validation.cjs +47 -38
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/dist/validation.js +47 -38
- package/dist/validation.js.map +1 -1
- package/package.json +1 -1
- package/schema/schema.json +47 -38
|
@@ -1,9 +1,35 @@
|
|
|
1
|
+
// src/bin/local-proxy-is-running.ts
|
|
2
|
+
function localProxyIsRunning() {
|
|
3
|
+
return process.env.TURBO_TASK_HAS_MFE_PROXY === "true";
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// src/bin/logger.ts
|
|
7
|
+
function debug(...args) {
|
|
8
|
+
if (process.env.MFE_DEBUG) {
|
|
9
|
+
console.log(...args);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function info(...args) {
|
|
13
|
+
console.log(...args);
|
|
14
|
+
}
|
|
15
|
+
function warn(...args) {
|
|
16
|
+
console.warn(...args);
|
|
17
|
+
}
|
|
18
|
+
function error(...args) {
|
|
19
|
+
console.error(...args);
|
|
20
|
+
}
|
|
21
|
+
var logger = {
|
|
22
|
+
debug,
|
|
23
|
+
info,
|
|
24
|
+
warn,
|
|
25
|
+
error
|
|
26
|
+
};
|
|
27
|
+
|
|
1
28
|
// src/bin/check-proxy.ts
|
|
2
29
|
function displayLocalProxyInfo(port) {
|
|
3
|
-
|
|
4
|
-
if (TURBO_TASK_HAS_MFE_PROXY === "true" && MFE_PROXY_MESSAGE_PRINTED !== "true") {
|
|
30
|
+
if (localProxyIsRunning() && process.env.MFE_PROXY_MESSAGE_PRINTED !== "true") {
|
|
5
31
|
process.env.MFE_PROXY_MESSAGE_PRINTED = "true";
|
|
6
|
-
|
|
32
|
+
logger.info(`Microfrontends Proxy running on http://localhost:${port}`);
|
|
7
33
|
}
|
|
8
34
|
}
|
|
9
35
|
|
|
@@ -198,8 +224,8 @@ import fg from "fast-glob";
|
|
|
198
224
|
|
|
199
225
|
// src/config/microfrontends/utils/get-config-file-name.ts
|
|
200
226
|
var DEFAULT_CONFIGURATION_FILENAMES = [
|
|
201
|
-
"microfrontends.
|
|
202
|
-
"microfrontends.
|
|
227
|
+
"microfrontends.json",
|
|
228
|
+
"microfrontends.jsonc"
|
|
203
229
|
];
|
|
204
230
|
function getPossibleConfigurationFilenames({
|
|
205
231
|
customConfigFilename
|
|
@@ -207,7 +233,7 @@ function getPossibleConfigurationFilenames({
|
|
|
207
233
|
if (customConfigFilename) {
|
|
208
234
|
if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
|
|
209
235
|
throw new Error(
|
|
210
|
-
`
|
|
236
|
+
`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.`
|
|
211
237
|
);
|
|
212
238
|
}
|
|
213
239
|
return Array.from(
|
|
@@ -225,6 +251,10 @@ function findPackageWithMicrofrontendsConfig({
|
|
|
225
251
|
customConfigFilename
|
|
226
252
|
}) {
|
|
227
253
|
const applicationName = applicationContext.name;
|
|
254
|
+
logger.debug(
|
|
255
|
+
"[MFE Config] Searching repository for configs containing application:",
|
|
256
|
+
applicationName
|
|
257
|
+
);
|
|
228
258
|
try {
|
|
229
259
|
const microfrontendsJsonPaths = fg.globSync(
|
|
230
260
|
`**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
|
|
@@ -236,6 +266,11 @@ function findPackageWithMicrofrontendsConfig({
|
|
|
236
266
|
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
237
267
|
}
|
|
238
268
|
);
|
|
269
|
+
logger.debug(
|
|
270
|
+
"[MFE Config] Found",
|
|
271
|
+
microfrontendsJsonPaths.length,
|
|
272
|
+
"config file(s) in repository"
|
|
273
|
+
);
|
|
239
274
|
const matchingPaths = [];
|
|
240
275
|
for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
|
|
241
276
|
try {
|
|
@@ -245,19 +280,31 @@ function findPackageWithMicrofrontendsConfig({
|
|
|
245
280
|
);
|
|
246
281
|
const microfrontendsJson = parse(microfrontendsJsonContent);
|
|
247
282
|
if (microfrontendsJson.applications[applicationName]) {
|
|
283
|
+
logger.debug(
|
|
284
|
+
"[MFE Config] Found application in config:",
|
|
285
|
+
microfrontendsJsonPath
|
|
286
|
+
);
|
|
248
287
|
matchingPaths.push(microfrontendsJsonPath);
|
|
249
288
|
} else {
|
|
250
289
|
for (const [_, app] of Object.entries(
|
|
251
290
|
microfrontendsJson.applications
|
|
252
291
|
)) {
|
|
253
292
|
if (app.packageName === applicationName) {
|
|
293
|
+
logger.debug(
|
|
294
|
+
"[MFE Config] Found application via packageName in config:",
|
|
295
|
+
microfrontendsJsonPath
|
|
296
|
+
);
|
|
254
297
|
matchingPaths.push(microfrontendsJsonPath);
|
|
255
298
|
}
|
|
256
299
|
}
|
|
257
300
|
}
|
|
258
|
-
} catch (
|
|
301
|
+
} catch (error2) {
|
|
259
302
|
}
|
|
260
303
|
}
|
|
304
|
+
logger.debug(
|
|
305
|
+
"[MFE Config] Total matching config files:",
|
|
306
|
+
matchingPaths.length
|
|
307
|
+
);
|
|
261
308
|
if (matchingPaths.length > 1) {
|
|
262
309
|
throw new MicrofrontendError(
|
|
263
310
|
`Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
|
|
@@ -291,9 +338,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
|
|
|
291
338
|
}
|
|
292
339
|
const [packageJsonPath] = matchingPaths;
|
|
293
340
|
return dirname(packageJsonPath);
|
|
294
|
-
} catch (
|
|
295
|
-
if (
|
|
296
|
-
throw
|
|
341
|
+
} catch (error2) {
|
|
342
|
+
if (error2 instanceof MicrofrontendError) {
|
|
343
|
+
throw error2;
|
|
297
344
|
}
|
|
298
345
|
return null;
|
|
299
346
|
}
|
|
@@ -338,8 +385,8 @@ function isMonorepo({
|
|
|
338
385
|
fs2.readFileSync(packageJsonPath, "utf-8")
|
|
339
386
|
);
|
|
340
387
|
return packageJson.workspaces !== void 0;
|
|
341
|
-
} catch (
|
|
342
|
-
|
|
388
|
+
} catch (error2) {
|
|
389
|
+
logger.error("Error determining if repository is a monorepo", error2);
|
|
343
390
|
return false;
|
|
344
391
|
}
|
|
345
392
|
}
|
|
@@ -1056,15 +1103,18 @@ import fs5 from "node:fs";
|
|
|
1056
1103
|
import path4 from "node:path";
|
|
1057
1104
|
function getApplicationContext(opts) {
|
|
1058
1105
|
if (opts?.appName) {
|
|
1106
|
+
logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
|
|
1059
1107
|
return { name: opts.appName };
|
|
1060
1108
|
}
|
|
1061
1109
|
if (process.env.VERCEL_PROJECT_NAME) {
|
|
1110
|
+
logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
|
|
1062
1111
|
return {
|
|
1063
1112
|
name: process.env.VERCEL_PROJECT_NAME,
|
|
1064
1113
|
projectName: process.env.VERCEL_PROJECT_NAME
|
|
1065
1114
|
};
|
|
1066
1115
|
}
|
|
1067
1116
|
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
1117
|
+
logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
|
|
1068
1118
|
return {
|
|
1069
1119
|
name: process.env.NX_TASK_TARGET_PROJECT,
|
|
1070
1120
|
packageJsonName: process.env.NX_TASK_TARGET_PROJECT
|
|
@@ -1077,6 +1127,7 @@ function getApplicationContext(opts) {
|
|
|
1077
1127
|
);
|
|
1078
1128
|
const projectJson = JSON.parse(vercelProjectJsonPath);
|
|
1079
1129
|
if (projectJson.projectName) {
|
|
1130
|
+
logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
|
|
1080
1131
|
return {
|
|
1081
1132
|
name: projectJson.projectName,
|
|
1082
1133
|
projectName: projectJson.projectName
|
|
@@ -1100,6 +1151,7 @@ function getApplicationContext(opts) {
|
|
|
1100
1151
|
}
|
|
1101
1152
|
);
|
|
1102
1153
|
}
|
|
1154
|
+
logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
|
|
1103
1155
|
return { name: packageJson.name, packageJsonName: packageJson.name };
|
|
1104
1156
|
} catch (err) {
|
|
1105
1157
|
throw MicrofrontendError.handle(err, {
|
|
@@ -1133,38 +1185,28 @@ var schema_default = {
|
|
|
1133
1185
|
type: "object",
|
|
1134
1186
|
properties: {
|
|
1135
1187
|
$schema: {
|
|
1136
|
-
type: "string"
|
|
1188
|
+
type: "string",
|
|
1189
|
+
description: "See https://openapi.vercel.sh/microfrontends.json."
|
|
1137
1190
|
},
|
|
1138
1191
|
version: {
|
|
1139
1192
|
type: "string",
|
|
1140
|
-
const: "1"
|
|
1141
|
-
|
|
1142
|
-
options: {
|
|
1143
|
-
$ref: "#/definitions/Options"
|
|
1193
|
+
const: "1",
|
|
1194
|
+
description: "The version of the microfrontends config schema."
|
|
1144
1195
|
},
|
|
1145
1196
|
applications: {
|
|
1146
1197
|
$ref: "#/definitions/ApplicationRouting",
|
|
1147
|
-
description: "Mapping of
|
|
1198
|
+
description: "Mapping of Vercel project names to their microfrontend configurations."
|
|
1199
|
+
},
|
|
1200
|
+
options: {
|
|
1201
|
+
$ref: "#/definitions/Options",
|
|
1202
|
+
description: "Optional configuration options for the microfrontend."
|
|
1148
1203
|
}
|
|
1149
1204
|
},
|
|
1150
1205
|
required: [
|
|
1151
1206
|
"applications"
|
|
1152
1207
|
],
|
|
1153
|
-
additionalProperties: false
|
|
1154
|
-
|
|
1155
|
-
Options: {
|
|
1156
|
-
type: "object",
|
|
1157
|
-
properties: {
|
|
1158
|
-
disableOverrides: {
|
|
1159
|
-
type: "boolean",
|
|
1160
|
-
description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect."
|
|
1161
|
-
},
|
|
1162
|
-
localProxyPort: {
|
|
1163
|
-
type: "number",
|
|
1164
|
-
description: "The port number used by the local proxy server.\n\nThe default is `3024`."
|
|
1165
|
-
}
|
|
1166
|
-
},
|
|
1167
|
-
additionalProperties: false
|
|
1208
|
+
additionalProperties: false,
|
|
1209
|
+
description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
|
|
1168
1210
|
},
|
|
1169
1211
|
ApplicationRouting: {
|
|
1170
1212
|
type: "object",
|
|
@@ -1172,8 +1214,9 @@ var schema_default = {
|
|
|
1172
1214
|
$ref: "#/definitions/Application"
|
|
1173
1215
|
},
|
|
1174
1216
|
propertyNames: {
|
|
1175
|
-
description: "The
|
|
1176
|
-
}
|
|
1217
|
+
description: "The Vercel project name of the microfrontend application.\n\nNote: If this name does not also match the name `name` from the `package.json`, set `packageName` with the name used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
|
|
1218
|
+
},
|
|
1219
|
+
description: "Mapping of Vercel project names to their microfrontend configurations."
|
|
1177
1220
|
},
|
|
1178
1221
|
Application: {
|
|
1179
1222
|
anyOf: [
|
|
@@ -1183,14 +1226,15 @@ var schema_default = {
|
|
|
1183
1226
|
{
|
|
1184
1227
|
$ref: "#/definitions/ChildApplication"
|
|
1185
1228
|
}
|
|
1186
|
-
]
|
|
1229
|
+
],
|
|
1230
|
+
description: "The configuration for a microfrontend application. There must always be one default application."
|
|
1187
1231
|
},
|
|
1188
1232
|
DefaultApplication: {
|
|
1189
1233
|
type: "object",
|
|
1190
1234
|
properties: {
|
|
1191
1235
|
packageName: {
|
|
1192
1236
|
type: "string",
|
|
1193
|
-
description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json
|
|
1237
|
+
description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
|
|
1194
1238
|
},
|
|
1195
1239
|
development: {
|
|
1196
1240
|
$ref: "#/definitions/DefaultDevelopment",
|
|
@@ -1210,15 +1254,15 @@ var schema_default = {
|
|
|
1210
1254
|
"number",
|
|
1211
1255
|
"string"
|
|
1212
1256
|
],
|
|
1213
|
-
description: "A local port number or host
|
|
1257
|
+
description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
|
|
1214
1258
|
},
|
|
1215
1259
|
task: {
|
|
1216
1260
|
type: "string",
|
|
1217
|
-
description:
|
|
1261
|
+
description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
|
|
1218
1262
|
},
|
|
1219
1263
|
fallback: {
|
|
1220
1264
|
type: "string",
|
|
1221
|
-
description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS."
|
|
1265
|
+
description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
|
|
1222
1266
|
}
|
|
1223
1267
|
},
|
|
1224
1268
|
required: [
|
|
@@ -1231,7 +1275,7 @@ var schema_default = {
|
|
|
1231
1275
|
properties: {
|
|
1232
1276
|
packageName: {
|
|
1233
1277
|
type: "string",
|
|
1234
|
-
description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json
|
|
1278
|
+
description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
|
|
1235
1279
|
},
|
|
1236
1280
|
development: {
|
|
1237
1281
|
$ref: "#/definitions/ChildDevelopment",
|
|
@@ -1239,11 +1283,11 @@ var schema_default = {
|
|
|
1239
1283
|
},
|
|
1240
1284
|
routing: {
|
|
1241
1285
|
$ref: "#/definitions/Routing",
|
|
1242
|
-
description: "Groups of path expressions that are routed to this application."
|
|
1286
|
+
description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
|
|
1243
1287
|
},
|
|
1244
1288
|
assetPrefix: {
|
|
1245
1289
|
type: "string",
|
|
1246
|
-
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."
|
|
1290
|
+
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.\n\nThe default value is the auto-generated asset prefix of the form `vc-ap-<hash>`.\n\nSee https://vercel.com/docs/microfrontends/path-routing#asset-prefix."
|
|
1247
1291
|
}
|
|
1248
1292
|
},
|
|
1249
1293
|
required: [
|
|
@@ -1259,15 +1303,15 @@ var schema_default = {
|
|
|
1259
1303
|
"number",
|
|
1260
1304
|
"string"
|
|
1261
1305
|
],
|
|
1262
|
-
description: "A local port number or host
|
|
1306
|
+
description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
|
|
1263
1307
|
},
|
|
1264
1308
|
task: {
|
|
1265
1309
|
type: "string",
|
|
1266
|
-
description:
|
|
1310
|
+
description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
|
|
1267
1311
|
},
|
|
1268
1312
|
fallback: {
|
|
1269
1313
|
type: "string",
|
|
1270
|
-
description: "Fallback for local development, could point to any environment.
|
|
1314
|
+
description: "Fallback for local development, could point to any environment. If not provided for child apps, the fallback of the default app will be used.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
|
|
1271
1315
|
}
|
|
1272
1316
|
},
|
|
1273
1317
|
additionalProperties: false
|
|
@@ -1276,29 +1320,46 @@ var schema_default = {
|
|
|
1276
1320
|
type: "array",
|
|
1277
1321
|
items: {
|
|
1278
1322
|
$ref: "#/definitions/PathGroup"
|
|
1279
|
-
}
|
|
1323
|
+
},
|
|
1324
|
+
description: "A list of path groups that are routed to this application."
|
|
1280
1325
|
},
|
|
1281
1326
|
PathGroup: {
|
|
1282
1327
|
type: "object",
|
|
1283
1328
|
properties: {
|
|
1284
1329
|
group: {
|
|
1285
1330
|
type: "string",
|
|
1286
|
-
description: "
|
|
1331
|
+
description: "Group name for the paths."
|
|
1287
1332
|
},
|
|
1288
1333
|
flag: {
|
|
1289
1334
|
type: "string",
|
|
1290
|
-
description: "
|
|
1335
|
+
description: "The name of the feature flag that controls routing for this group of paths. See https://vercel.com/docs/microfrontends/path-routing#routing-changes-safely-with-flags."
|
|
1291
1336
|
},
|
|
1292
1337
|
paths: {
|
|
1293
1338
|
type: "array",
|
|
1294
1339
|
items: {
|
|
1295
1340
|
type: "string"
|
|
1296
|
-
}
|
|
1341
|
+
},
|
|
1342
|
+
description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
|
|
1297
1343
|
}
|
|
1298
1344
|
},
|
|
1299
1345
|
required: [
|
|
1300
1346
|
"paths"
|
|
1301
1347
|
],
|
|
1348
|
+
additionalProperties: false,
|
|
1349
|
+
description: "A group of paths that is routed to this application."
|
|
1350
|
+
},
|
|
1351
|
+
Options: {
|
|
1352
|
+
type: "object",
|
|
1353
|
+
properties: {
|
|
1354
|
+
disableOverrides: {
|
|
1355
|
+
type: "boolean",
|
|
1356
|
+
description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect.\n\nSee https://vercel.com/docs/microfrontends/managing-microfrontends/vercel-toolbar#routing-overrides."
|
|
1357
|
+
},
|
|
1358
|
+
localProxyPort: {
|
|
1359
|
+
type: "number",
|
|
1360
|
+
description: "The port number used by the local proxy server.\n\nThe default value is 3024.\n\nSee https://vercel.com/docs/microfrontends/local-development."
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1302
1363
|
additionalProperties: false
|
|
1303
1364
|
}
|
|
1304
1365
|
}
|
|
@@ -1317,19 +1378,19 @@ function formatAjvErrors(errors) {
|
|
|
1317
1378
|
return [];
|
|
1318
1379
|
}
|
|
1319
1380
|
const errorMessages = [];
|
|
1320
|
-
for (const
|
|
1321
|
-
if (
|
|
1381
|
+
for (const error2 of errors) {
|
|
1382
|
+
if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
|
|
1322
1383
|
continue;
|
|
1323
1384
|
}
|
|
1324
|
-
const instancePath =
|
|
1385
|
+
const instancePath = error2.instancePath.slice(1);
|
|
1325
1386
|
const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
|
|
1326
|
-
if (
|
|
1387
|
+
if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
|
|
1327
1388
|
errorMessages.push(
|
|
1328
1389
|
`Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
|
|
1329
1390
|
);
|
|
1330
|
-
} else if (
|
|
1391
|
+
} else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
|
|
1331
1392
|
const anyOfErrors = errors.filter(
|
|
1332
|
-
(e) => e.instancePath ===
|
|
1393
|
+
(e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
|
|
1333
1394
|
);
|
|
1334
1395
|
if (anyOfErrors.every((e) => e.keyword === "type")) {
|
|
1335
1396
|
const allowedTypes = LIST_FORMATTER2.format(
|
|
@@ -1345,13 +1406,13 @@ function formatAjvErrors(errors) {
|
|
|
1345
1406
|
`Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
|
|
1346
1407
|
);
|
|
1347
1408
|
}
|
|
1348
|
-
} else if (
|
|
1409
|
+
} else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
|
|
1349
1410
|
errorMessages.push(
|
|
1350
|
-
`Property '${
|
|
1411
|
+
`Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
|
|
1351
1412
|
);
|
|
1352
|
-
} else if (
|
|
1413
|
+
} else if (error2.keyword === "required") {
|
|
1353
1414
|
errorMessages.push(
|
|
1354
|
-
`Property '${
|
|
1415
|
+
`Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
|
|
1355
1416
|
);
|
|
1356
1417
|
}
|
|
1357
1418
|
}
|
|
@@ -1364,8 +1425,8 @@ function validateSchema(configString) {
|
|
|
1364
1425
|
const isValid = validate(parsedConfig);
|
|
1365
1426
|
if (!isValid) {
|
|
1366
1427
|
throw new MicrofrontendError(
|
|
1367
|
-
`Invalid microfrontends config:${formatAjvErrors(validate.errors).map((
|
|
1368
|
-
- ${
|
|
1428
|
+
`Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
|
|
1429
|
+
- ${error2}`).join(
|
|
1369
1430
|
""
|
|
1370
1431
|
)}
|
|
1371
1432
|
|
|
@@ -1462,7 +1523,13 @@ var MicrofrontendsServer = class {
|
|
|
1462
1523
|
filePath,
|
|
1463
1524
|
cookies
|
|
1464
1525
|
} = {}) {
|
|
1526
|
+
logger.debug("[MFE Config] Starting config inference", {
|
|
1527
|
+
appName,
|
|
1528
|
+
directory: directory || process.cwd(),
|
|
1529
|
+
filePath
|
|
1530
|
+
});
|
|
1465
1531
|
if (filePath) {
|
|
1532
|
+
logger.debug("[MFE Config] Using explicit filePath:", filePath);
|
|
1466
1533
|
return MicrofrontendsServer.fromFile({
|
|
1467
1534
|
filePath,
|
|
1468
1535
|
cookies
|
|
@@ -1470,16 +1537,25 @@ var MicrofrontendsServer = class {
|
|
|
1470
1537
|
}
|
|
1471
1538
|
try {
|
|
1472
1539
|
const packageRoot = findPackageRoot(directory);
|
|
1540
|
+
logger.debug("[MFE Config] Package root:", packageRoot);
|
|
1473
1541
|
const applicationContext = getApplicationContext({
|
|
1474
1542
|
appName,
|
|
1475
1543
|
packageRoot
|
|
1476
1544
|
});
|
|
1545
|
+
logger.debug("[MFE Config] Application context:", applicationContext);
|
|
1477
1546
|
const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
|
|
1547
|
+
if (customConfigFilename) {
|
|
1548
|
+
logger.debug(
|
|
1549
|
+
"[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
|
|
1550
|
+
customConfigFilename
|
|
1551
|
+
);
|
|
1552
|
+
}
|
|
1478
1553
|
const maybeConfig = findConfig({
|
|
1479
1554
|
dir: packageRoot,
|
|
1480
1555
|
customConfigFilename
|
|
1481
1556
|
});
|
|
1482
1557
|
if (maybeConfig) {
|
|
1558
|
+
logger.debug("[MFE Config] Config found at package root:", maybeConfig);
|
|
1483
1559
|
return MicrofrontendsServer.fromFile({
|
|
1484
1560
|
filePath: maybeConfig,
|
|
1485
1561
|
cookies
|
|
@@ -1487,42 +1563,78 @@ var MicrofrontendsServer = class {
|
|
|
1487
1563
|
}
|
|
1488
1564
|
const repositoryRoot = findRepositoryRoot();
|
|
1489
1565
|
const isMonorepo2 = isMonorepo({ repositoryRoot });
|
|
1566
|
+
logger.debug(
|
|
1567
|
+
"[MFE Config] Repository root:",
|
|
1568
|
+
repositoryRoot,
|
|
1569
|
+
"Is monorepo:",
|
|
1570
|
+
isMonorepo2
|
|
1571
|
+
);
|
|
1490
1572
|
const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
|
|
1491
1573
|
if (typeof configFromEnv === "string") {
|
|
1574
|
+
logger.debug(
|
|
1575
|
+
"[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
|
|
1576
|
+
configFromEnv
|
|
1577
|
+
);
|
|
1492
1578
|
const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
|
|
1493
1579
|
if (maybeConfigFromEnv) {
|
|
1580
|
+
logger.debug(
|
|
1581
|
+
"[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
|
|
1582
|
+
maybeConfigFromEnv
|
|
1583
|
+
);
|
|
1494
1584
|
return MicrofrontendsServer.fromFile({
|
|
1495
1585
|
filePath: maybeConfigFromEnv,
|
|
1496
1586
|
cookies
|
|
1497
1587
|
});
|
|
1498
1588
|
}
|
|
1499
1589
|
} else {
|
|
1590
|
+
const vercelDir = join2(packageRoot, ".vercel");
|
|
1591
|
+
logger.debug(
|
|
1592
|
+
"[MFE Config] Searching for config in .vercel directory:",
|
|
1593
|
+
vercelDir
|
|
1594
|
+
);
|
|
1500
1595
|
const maybeConfigFromVercel = findConfig({
|
|
1501
|
-
dir:
|
|
1596
|
+
dir: vercelDir,
|
|
1502
1597
|
customConfigFilename
|
|
1503
1598
|
});
|
|
1504
1599
|
if (maybeConfigFromVercel) {
|
|
1600
|
+
logger.debug(
|
|
1601
|
+
"[MFE Config] Config found in .vercel directory:",
|
|
1602
|
+
maybeConfigFromVercel
|
|
1603
|
+
);
|
|
1505
1604
|
return MicrofrontendsServer.fromFile({
|
|
1506
1605
|
filePath: maybeConfigFromVercel,
|
|
1507
1606
|
cookies
|
|
1508
1607
|
});
|
|
1509
1608
|
}
|
|
1510
1609
|
if (isMonorepo2) {
|
|
1610
|
+
logger.debug(
|
|
1611
|
+
"[MFE Config] Inferring microfrontends location in monorepo for application:",
|
|
1612
|
+
applicationContext.name
|
|
1613
|
+
);
|
|
1511
1614
|
const defaultPackage = inferMicrofrontendsLocation({
|
|
1512
1615
|
repositoryRoot,
|
|
1513
1616
|
applicationContext,
|
|
1514
1617
|
customConfigFilename
|
|
1515
1618
|
});
|
|
1619
|
+
logger.debug(
|
|
1620
|
+
"[MFE Config] Inferred package location:",
|
|
1621
|
+
defaultPackage
|
|
1622
|
+
);
|
|
1516
1623
|
const maybeConfigFromDefault = findConfig({
|
|
1517
1624
|
dir: defaultPackage,
|
|
1518
1625
|
customConfigFilename
|
|
1519
1626
|
});
|
|
1520
1627
|
if (maybeConfigFromDefault) {
|
|
1628
|
+
logger.debug(
|
|
1629
|
+
"[MFE Config] Config found in inferred package:",
|
|
1630
|
+
maybeConfigFromDefault
|
|
1631
|
+
);
|
|
1521
1632
|
return MicrofrontendsServer.fromFile({
|
|
1522
1633
|
filePath: maybeConfigFromDefault,
|
|
1523
1634
|
cookies
|
|
1524
1635
|
});
|
|
1525
1636
|
}
|
|
1637
|
+
logger.debug("[MFE Config] No config found in inferred package");
|
|
1526
1638
|
}
|
|
1527
1639
|
}
|
|
1528
1640
|
throw new MicrofrontendError(
|
|
@@ -1548,8 +1660,13 @@ var MicrofrontendsServer = class {
|
|
|
1548
1660
|
cookies
|
|
1549
1661
|
}) {
|
|
1550
1662
|
try {
|
|
1663
|
+
logger.debug("[MFE Config] Reading config from file:", filePath);
|
|
1551
1664
|
const configJson = fs6.readFileSync(filePath, "utf-8");
|
|
1552
1665
|
const config = MicrofrontendsServer.validate(configJson);
|
|
1666
|
+
logger.debug(
|
|
1667
|
+
"[MFE Config] Config loaded with applications:",
|
|
1668
|
+
Object.keys(config.applications)
|
|
1669
|
+
);
|
|
1553
1670
|
return new MicrofrontendsServer({
|
|
1554
1671
|
config,
|
|
1555
1672
|
overrides: cookies ? parseOverrides(cookies) : void 0
|