@vercel/microfrontends 2.2.0 → 2.2.2
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 +25 -0
- package/cli/index.cjs +0 -1
- package/dist/bin/cli.cjs +551 -381
- package/dist/config.cjs +191 -169
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +3 -2
- package/dist/config.js +192 -170
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +643 -489
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +645 -491
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +671 -519
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +669 -517
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +661 -509
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.d.ts +2 -2
- package/dist/microfrontends/server.js +663 -511
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/microfrontends/utils.cjs +117 -23
- package/dist/microfrontends/utils.cjs.map +1 -1
- package/dist/microfrontends/utils.d.ts +4 -4
- package/dist/microfrontends/utils.js +118 -24
- 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.d.ts +8 -8
- package/dist/next/client.js +1 -1
- package/dist/next/client.js.map +1 -1
- package/dist/next/config.cjs +784 -626
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +782 -624
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +244 -222
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +245 -223
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +192 -170
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +1 -1
- package/dist/next/testing.js +193 -171
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.cjs +5 -5
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.d.ts +9 -9
- package/dist/overrides.js +5 -5
- package/dist/overrides.js.map +1 -1
- package/dist/utils/mfe-port.cjs +689 -522
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.d.ts +9 -1
- package/dist/utils/mfe-port.js +687 -521
- package/dist/utils/mfe-port.js.map +1 -1
- package/dist/validation.cjs +8 -24
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.js +8 -24
- package/dist/validation.js.map +1 -1
- package/package.json +4 -6
package/dist/bin/cli.cjs
CHANGED
|
@@ -24,13 +24,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/bin/index.ts
|
|
27
|
-
var import_commander = require("commander");
|
|
28
27
|
var import_env = require("@next/env");
|
|
28
|
+
var import_commander = require("commander");
|
|
29
29
|
|
|
30
30
|
// package.json
|
|
31
31
|
var package_default = {
|
|
32
32
|
name: "@vercel/microfrontends",
|
|
33
|
-
version: "2.2.
|
|
33
|
+
version: "2.2.2",
|
|
34
34
|
private: false,
|
|
35
35
|
description: "Defines configuration and utilities for microfrontends development",
|
|
36
36
|
keywords: [
|
|
@@ -161,15 +161,14 @@ var package_default = {
|
|
|
161
161
|
postbuild: "pnpm generate:exports",
|
|
162
162
|
"generate:exports": "tsx scripts/generate-exports/index.ts",
|
|
163
163
|
"generate:schema": "tsx scripts/generate-json-schema.ts",
|
|
164
|
-
lint: "
|
|
165
|
-
"lint-fix": "eslint . --fix",
|
|
164
|
+
lint: "biome check",
|
|
166
165
|
prepublishOnly: "pnpm build && pnpm generate:exports && pnpm generate:schema",
|
|
167
166
|
proxy: "tsx src/proxy/index.ts",
|
|
168
167
|
test: "cross-env TZ=UTC jest",
|
|
169
168
|
typecheck: "tsc --noEmit"
|
|
170
169
|
},
|
|
171
170
|
dependencies: {
|
|
172
|
-
"@next/env": "
|
|
171
|
+
"@next/env": "16.0.10",
|
|
173
172
|
"@types/md5": "^2.3.5",
|
|
174
173
|
ajv: "^8.17.1",
|
|
175
174
|
commander: "^12.1.0",
|
|
@@ -195,10 +194,9 @@ var package_default = {
|
|
|
195
194
|
"@types/react": "18.3.1",
|
|
196
195
|
"@types/react-dom": "18.3.0",
|
|
197
196
|
"@types/semver": "^7.7.0",
|
|
198
|
-
"eslint-config-custom": "workspace:*",
|
|
199
197
|
jest: "^29.7.0",
|
|
200
198
|
"jest-environment-jsdom": "29.2.2",
|
|
201
|
-
next: "
|
|
199
|
+
next: "16.0.10",
|
|
202
200
|
react: "19.0.0",
|
|
203
201
|
"react-dom": "19.0.0",
|
|
204
202
|
"ts-config": "workspace:*",
|
|
@@ -249,11 +247,34 @@ var http = __toESM(require("http"), 1);
|
|
|
249
247
|
var https = __toESM(require("https"), 1);
|
|
250
248
|
var import_node_url = require("url");
|
|
251
249
|
var import_cookie = require("cookie");
|
|
252
|
-
var import_path_to_regexp3 = require("path-to-regexp");
|
|
253
250
|
var import_http_proxy = __toESM(require("http-proxy"), 1);
|
|
251
|
+
var import_path_to_regexp3 = require("path-to-regexp");
|
|
254
252
|
|
|
255
|
-
// src/config/microfrontends
|
|
256
|
-
var
|
|
253
|
+
// src/config/microfrontends/server/index.ts
|
|
254
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
255
|
+
var import_node_path8 = require("path");
|
|
256
|
+
|
|
257
|
+
// src/bin/logger.ts
|
|
258
|
+
function debug(...args) {
|
|
259
|
+
if (process.env.MFE_DEBUG) {
|
|
260
|
+
console.log(...args);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function info(...args) {
|
|
264
|
+
console.log(...args);
|
|
265
|
+
}
|
|
266
|
+
function warn(...args) {
|
|
267
|
+
console.warn(...args);
|
|
268
|
+
}
|
|
269
|
+
function error(...args) {
|
|
270
|
+
console.error(...args);
|
|
271
|
+
}
|
|
272
|
+
var logger = {
|
|
273
|
+
debug,
|
|
274
|
+
info,
|
|
275
|
+
warn,
|
|
276
|
+
error
|
|
277
|
+
};
|
|
257
278
|
|
|
258
279
|
// src/config/errors.ts
|
|
259
280
|
var MicrofrontendError = class extends Error {
|
|
@@ -347,27 +368,18 @@ var MicrofrontendError = class extends Error {
|
|
|
347
368
|
}
|
|
348
369
|
};
|
|
349
370
|
|
|
350
|
-
// src/config/microfrontends-config/
|
|
351
|
-
|
|
352
|
-
const config = process.env.MFE_CONFIG;
|
|
353
|
-
if (!config) {
|
|
354
|
-
throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
|
|
355
|
-
type: "config",
|
|
356
|
-
subtype: "not_found_in_env"
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
return config;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// src/config/schema/utils/is-default-app.ts
|
|
363
|
-
function isDefaultApp(a) {
|
|
364
|
-
return !("routing" in a);
|
|
365
|
-
}
|
|
371
|
+
// src/config/microfrontends-config/isomorphic/index.ts
|
|
372
|
+
var import_jsonc_parser = require("jsonc-parser");
|
|
366
373
|
|
|
367
374
|
// src/config/overrides/constants.ts
|
|
368
375
|
var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
|
|
369
376
|
var OVERRIDES_ENV_COOKIE_PREFIX = `${OVERRIDES_COOKIE_PREFIX}:env:`;
|
|
370
377
|
|
|
378
|
+
// src/config/overrides/get-app-env-override-cookie-name.ts
|
|
379
|
+
function getAppEnvOverrideCookieName(application) {
|
|
380
|
+
return `${OVERRIDES_ENV_COOKIE_PREFIX}${application}`;
|
|
381
|
+
}
|
|
382
|
+
|
|
371
383
|
// src/config/overrides/is-override-cookie.ts
|
|
372
384
|
function isOverrideCookie(cookie) {
|
|
373
385
|
return Boolean(cookie.name?.startsWith(OVERRIDES_COOKIE_PREFIX));
|
|
@@ -397,9 +409,9 @@ function parseOverrides(cookies) {
|
|
|
397
409
|
return overridesConfig;
|
|
398
410
|
}
|
|
399
411
|
|
|
400
|
-
// src/config/
|
|
401
|
-
function
|
|
402
|
-
return
|
|
412
|
+
// src/config/schema/utils/is-default-app.ts
|
|
413
|
+
function isDefaultApp(a) {
|
|
414
|
+
return !("routing" in a);
|
|
403
415
|
}
|
|
404
416
|
|
|
405
417
|
// src/config/microfrontends-config/client/index.ts
|
|
@@ -500,6 +512,183 @@ var MicrofrontendConfigClient = class {
|
|
|
500
512
|
}
|
|
501
513
|
};
|
|
502
514
|
|
|
515
|
+
// src/config/microfrontends-config/utils/get-config-from-env.ts
|
|
516
|
+
function getConfigStringFromEnv() {
|
|
517
|
+
const config = process.env.MFE_CONFIG;
|
|
518
|
+
if (!config) {
|
|
519
|
+
throw new MicrofrontendError(`Missing "MFE_CONFIG" in environment.`, {
|
|
520
|
+
type: "config",
|
|
521
|
+
subtype: "not_found_in_env"
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return config;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// src/config/microfrontends-config/isomorphic/constants.ts
|
|
528
|
+
var DEFAULT_LOCAL_PROXY_PORT = 3024;
|
|
529
|
+
var MFE_APP_PORT_ENV = "MFE_APP_PORT";
|
|
530
|
+
var MFE_LOCAL_PROXY_PORT_ENV = "MFE_LOCAL_PROXY_PORT";
|
|
531
|
+
|
|
532
|
+
// src/config/microfrontends-config/isomorphic/utils/generate-port.ts
|
|
533
|
+
function generatePortFromName({
|
|
534
|
+
name,
|
|
535
|
+
minPort = 3e3,
|
|
536
|
+
maxPort = 8e3
|
|
537
|
+
}) {
|
|
538
|
+
if (!name) {
|
|
539
|
+
throw new Error("Name is required to generate a port");
|
|
540
|
+
}
|
|
541
|
+
let hash = 0;
|
|
542
|
+
for (let i = 0; i < name.length; i++) {
|
|
543
|
+
hash = (hash << 5) - hash + name.charCodeAt(i);
|
|
544
|
+
hash |= 0;
|
|
545
|
+
}
|
|
546
|
+
hash = Math.abs(hash);
|
|
547
|
+
const range = maxPort - minPort;
|
|
548
|
+
const port = minPort + hash % range;
|
|
549
|
+
return port;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// src/config/microfrontends-config/isomorphic/host.ts
|
|
553
|
+
var Host = class {
|
|
554
|
+
constructor(hostConfig, options) {
|
|
555
|
+
if (typeof hostConfig === "string") {
|
|
556
|
+
({
|
|
557
|
+
protocol: this.protocol,
|
|
558
|
+
host: this.host,
|
|
559
|
+
port: this.port
|
|
560
|
+
} = Host.parseUrl(hostConfig));
|
|
561
|
+
} else {
|
|
562
|
+
const { protocol = "https", host, port } = hostConfig;
|
|
563
|
+
this.protocol = protocol;
|
|
564
|
+
this.host = host;
|
|
565
|
+
this.port = port;
|
|
566
|
+
}
|
|
567
|
+
this.local = options?.isLocal;
|
|
568
|
+
}
|
|
569
|
+
static parseUrl(url, defaultProtocol = "https") {
|
|
570
|
+
let hostToParse = url;
|
|
571
|
+
if (!/^https?:\/\//.exec(hostToParse)) {
|
|
572
|
+
hostToParse = `${defaultProtocol}://${hostToParse}`;
|
|
573
|
+
}
|
|
574
|
+
const parsed = new URL(hostToParse);
|
|
575
|
+
if (!parsed.hostname) {
|
|
576
|
+
throw new Error(Host.getMicrofrontendsError(url, "requires a host"));
|
|
577
|
+
}
|
|
578
|
+
if (parsed.hash) {
|
|
579
|
+
throw new Error(
|
|
580
|
+
Host.getMicrofrontendsError(url, "cannot have a fragment")
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
if (parsed.username || parsed.password) {
|
|
584
|
+
throw new Error(
|
|
585
|
+
Host.getMicrofrontendsError(
|
|
586
|
+
url,
|
|
587
|
+
"cannot have authentication credentials (username and/or password)"
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
if (parsed.pathname !== "/") {
|
|
592
|
+
throw new Error(Host.getMicrofrontendsError(url, "cannot have a path"));
|
|
593
|
+
}
|
|
594
|
+
if (parsed.search) {
|
|
595
|
+
throw new Error(
|
|
596
|
+
Host.getMicrofrontendsError(url, "cannot have query parameters")
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
const protocol = parsed.protocol.slice(0, -1);
|
|
600
|
+
return {
|
|
601
|
+
protocol,
|
|
602
|
+
host: parsed.hostname,
|
|
603
|
+
port: parsed.port ? Number.parseInt(parsed.port, 10) : void 0
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
static getMicrofrontendsError(url, message) {
|
|
607
|
+
return `Microfrontends configuration error: the URL ${url} in your microfrontends.json ${message}.`;
|
|
608
|
+
}
|
|
609
|
+
isLocal() {
|
|
610
|
+
return this.local || this.host === "localhost" || this.host === "127.0.0.1";
|
|
611
|
+
}
|
|
612
|
+
toString() {
|
|
613
|
+
const url = this.toUrl();
|
|
614
|
+
return url.toString().replace(/\/$/, "");
|
|
615
|
+
}
|
|
616
|
+
toUrl() {
|
|
617
|
+
const url = `${this.protocol}://${this.host}${this.port ? `:${this.port}` : ""}`;
|
|
618
|
+
return new URL(url);
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
var LocalHost = class extends Host {
|
|
622
|
+
constructor({
|
|
623
|
+
appName,
|
|
624
|
+
local
|
|
625
|
+
}) {
|
|
626
|
+
const portOverride = process.env[MFE_APP_PORT_ENV];
|
|
627
|
+
if (portOverride) {
|
|
628
|
+
const overridePort = Number.parseInt(portOverride, 10);
|
|
629
|
+
if (!Number.isNaN(overridePort) && overridePort > 0 && overridePort < 65536) {
|
|
630
|
+
super({
|
|
631
|
+
protocol: "http",
|
|
632
|
+
host: "localhost",
|
|
633
|
+
port: overridePort
|
|
634
|
+
});
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
let protocol;
|
|
639
|
+
let host;
|
|
640
|
+
let port;
|
|
641
|
+
if (typeof local === "number") {
|
|
642
|
+
port = local;
|
|
643
|
+
} else if (typeof local === "string") {
|
|
644
|
+
if (/^\d+$/.test(local)) {
|
|
645
|
+
port = Number.parseInt(local, 10);
|
|
646
|
+
} else {
|
|
647
|
+
const parsed = Host.parseUrl(local, "http");
|
|
648
|
+
protocol = parsed.protocol;
|
|
649
|
+
host = parsed.host;
|
|
650
|
+
port = parsed.port;
|
|
651
|
+
}
|
|
652
|
+
} else if (local) {
|
|
653
|
+
protocol = local.protocol;
|
|
654
|
+
host = local.host;
|
|
655
|
+
port = local.port;
|
|
656
|
+
}
|
|
657
|
+
super({
|
|
658
|
+
protocol: protocol ?? "http",
|
|
659
|
+
host: host ?? "localhost",
|
|
660
|
+
port: port ?? generatePortFromName({ name: appName })
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
|
|
666
|
+
var import_md5 = __toESM(require("md5"), 1);
|
|
667
|
+
function hashApplicationName(name) {
|
|
668
|
+
if (!name) {
|
|
669
|
+
throw new Error("Application name is required to generate hash");
|
|
670
|
+
}
|
|
671
|
+
return (0, import_md5.default)(name).substring(0, 6).padStart(6, "0");
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
|
|
675
|
+
var PREFIX = "vc-ap";
|
|
676
|
+
function generateAssetPrefixFromName({
|
|
677
|
+
name
|
|
678
|
+
}) {
|
|
679
|
+
if (!name) {
|
|
680
|
+
throw new Error("Name is required to generate an asset prefix");
|
|
681
|
+
}
|
|
682
|
+
return `${PREFIX}-${hashApplicationName(name)}`;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// src/config/microfrontends-config/isomorphic/utils/generate-automation-bypass-env-var-name.ts
|
|
686
|
+
function generateAutomationBypassEnvVarName({
|
|
687
|
+
name
|
|
688
|
+
}) {
|
|
689
|
+
return `AUTOMATION_BYPASS_${name.toUpperCase().replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
690
|
+
}
|
|
691
|
+
|
|
503
692
|
// src/config/microfrontends-config/isomorphic/validation.ts
|
|
504
693
|
var import_path_to_regexp2 = require("path-to-regexp");
|
|
505
694
|
var LIST_FORMATTER = new Intl.ListFormat("en", {
|
|
@@ -681,154 +870,6 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
|
|
|
681
870
|
}
|
|
682
871
|
};
|
|
683
872
|
|
|
684
|
-
// src/config/microfrontends-config/isomorphic/utils/hash-application-name.ts
|
|
685
|
-
var import_md5 = __toESM(require("md5"), 1);
|
|
686
|
-
function hashApplicationName(name) {
|
|
687
|
-
if (!name) {
|
|
688
|
-
throw new Error("Application name is required to generate hash");
|
|
689
|
-
}
|
|
690
|
-
return (0, import_md5.default)(name).substring(0, 6).padStart(6, "0");
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// src/config/microfrontends-config/isomorphic/utils/generate-asset-prefix.ts
|
|
694
|
-
var PREFIX = "vc-ap";
|
|
695
|
-
function generateAssetPrefixFromName({
|
|
696
|
-
name
|
|
697
|
-
}) {
|
|
698
|
-
if (!name) {
|
|
699
|
-
throw new Error("Name is required to generate an asset prefix");
|
|
700
|
-
}
|
|
701
|
-
return `${PREFIX}-${hashApplicationName(name)}`;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
// src/config/microfrontends-config/isomorphic/utils/generate-port.ts
|
|
705
|
-
function generatePortFromName({
|
|
706
|
-
name,
|
|
707
|
-
minPort = 3e3,
|
|
708
|
-
maxPort = 8e3
|
|
709
|
-
}) {
|
|
710
|
-
if (!name) {
|
|
711
|
-
throw new Error("Name is required to generate a port");
|
|
712
|
-
}
|
|
713
|
-
let hash = 0;
|
|
714
|
-
for (let i = 0; i < name.length; i++) {
|
|
715
|
-
hash = (hash << 5) - hash + name.charCodeAt(i);
|
|
716
|
-
hash |= 0;
|
|
717
|
-
}
|
|
718
|
-
hash = Math.abs(hash);
|
|
719
|
-
const range = maxPort - minPort;
|
|
720
|
-
const port = minPort + hash % range;
|
|
721
|
-
return port;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
// src/config/microfrontends-config/isomorphic/host.ts
|
|
725
|
-
var Host = class {
|
|
726
|
-
constructor(hostConfig, options) {
|
|
727
|
-
if (typeof hostConfig === "string") {
|
|
728
|
-
({
|
|
729
|
-
protocol: this.protocol,
|
|
730
|
-
host: this.host,
|
|
731
|
-
port: this.port
|
|
732
|
-
} = Host.parseUrl(hostConfig));
|
|
733
|
-
} else {
|
|
734
|
-
const { protocol = "https", host, port } = hostConfig;
|
|
735
|
-
this.protocol = protocol;
|
|
736
|
-
this.host = host;
|
|
737
|
-
this.port = port;
|
|
738
|
-
}
|
|
739
|
-
this.local = options?.isLocal;
|
|
740
|
-
}
|
|
741
|
-
static parseUrl(url, defaultProtocol = "https") {
|
|
742
|
-
let hostToParse = url;
|
|
743
|
-
if (!/^https?:\/\//.exec(hostToParse)) {
|
|
744
|
-
hostToParse = `${defaultProtocol}://${hostToParse}`;
|
|
745
|
-
}
|
|
746
|
-
const parsed = new URL(hostToParse);
|
|
747
|
-
if (!parsed.hostname) {
|
|
748
|
-
throw new Error(Host.getMicrofrontendsError(url, "requires a host"));
|
|
749
|
-
}
|
|
750
|
-
if (parsed.hash) {
|
|
751
|
-
throw new Error(
|
|
752
|
-
Host.getMicrofrontendsError(url, "cannot have a fragment")
|
|
753
|
-
);
|
|
754
|
-
}
|
|
755
|
-
if (parsed.username || parsed.password) {
|
|
756
|
-
throw new Error(
|
|
757
|
-
Host.getMicrofrontendsError(
|
|
758
|
-
url,
|
|
759
|
-
"cannot have authentication credentials (username and/or password)"
|
|
760
|
-
)
|
|
761
|
-
);
|
|
762
|
-
}
|
|
763
|
-
if (parsed.pathname !== "/") {
|
|
764
|
-
throw new Error(Host.getMicrofrontendsError(url, "cannot have a path"));
|
|
765
|
-
}
|
|
766
|
-
if (parsed.search) {
|
|
767
|
-
throw new Error(
|
|
768
|
-
Host.getMicrofrontendsError(url, "cannot have query parameters")
|
|
769
|
-
);
|
|
770
|
-
}
|
|
771
|
-
const protocol = parsed.protocol.slice(0, -1);
|
|
772
|
-
return {
|
|
773
|
-
protocol,
|
|
774
|
-
host: parsed.hostname,
|
|
775
|
-
port: parsed.port ? Number.parseInt(parsed.port) : void 0
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
static getMicrofrontendsError(url, message) {
|
|
779
|
-
return `Microfrontends configuration error: the URL ${url} in your microfrontends.json ${message}.`;
|
|
780
|
-
}
|
|
781
|
-
isLocal() {
|
|
782
|
-
return this.local || this.host === "localhost" || this.host === "127.0.0.1";
|
|
783
|
-
}
|
|
784
|
-
toString() {
|
|
785
|
-
const url = this.toUrl();
|
|
786
|
-
return url.toString().replace(/\/$/, "");
|
|
787
|
-
}
|
|
788
|
-
toUrl() {
|
|
789
|
-
const url = `${this.protocol}://${this.host}${this.port ? `:${this.port}` : ""}`;
|
|
790
|
-
return new URL(url);
|
|
791
|
-
}
|
|
792
|
-
};
|
|
793
|
-
var LocalHost = class extends Host {
|
|
794
|
-
constructor({
|
|
795
|
-
appName,
|
|
796
|
-
local
|
|
797
|
-
}) {
|
|
798
|
-
let protocol;
|
|
799
|
-
let host;
|
|
800
|
-
let port;
|
|
801
|
-
if (typeof local === "number") {
|
|
802
|
-
port = local;
|
|
803
|
-
} else if (typeof local === "string") {
|
|
804
|
-
if (/^\d+$/.test(local)) {
|
|
805
|
-
port = Number.parseInt(local);
|
|
806
|
-
} else {
|
|
807
|
-
const parsed = Host.parseUrl(local, "http");
|
|
808
|
-
protocol = parsed.protocol;
|
|
809
|
-
host = parsed.host;
|
|
810
|
-
port = parsed.port;
|
|
811
|
-
}
|
|
812
|
-
} else if (local) {
|
|
813
|
-
protocol = local.protocol;
|
|
814
|
-
host = local.host;
|
|
815
|
-
port = local.port;
|
|
816
|
-
}
|
|
817
|
-
super({
|
|
818
|
-
protocol: protocol ?? "http",
|
|
819
|
-
host: host ?? "localhost",
|
|
820
|
-
port: port ?? generatePortFromName({ name: appName })
|
|
821
|
-
});
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
|
|
825
|
-
// src/config/microfrontends-config/isomorphic/utils/generate-automation-bypass-env-var-name.ts
|
|
826
|
-
function generateAutomationBypassEnvVarName({
|
|
827
|
-
name
|
|
828
|
-
}) {
|
|
829
|
-
return `AUTOMATION_BYPASS_${name.toUpperCase().replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
873
|
// src/config/microfrontends-config/isomorphic/application.ts
|
|
833
874
|
var Application = class {
|
|
834
875
|
constructor(name, {
|
|
@@ -909,9 +950,6 @@ var ChildApplication = class extends Application {
|
|
|
909
950
|
}
|
|
910
951
|
};
|
|
911
952
|
|
|
912
|
-
// src/config/microfrontends-config/isomorphic/constants.ts
|
|
913
|
-
var DEFAULT_LOCAL_PROXY_PORT = 3024;
|
|
914
|
-
|
|
915
953
|
// src/config/microfrontends-config/isomorphic/index.ts
|
|
916
954
|
var MicrofrontendConfigIsomorphic = class {
|
|
917
955
|
constructor({
|
|
@@ -1030,9 +1068,17 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
1030
1068
|
return this.defaultApplication;
|
|
1031
1069
|
}
|
|
1032
1070
|
/**
|
|
1033
|
-
* Returns the configured port for the local proxy
|
|
1071
|
+
* Returns the configured port for the local proxy.
|
|
1072
|
+
* Can be overridden via MFE_LOCAL_PROXY_PORT environment variable.
|
|
1034
1073
|
*/
|
|
1035
1074
|
getLocalProxyPort() {
|
|
1075
|
+
const portOverride = process.env[MFE_LOCAL_PROXY_PORT_ENV];
|
|
1076
|
+
if (portOverride) {
|
|
1077
|
+
const port = Number.parseInt(portOverride, 10);
|
|
1078
|
+
if (!Number.isNaN(port) && port > 0 && port < 65536) {
|
|
1079
|
+
return port;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1036
1082
|
return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
|
|
1037
1083
|
}
|
|
1038
1084
|
toClientConfig(options) {
|
|
@@ -1070,23 +1116,78 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
1070
1116
|
}
|
|
1071
1117
|
};
|
|
1072
1118
|
|
|
1073
|
-
// src/config/microfrontends/
|
|
1074
|
-
var
|
|
1075
|
-
var
|
|
1119
|
+
// src/config/microfrontends/utils/find-config.ts
|
|
1120
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
1121
|
+
var import_node_path = require("path");
|
|
1122
|
+
|
|
1123
|
+
// src/config/microfrontends/utils/get-config-file-name.ts
|
|
1124
|
+
var DEFAULT_CONFIGURATION_FILENAMES = [
|
|
1125
|
+
"microfrontends.json",
|
|
1126
|
+
"microfrontends.jsonc"
|
|
1127
|
+
];
|
|
1128
|
+
function getPossibleConfigurationFilenames({
|
|
1129
|
+
customConfigFilename
|
|
1130
|
+
}) {
|
|
1131
|
+
if (customConfigFilename) {
|
|
1132
|
+
if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
|
|
1133
|
+
throw new Error(
|
|
1134
|
+
`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.`
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
return Array.from(
|
|
1138
|
+
/* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
return DEFAULT_CONFIGURATION_FILENAMES;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// src/config/microfrontends/utils/find-config.ts
|
|
1145
|
+
function findConfig({
|
|
1146
|
+
dir,
|
|
1147
|
+
customConfigFilename
|
|
1148
|
+
}) {
|
|
1149
|
+
for (const filename of getPossibleConfigurationFilenames({
|
|
1150
|
+
customConfigFilename
|
|
1151
|
+
})) {
|
|
1152
|
+
const maybeConfig = (0, import_node_path.join)(dir, filename);
|
|
1153
|
+
if (import_node_fs.default.existsSync(maybeConfig)) {
|
|
1154
|
+
return maybeConfig;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
return null;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/config/microfrontends/utils/find-package-root.ts
|
|
1161
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
1162
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
1163
|
+
var PACKAGE_JSON = "package.json";
|
|
1164
|
+
function findPackageRoot(startDir) {
|
|
1165
|
+
let currentDir = startDir || process.cwd();
|
|
1166
|
+
while (currentDir !== import_node_path2.default.parse(currentDir).root) {
|
|
1167
|
+
const pkgJsonPath = import_node_path2.default.join(currentDir, PACKAGE_JSON);
|
|
1168
|
+
if (import_node_fs2.default.existsSync(pkgJsonPath)) {
|
|
1169
|
+
return currentDir;
|
|
1170
|
+
}
|
|
1171
|
+
currentDir = import_node_path2.default.dirname(currentDir);
|
|
1172
|
+
}
|
|
1173
|
+
throw new Error(
|
|
1174
|
+
`The root of the package that contains the \`package.json\` file for the \`${startDir}\` directory could not be found.`
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1076
1177
|
|
|
1077
1178
|
// src/config/microfrontends/utils/find-repository-root.ts
|
|
1078
|
-
var
|
|
1079
|
-
var
|
|
1179
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
1180
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
1080
1181
|
var GIT_DIRECTORY = ".git";
|
|
1081
1182
|
function hasGitDirectory(dir) {
|
|
1082
|
-
const gitPath =
|
|
1083
|
-
return
|
|
1183
|
+
const gitPath = import_node_path3.default.join(dir, GIT_DIRECTORY);
|
|
1184
|
+
return import_node_fs3.default.existsSync(gitPath) && import_node_fs3.default.statSync(gitPath).isDirectory();
|
|
1084
1185
|
}
|
|
1085
1186
|
function hasPnpmWorkspaces(dir) {
|
|
1086
|
-
return
|
|
1187
|
+
return import_node_fs3.default.existsSync(import_node_path3.default.join(dir, "pnpm-workspace.yaml"));
|
|
1087
1188
|
}
|
|
1088
1189
|
function hasPackageJson(dir) {
|
|
1089
|
-
return
|
|
1190
|
+
return import_node_fs3.default.existsSync(import_node_path3.default.join(dir, "package.json"));
|
|
1090
1191
|
}
|
|
1091
1192
|
function findRepositoryRoot(startDir) {
|
|
1092
1193
|
if (process.env.NX_WORKSPACE_ROOT) {
|
|
@@ -1094,14 +1195,14 @@ function findRepositoryRoot(startDir) {
|
|
|
1094
1195
|
}
|
|
1095
1196
|
let currentDir = startDir || process.cwd();
|
|
1096
1197
|
let lastPackageJsonDir = null;
|
|
1097
|
-
while (currentDir !==
|
|
1198
|
+
while (currentDir !== import_node_path3.default.parse(currentDir).root) {
|
|
1098
1199
|
if (hasGitDirectory(currentDir) || hasPnpmWorkspaces(currentDir)) {
|
|
1099
1200
|
return currentDir;
|
|
1100
1201
|
}
|
|
1101
1202
|
if (hasPackageJson(currentDir)) {
|
|
1102
1203
|
lastPackageJsonDir = currentDir;
|
|
1103
1204
|
}
|
|
1104
|
-
currentDir =
|
|
1205
|
+
currentDir = import_node_path3.default.dirname(currentDir);
|
|
1105
1206
|
}
|
|
1106
1207
|
if (lastPackageJsonDir) {
|
|
1107
1208
|
return lastPackageJsonDir;
|
|
@@ -1111,34 +1212,88 @@ function findRepositoryRoot(startDir) {
|
|
|
1111
1212
|
);
|
|
1112
1213
|
}
|
|
1113
1214
|
|
|
1114
|
-
// src/config/microfrontends/utils/
|
|
1115
|
-
var
|
|
1116
|
-
var
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1215
|
+
// src/config/microfrontends/utils/get-application-context.ts
|
|
1216
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1217
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1218
|
+
function getApplicationContext(opts) {
|
|
1219
|
+
if (opts?.appName) {
|
|
1220
|
+
logger.debug(
|
|
1221
|
+
"[MFE Config] Application name from appName parameter:",
|
|
1222
|
+
opts.appName
|
|
1223
|
+
);
|
|
1224
|
+
return { name: opts.appName };
|
|
1225
|
+
}
|
|
1226
|
+
if (process.env.VERCEL_PROJECT_NAME) {
|
|
1227
|
+
logger.debug(
|
|
1228
|
+
"[MFE Config] Application name from VERCEL_PROJECT_NAME:",
|
|
1229
|
+
process.env.VERCEL_PROJECT_NAME
|
|
1230
|
+
);
|
|
1231
|
+
return {
|
|
1232
|
+
name: process.env.VERCEL_PROJECT_NAME,
|
|
1233
|
+
projectName: process.env.VERCEL_PROJECT_NAME
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
1237
|
+
logger.debug(
|
|
1238
|
+
"[MFE Config] Application name from NX_TASK_TARGET_PROJECT:",
|
|
1239
|
+
process.env.NX_TASK_TARGET_PROJECT
|
|
1240
|
+
);
|
|
1241
|
+
return {
|
|
1242
|
+
name: process.env.NX_TASK_TARGET_PROJECT,
|
|
1243
|
+
packageJsonName: process.env.NX_TASK_TARGET_PROJECT
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
try {
|
|
1247
|
+
const vercelProjectJsonPath = import_node_fs4.default.readFileSync(
|
|
1248
|
+
import_node_path4.default.join(opts?.packageRoot || ".", ".vercel", "project.json"),
|
|
1249
|
+
"utf-8"
|
|
1250
|
+
);
|
|
1251
|
+
const projectJson = JSON.parse(vercelProjectJsonPath);
|
|
1252
|
+
if (projectJson.projectName) {
|
|
1253
|
+
logger.debug(
|
|
1254
|
+
"[MFE Config] Application name from .vercel/project.json:",
|
|
1255
|
+
projectJson.projectName
|
|
1132
1256
|
);
|
|
1257
|
+
return {
|
|
1258
|
+
name: projectJson.projectName,
|
|
1259
|
+
projectName: projectJson.projectName
|
|
1260
|
+
};
|
|
1133
1261
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1262
|
+
} catch (_) {
|
|
1263
|
+
}
|
|
1264
|
+
try {
|
|
1265
|
+
const packageJsonString = import_node_fs4.default.readFileSync(
|
|
1266
|
+
import_node_path4.default.join(opts?.packageRoot || ".", "package.json"),
|
|
1267
|
+
"utf-8"
|
|
1268
|
+
);
|
|
1269
|
+
const packageJson = JSON.parse(packageJsonString);
|
|
1270
|
+
if (!packageJson.name) {
|
|
1271
|
+
throw new MicrofrontendError(
|
|
1272
|
+
`package.json file missing required field "name"`,
|
|
1273
|
+
{
|
|
1274
|
+
type: "packageJson",
|
|
1275
|
+
subtype: "missing_field_name",
|
|
1276
|
+
source: "@vercel/microfrontends/next"
|
|
1277
|
+
}
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
logger.debug(
|
|
1281
|
+
"[MFE Config] Application name from package.json:",
|
|
1282
|
+
packageJson.name
|
|
1136
1283
|
);
|
|
1284
|
+
return { name: packageJson.name, packageJsonName: packageJson.name };
|
|
1285
|
+
} catch (err) {
|
|
1286
|
+
throw MicrofrontendError.handle(err, {
|
|
1287
|
+
fileName: "package.json"
|
|
1288
|
+
});
|
|
1137
1289
|
}
|
|
1138
|
-
return DEFAULT_CONFIGURATION_FILENAMES;
|
|
1139
1290
|
}
|
|
1140
1291
|
|
|
1141
1292
|
// src/config/microfrontends/utils/infer-microfrontends-location.ts
|
|
1293
|
+
var import_node_fs5 = require("fs");
|
|
1294
|
+
var import_node_path5 = require("path");
|
|
1295
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
1296
|
+
var import_jsonc_parser2 = require("jsonc-parser");
|
|
1142
1297
|
var configCache = {};
|
|
1143
1298
|
function findPackageWithMicrofrontendsConfig({
|
|
1144
1299
|
repositoryRoot,
|
|
@@ -1146,6 +1301,10 @@ function findPackageWithMicrofrontendsConfig({
|
|
|
1146
1301
|
customConfigFilename
|
|
1147
1302
|
}) {
|
|
1148
1303
|
const applicationName = applicationContext.name;
|
|
1304
|
+
logger.debug(
|
|
1305
|
+
"[MFE Config] Searching repository for configs containing application:",
|
|
1306
|
+
applicationName
|
|
1307
|
+
);
|
|
1149
1308
|
try {
|
|
1150
1309
|
const microfrontendsJsonPaths = import_fast_glob.default.globSync(
|
|
1151
1310
|
`**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
|
|
@@ -1157,28 +1316,21 @@ function findPackageWithMicrofrontendsConfig({
|
|
|
1157
1316
|
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
1158
1317
|
}
|
|
1159
1318
|
);
|
|
1319
|
+
logger.debug(
|
|
1320
|
+
"[MFE Config] Found",
|
|
1321
|
+
microfrontendsJsonPaths.length,
|
|
1322
|
+
"config file(s) in repository"
|
|
1323
|
+
);
|
|
1160
1324
|
const matchingPaths = [];
|
|
1161
1325
|
for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
microfrontendsJsonPath,
|
|
1165
|
-
"utf-8"
|
|
1166
|
-
);
|
|
1167
|
-
const microfrontendsJson = (0, import_jsonc_parser2.parse)(microfrontendsJsonContent);
|
|
1168
|
-
if (microfrontendsJson.applications[applicationName]) {
|
|
1169
|
-
matchingPaths.push(microfrontendsJsonPath);
|
|
1170
|
-
} else {
|
|
1171
|
-
for (const [_, app] of Object.entries(
|
|
1172
|
-
microfrontendsJson.applications
|
|
1173
|
-
)) {
|
|
1174
|
-
if (app.packageName === applicationName) {
|
|
1175
|
-
matchingPaths.push(microfrontendsJsonPath);
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
} catch (error2) {
|
|
1326
|
+
if (doesApplicationExistInConfig(microfrontendsJsonPath, applicationName)) {
|
|
1327
|
+
matchingPaths.push(microfrontendsJsonPath);
|
|
1180
1328
|
}
|
|
1181
1329
|
}
|
|
1330
|
+
logger.debug(
|
|
1331
|
+
"[MFE Config] Total matching config files:",
|
|
1332
|
+
matchingPaths.length
|
|
1333
|
+
);
|
|
1182
1334
|
if (matchingPaths.length > 1) {
|
|
1183
1335
|
throw new MicrofrontendError(
|
|
1184
1336
|
`Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
|
|
@@ -1187,6 +1339,34 @@ ${matchingPaths.join("\n \u2022 ")}`,
|
|
|
1187
1339
|
);
|
|
1188
1340
|
}
|
|
1189
1341
|
if (matchingPaths.length === 0) {
|
|
1342
|
+
if (repositoryRoot && doesMisplacedConfigExist(
|
|
1343
|
+
repositoryRoot,
|
|
1344
|
+
applicationName,
|
|
1345
|
+
customConfigFilename
|
|
1346
|
+
)) {
|
|
1347
|
+
logger.debug(
|
|
1348
|
+
"[MFE Config] Found misplaced config in wrong .vercel directory in repository"
|
|
1349
|
+
);
|
|
1350
|
+
const misplacedConfigPath = (0, import_node_path5.join)(
|
|
1351
|
+
repositoryRoot,
|
|
1352
|
+
".vercel",
|
|
1353
|
+
customConfigFilename || "microfrontends.json"
|
|
1354
|
+
);
|
|
1355
|
+
throw new MicrofrontendError(
|
|
1356
|
+
`Unable to automatically infer the location of the \`microfrontends.json\` file.
|
|
1357
|
+
|
|
1358
|
+
A microfrontends config was found in the \`.vercel\` directory at the repository root: ${misplacedConfigPath}
|
|
1359
|
+
However, in a monorepo, the config file should be placed in the \`.vercel\` directory in your application directory instead.
|
|
1360
|
+
|
|
1361
|
+
To fix this:
|
|
1362
|
+
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
|
|
1363
|
+
2. If manually defined, move the config file to the \`.vercel\` directory in your application
|
|
1364
|
+
3. Alternatively, set the VC_MICROFRONTENDS_CONFIG environment variable to the correct path
|
|
1365
|
+
|
|
1366
|
+
For more information, see: https://vercel.com/docs/cli/project-linking`,
|
|
1367
|
+
{ type: "config", subtype: "inference_failed" }
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1190
1370
|
let additionalErrorMessage = "";
|
|
1191
1371
|
if (microfrontendsJsonPaths.length > 0) {
|
|
1192
1372
|
if (!applicationContext.projectName) {
|
|
@@ -1211,7 +1391,7 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
|
|
|
1211
1391
|
);
|
|
1212
1392
|
}
|
|
1213
1393
|
const [packageJsonPath] = matchingPaths;
|
|
1214
|
-
return (0,
|
|
1394
|
+
return (0, import_node_path5.dirname)(packageJsonPath);
|
|
1215
1395
|
} catch (error2) {
|
|
1216
1396
|
if (error2 instanceof MicrofrontendError) {
|
|
1217
1397
|
throw error2;
|
|
@@ -1234,53 +1414,76 @@ function inferMicrofrontendsLocation(opts) {
|
|
|
1234
1414
|
configCache[cacheKey] = result;
|
|
1235
1415
|
return result;
|
|
1236
1416
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
function debug(...args) {
|
|
1244
|
-
if (process.env.MFE_DEBUG) {
|
|
1245
|
-
console.log(...args);
|
|
1417
|
+
function existsSync(path7) {
|
|
1418
|
+
try {
|
|
1419
|
+
(0, import_node_fs5.statSync)(path7);
|
|
1420
|
+
return true;
|
|
1421
|
+
} catch (_) {
|
|
1422
|
+
return false;
|
|
1246
1423
|
}
|
|
1247
1424
|
}
|
|
1248
|
-
function
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1425
|
+
function doesMisplacedConfigExist(repositoryRoot, applicationName, customConfigFilename) {
|
|
1426
|
+
logger.debug(
|
|
1427
|
+
"[MFE Config] Looking for misplaced config in wrong .vercel directory"
|
|
1428
|
+
);
|
|
1429
|
+
const misplacedConfigPath = (0, import_node_path5.join)(
|
|
1430
|
+
repositoryRoot,
|
|
1431
|
+
".vercel",
|
|
1432
|
+
customConfigFilename || "microfrontends.json"
|
|
1433
|
+
);
|
|
1434
|
+
return existsSync(misplacedConfigPath) && doesApplicationExistInConfig(misplacedConfigPath, applicationName);
|
|
1253
1435
|
}
|
|
1254
|
-
function
|
|
1255
|
-
|
|
1436
|
+
function doesApplicationExistInConfig(microfrontendsJsonPath, applicationName) {
|
|
1437
|
+
try {
|
|
1438
|
+
const microfrontendsJsonContent = (0, import_node_fs5.readFileSync)(
|
|
1439
|
+
microfrontendsJsonPath,
|
|
1440
|
+
"utf-8"
|
|
1441
|
+
);
|
|
1442
|
+
const microfrontendsJson = (0, import_jsonc_parser2.parse)(microfrontendsJsonContent);
|
|
1443
|
+
if (microfrontendsJson.applications[applicationName]) {
|
|
1444
|
+
logger.debug(
|
|
1445
|
+
"[MFE Config] Found application in config:",
|
|
1446
|
+
microfrontendsJsonPath
|
|
1447
|
+
);
|
|
1448
|
+
return true;
|
|
1449
|
+
}
|
|
1450
|
+
for (const [_, app] of Object.entries(microfrontendsJson.applications)) {
|
|
1451
|
+
if (app.packageName === applicationName) {
|
|
1452
|
+
logger.debug(
|
|
1453
|
+
"[MFE Config] Found application via packageName in config:",
|
|
1454
|
+
microfrontendsJsonPath
|
|
1455
|
+
);
|
|
1456
|
+
return true;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
} catch (error2) {
|
|
1460
|
+
logger.debug("[MFE Config] Error checking application in config:", error2);
|
|
1461
|
+
}
|
|
1462
|
+
return false;
|
|
1256
1463
|
}
|
|
1257
|
-
var logger = {
|
|
1258
|
-
debug,
|
|
1259
|
-
info,
|
|
1260
|
-
warn,
|
|
1261
|
-
error
|
|
1262
|
-
};
|
|
1263
1464
|
|
|
1264
1465
|
// src/config/microfrontends/utils/is-monorepo.ts
|
|
1466
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
1467
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
1265
1468
|
function isMonorepo({
|
|
1266
1469
|
repositoryRoot
|
|
1267
1470
|
}) {
|
|
1268
1471
|
try {
|
|
1269
|
-
if (
|
|
1472
|
+
if (import_node_fs6.default.existsSync(import_node_path6.default.join(repositoryRoot, "pnpm-workspace.yaml"))) {
|
|
1270
1473
|
return true;
|
|
1271
1474
|
}
|
|
1272
|
-
if (
|
|
1475
|
+
if (import_node_fs6.default.existsSync(import_node_path6.default.join(repositoryRoot, "vlt-workspaces.json"))) {
|
|
1273
1476
|
return true;
|
|
1274
1477
|
}
|
|
1275
|
-
if (process.env.NX_WORKSPACE_ROOT ===
|
|
1478
|
+
if (process.env.NX_WORKSPACE_ROOT === import_node_path6.default.resolve(repositoryRoot)) {
|
|
1276
1479
|
return true;
|
|
1277
1480
|
}
|
|
1278
|
-
const packageJsonPath =
|
|
1279
|
-
if (!
|
|
1481
|
+
const packageJsonPath = import_node_path6.default.join(repositoryRoot, "package.json");
|
|
1482
|
+
if (!import_node_fs6.default.existsSync(packageJsonPath)) {
|
|
1280
1483
|
return false;
|
|
1281
1484
|
}
|
|
1282
1485
|
const packageJson = JSON.parse(
|
|
1283
|
-
|
|
1486
|
+
import_node_fs6.default.readFileSync(packageJsonPath, "utf-8")
|
|
1284
1487
|
);
|
|
1285
1488
|
return packageJson.workspaces !== void 0;
|
|
1286
1489
|
} catch (error2) {
|
|
@@ -1289,99 +1492,6 @@ function isMonorepo({
|
|
|
1289
1492
|
}
|
|
1290
1493
|
}
|
|
1291
1494
|
|
|
1292
|
-
// src/config/microfrontends/utils/find-package-root.ts
|
|
1293
|
-
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1294
|
-
var import_node_path4 = __toESM(require("path"), 1);
|
|
1295
|
-
var PACKAGE_JSON = "package.json";
|
|
1296
|
-
function findPackageRoot(startDir) {
|
|
1297
|
-
let currentDir = startDir || process.cwd();
|
|
1298
|
-
while (currentDir !== import_node_path4.default.parse(currentDir).root) {
|
|
1299
|
-
const pkgJsonPath = import_node_path4.default.join(currentDir, PACKAGE_JSON);
|
|
1300
|
-
if (import_node_fs4.default.existsSync(pkgJsonPath)) {
|
|
1301
|
-
return currentDir;
|
|
1302
|
-
}
|
|
1303
|
-
currentDir = import_node_path4.default.dirname(currentDir);
|
|
1304
|
-
}
|
|
1305
|
-
throw new Error(
|
|
1306
|
-
`The root of the package that contains the \`package.json\` file for the \`${startDir}\` directory could not be found.`
|
|
1307
|
-
);
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
// src/config/microfrontends/utils/find-config.ts
|
|
1311
|
-
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
1312
|
-
var import_node_path5 = require("path");
|
|
1313
|
-
function findConfig({
|
|
1314
|
-
dir,
|
|
1315
|
-
customConfigFilename
|
|
1316
|
-
}) {
|
|
1317
|
-
for (const filename of getPossibleConfigurationFilenames({
|
|
1318
|
-
customConfigFilename
|
|
1319
|
-
})) {
|
|
1320
|
-
const maybeConfig = (0, import_node_path5.join)(dir, filename);
|
|
1321
|
-
if (import_node_fs5.default.existsSync(maybeConfig)) {
|
|
1322
|
-
return maybeConfig;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
return null;
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
// src/config/microfrontends/utils/get-application-context.ts
|
|
1329
|
-
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
1330
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
1331
|
-
function getApplicationContext(opts) {
|
|
1332
|
-
if (opts?.appName) {
|
|
1333
|
-
return { name: opts.appName };
|
|
1334
|
-
}
|
|
1335
|
-
if (process.env.VERCEL_PROJECT_NAME) {
|
|
1336
|
-
return {
|
|
1337
|
-
name: process.env.VERCEL_PROJECT_NAME,
|
|
1338
|
-
projectName: process.env.VERCEL_PROJECT_NAME
|
|
1339
|
-
};
|
|
1340
|
-
}
|
|
1341
|
-
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
1342
|
-
return {
|
|
1343
|
-
name: process.env.NX_TASK_TARGET_PROJECT,
|
|
1344
|
-
packageJsonName: process.env.NX_TASK_TARGET_PROJECT
|
|
1345
|
-
};
|
|
1346
|
-
}
|
|
1347
|
-
try {
|
|
1348
|
-
const vercelProjectJsonPath = import_node_fs6.default.readFileSync(
|
|
1349
|
-
import_node_path6.default.join(opts?.packageRoot || ".", ".vercel", "project.json"),
|
|
1350
|
-
"utf-8"
|
|
1351
|
-
);
|
|
1352
|
-
const projectJson = JSON.parse(vercelProjectJsonPath);
|
|
1353
|
-
if (projectJson.projectName) {
|
|
1354
|
-
return {
|
|
1355
|
-
name: projectJson.projectName,
|
|
1356
|
-
projectName: projectJson.projectName
|
|
1357
|
-
};
|
|
1358
|
-
}
|
|
1359
|
-
} catch (_) {
|
|
1360
|
-
}
|
|
1361
|
-
try {
|
|
1362
|
-
const packageJsonString = import_node_fs6.default.readFileSync(
|
|
1363
|
-
import_node_path6.default.join(opts?.packageRoot || ".", "package.json"),
|
|
1364
|
-
"utf-8"
|
|
1365
|
-
);
|
|
1366
|
-
const packageJson = JSON.parse(packageJsonString);
|
|
1367
|
-
if (!packageJson.name) {
|
|
1368
|
-
throw new MicrofrontendError(
|
|
1369
|
-
`package.json file missing required field "name"`,
|
|
1370
|
-
{
|
|
1371
|
-
type: "packageJson",
|
|
1372
|
-
subtype: "missing_field_name",
|
|
1373
|
-
source: "@vercel/microfrontends/next"
|
|
1374
|
-
}
|
|
1375
|
-
);
|
|
1376
|
-
}
|
|
1377
|
-
return { name: packageJson.name, packageJsonName: packageJson.name };
|
|
1378
|
-
} catch (err) {
|
|
1379
|
-
throw MicrofrontendError.handle(err, {
|
|
1380
|
-
fileName: "package.json"
|
|
1381
|
-
});
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
1495
|
// src/config/microfrontends/server/utils/get-output-file-path.ts
|
|
1386
1496
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
1387
1497
|
|
|
@@ -1395,8 +1505,8 @@ function getOutputFilePath() {
|
|
|
1395
1505
|
}
|
|
1396
1506
|
|
|
1397
1507
|
// src/config/microfrontends/server/validation.ts
|
|
1398
|
-
var import_jsonc_parser3 = require("jsonc-parser");
|
|
1399
1508
|
var import_ajv = require("ajv");
|
|
1509
|
+
var import_jsonc_parser3 = require("jsonc-parser");
|
|
1400
1510
|
|
|
1401
1511
|
// schema/schema.json
|
|
1402
1512
|
var schema_default = {
|
|
@@ -1424,9 +1534,7 @@ var schema_default = {
|
|
|
1424
1534
|
description: "Optional configuration options for the microfrontend."
|
|
1425
1535
|
}
|
|
1426
1536
|
},
|
|
1427
|
-
required: [
|
|
1428
|
-
"applications"
|
|
1429
|
-
],
|
|
1537
|
+
required: ["applications"],
|
|
1430
1538
|
additionalProperties: false,
|
|
1431
1539
|
description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
|
|
1432
1540
|
},
|
|
@@ -1463,19 +1571,14 @@ var schema_default = {
|
|
|
1463
1571
|
description: "Development configuration for the default application."
|
|
1464
1572
|
}
|
|
1465
1573
|
},
|
|
1466
|
-
required: [
|
|
1467
|
-
"development"
|
|
1468
|
-
],
|
|
1574
|
+
required: ["development"],
|
|
1469
1575
|
additionalProperties: false
|
|
1470
1576
|
},
|
|
1471
1577
|
DefaultDevelopment: {
|
|
1472
1578
|
type: "object",
|
|
1473
1579
|
properties: {
|
|
1474
1580
|
local: {
|
|
1475
|
-
type: [
|
|
1476
|
-
"number",
|
|
1477
|
-
"string"
|
|
1478
|
-
],
|
|
1581
|
+
type: ["number", "string"],
|
|
1479
1582
|
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."
|
|
1480
1583
|
},
|
|
1481
1584
|
task: {
|
|
@@ -1487,9 +1590,7 @@ var schema_default = {
|
|
|
1487
1590
|
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."
|
|
1488
1591
|
}
|
|
1489
1592
|
},
|
|
1490
|
-
required: [
|
|
1491
|
-
"fallback"
|
|
1492
|
-
],
|
|
1593
|
+
required: ["fallback"],
|
|
1493
1594
|
additionalProperties: false
|
|
1494
1595
|
},
|
|
1495
1596
|
ChildApplication: {
|
|
@@ -1512,19 +1613,14 @@ var schema_default = {
|
|
|
1512
1613
|
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."
|
|
1513
1614
|
}
|
|
1514
1615
|
},
|
|
1515
|
-
required: [
|
|
1516
|
-
"routing"
|
|
1517
|
-
],
|
|
1616
|
+
required: ["routing"],
|
|
1518
1617
|
additionalProperties: false
|
|
1519
1618
|
},
|
|
1520
1619
|
ChildDevelopment: {
|
|
1521
1620
|
type: "object",
|
|
1522
1621
|
properties: {
|
|
1523
1622
|
local: {
|
|
1524
|
-
type: [
|
|
1525
|
-
"number",
|
|
1526
|
-
"string"
|
|
1527
|
-
],
|
|
1623
|
+
type: ["number", "string"],
|
|
1528
1624
|
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."
|
|
1529
1625
|
},
|
|
1530
1626
|
task: {
|
|
@@ -1564,9 +1660,7 @@ var schema_default = {
|
|
|
1564
1660
|
description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
|
|
1565
1661
|
}
|
|
1566
1662
|
},
|
|
1567
|
-
required: [
|
|
1568
|
-
"paths"
|
|
1569
|
-
],
|
|
1663
|
+
required: ["paths"],
|
|
1570
1664
|
additionalProperties: false,
|
|
1571
1665
|
description: "A group of paths that is routed to this application."
|
|
1572
1666
|
},
|
|
@@ -1745,7 +1839,13 @@ var MicrofrontendsServer = class {
|
|
|
1745
1839
|
filePath,
|
|
1746
1840
|
cookies
|
|
1747
1841
|
} = {}) {
|
|
1842
|
+
logger.debug("[MFE Config] Starting config inference", {
|
|
1843
|
+
appName,
|
|
1844
|
+
directory: directory || process.cwd(),
|
|
1845
|
+
filePath
|
|
1846
|
+
});
|
|
1748
1847
|
if (filePath) {
|
|
1848
|
+
logger.debug("[MFE Config] Using explicit filePath:", filePath);
|
|
1749
1849
|
return MicrofrontendsServer.fromFile({
|
|
1750
1850
|
filePath,
|
|
1751
1851
|
cookies
|
|
@@ -1753,16 +1853,25 @@ var MicrofrontendsServer = class {
|
|
|
1753
1853
|
}
|
|
1754
1854
|
try {
|
|
1755
1855
|
const packageRoot = findPackageRoot(directory);
|
|
1856
|
+
logger.debug("[MFE Config] Package root:", packageRoot);
|
|
1756
1857
|
const applicationContext = getApplicationContext({
|
|
1757
1858
|
appName,
|
|
1758
1859
|
packageRoot
|
|
1759
1860
|
});
|
|
1861
|
+
logger.debug("[MFE Config] Application context:", applicationContext);
|
|
1760
1862
|
const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
|
|
1863
|
+
if (customConfigFilename) {
|
|
1864
|
+
logger.debug(
|
|
1865
|
+
"[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
|
|
1866
|
+
customConfigFilename
|
|
1867
|
+
);
|
|
1868
|
+
}
|
|
1761
1869
|
const maybeConfig = findConfig({
|
|
1762
1870
|
dir: packageRoot,
|
|
1763
1871
|
customConfigFilename
|
|
1764
1872
|
});
|
|
1765
1873
|
if (maybeConfig) {
|
|
1874
|
+
logger.debug("[MFE Config] Config found at package root:", maybeConfig);
|
|
1766
1875
|
return MicrofrontendsServer.fromFile({
|
|
1767
1876
|
filePath: maybeConfig,
|
|
1768
1877
|
cookies
|
|
@@ -1770,42 +1879,78 @@ var MicrofrontendsServer = class {
|
|
|
1770
1879
|
}
|
|
1771
1880
|
const repositoryRoot = findRepositoryRoot();
|
|
1772
1881
|
const isMonorepo2 = isMonorepo({ repositoryRoot });
|
|
1882
|
+
logger.debug(
|
|
1883
|
+
"[MFE Config] Repository root:",
|
|
1884
|
+
repositoryRoot,
|
|
1885
|
+
"Is monorepo:",
|
|
1886
|
+
isMonorepo2
|
|
1887
|
+
);
|
|
1773
1888
|
const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
|
|
1774
1889
|
if (typeof configFromEnv === "string") {
|
|
1890
|
+
logger.debug(
|
|
1891
|
+
"[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
|
|
1892
|
+
configFromEnv
|
|
1893
|
+
);
|
|
1775
1894
|
const maybeConfigFromEnv = (0, import_node_path8.resolve)(packageRoot, configFromEnv);
|
|
1776
1895
|
if (maybeConfigFromEnv) {
|
|
1896
|
+
logger.debug(
|
|
1897
|
+
"[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
|
|
1898
|
+
maybeConfigFromEnv
|
|
1899
|
+
);
|
|
1777
1900
|
return MicrofrontendsServer.fromFile({
|
|
1778
1901
|
filePath: maybeConfigFromEnv,
|
|
1779
1902
|
cookies
|
|
1780
1903
|
});
|
|
1781
1904
|
}
|
|
1782
1905
|
} else {
|
|
1906
|
+
const vercelDir = (0, import_node_path8.join)(packageRoot, ".vercel");
|
|
1907
|
+
logger.debug(
|
|
1908
|
+
"[MFE Config] Searching for config in .vercel directory:",
|
|
1909
|
+
vercelDir
|
|
1910
|
+
);
|
|
1783
1911
|
const maybeConfigFromVercel = findConfig({
|
|
1784
|
-
dir:
|
|
1912
|
+
dir: vercelDir,
|
|
1785
1913
|
customConfigFilename
|
|
1786
1914
|
});
|
|
1787
1915
|
if (maybeConfigFromVercel) {
|
|
1916
|
+
logger.debug(
|
|
1917
|
+
"[MFE Config] Config found in .vercel directory:",
|
|
1918
|
+
maybeConfigFromVercel
|
|
1919
|
+
);
|
|
1788
1920
|
return MicrofrontendsServer.fromFile({
|
|
1789
1921
|
filePath: maybeConfigFromVercel,
|
|
1790
1922
|
cookies
|
|
1791
1923
|
});
|
|
1792
1924
|
}
|
|
1793
1925
|
if (isMonorepo2) {
|
|
1926
|
+
logger.debug(
|
|
1927
|
+
"[MFE Config] Inferring microfrontends location in monorepo for application:",
|
|
1928
|
+
applicationContext.name
|
|
1929
|
+
);
|
|
1794
1930
|
const defaultPackage = inferMicrofrontendsLocation({
|
|
1795
1931
|
repositoryRoot,
|
|
1796
1932
|
applicationContext,
|
|
1797
1933
|
customConfigFilename
|
|
1798
1934
|
});
|
|
1935
|
+
logger.debug(
|
|
1936
|
+
"[MFE Config] Inferred package location:",
|
|
1937
|
+
defaultPackage
|
|
1938
|
+
);
|
|
1799
1939
|
const maybeConfigFromDefault = findConfig({
|
|
1800
1940
|
dir: defaultPackage,
|
|
1801
1941
|
customConfigFilename
|
|
1802
1942
|
});
|
|
1803
1943
|
if (maybeConfigFromDefault) {
|
|
1944
|
+
logger.debug(
|
|
1945
|
+
"[MFE Config] Config found in inferred package:",
|
|
1946
|
+
maybeConfigFromDefault
|
|
1947
|
+
);
|
|
1804
1948
|
return MicrofrontendsServer.fromFile({
|
|
1805
1949
|
filePath: maybeConfigFromDefault,
|
|
1806
1950
|
cookies
|
|
1807
1951
|
});
|
|
1808
1952
|
}
|
|
1953
|
+
logger.debug("[MFE Config] No config found in inferred package");
|
|
1809
1954
|
}
|
|
1810
1955
|
}
|
|
1811
1956
|
throw new MicrofrontendError(
|
|
@@ -1831,8 +1976,13 @@ var MicrofrontendsServer = class {
|
|
|
1831
1976
|
cookies
|
|
1832
1977
|
}) {
|
|
1833
1978
|
try {
|
|
1979
|
+
logger.debug("[MFE Config] Reading config from file:", filePath);
|
|
1834
1980
|
const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
|
|
1835
1981
|
const config = MicrofrontendsServer.validate(configJson);
|
|
1982
|
+
logger.debug(
|
|
1983
|
+
"[MFE Config] Config loaded with applications:",
|
|
1984
|
+
Object.keys(config.applications)
|
|
1985
|
+
);
|
|
1836
1986
|
return new MicrofrontendsServer({
|
|
1837
1987
|
config,
|
|
1838
1988
|
overrides: cookies ? parseOverrides(cookies) : void 0
|
|
@@ -2583,6 +2733,11 @@ var LocalProxy = class {
|
|
|
2583
2733
|
`The following apps passed via --local-apps are not in the microfrontends config: ${unknownApps.join(", ")} (microfrontends config contains: ${Array.from(allApps).join(", ")})`
|
|
2584
2734
|
);
|
|
2585
2735
|
}
|
|
2736
|
+
if (process.env[MFE_APP_PORT_ENV] && localApps.length > 1) {
|
|
2737
|
+
throw new Error(
|
|
2738
|
+
`${MFE_APP_PORT_ENV} cannot be used when multiple applications are running locally. You have ${localApps.length} local apps: ${localApps.join(", ")}. Either run a single app locally or remove the ${MFE_APP_PORT_ENV} environment variable.`
|
|
2739
|
+
);
|
|
2740
|
+
}
|
|
2586
2741
|
}
|
|
2587
2742
|
startServer() {
|
|
2588
2743
|
const httpServer = http.createServer(
|
|
@@ -2854,10 +3009,23 @@ function formatProxyTarget(target) {
|
|
|
2854
3009
|
var import_node_process = require("process");
|
|
2855
3010
|
|
|
2856
3011
|
// src/utils/mfe-port.ts
|
|
2857
|
-
var import_node_path9 = __toESM(require("path"), 1);
|
|
2858
3012
|
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
3013
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
3014
|
+
var MFE_APP_PORT_ENV2 = "MFE_APP_PORT";
|
|
2859
3015
|
function mfePort(packageDir) {
|
|
2860
3016
|
const { name: appName, version } = getPackageJson(packageDir);
|
|
3017
|
+
const portOverride = process.env[MFE_APP_PORT_ENV2];
|
|
3018
|
+
if (portOverride) {
|
|
3019
|
+
const port = Number.parseInt(portOverride, 10);
|
|
3020
|
+
if (!Number.isNaN(port) && port > 0 && port < 65536) {
|
|
3021
|
+
return {
|
|
3022
|
+
name: appName,
|
|
3023
|
+
version,
|
|
3024
|
+
port,
|
|
3025
|
+
overridden: true
|
|
3026
|
+
};
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
2861
3029
|
try {
|
|
2862
3030
|
const result = loadConfig({ packageDir, appName });
|
|
2863
3031
|
const { port } = result;
|
|
@@ -2890,14 +3058,16 @@ function loadConfig({
|
|
|
2890
3058
|
|
|
2891
3059
|
// src/bin/port.ts
|
|
2892
3060
|
function displayPort() {
|
|
3061
|
+
delete process.env.MFE_DEBUG;
|
|
2893
3062
|
const portInfo = mfePort((0, import_node_process.cwd)());
|
|
2894
3063
|
header(portInfo);
|
|
2895
3064
|
logger.info(portInfo.port);
|
|
2896
3065
|
}
|
|
2897
|
-
function header({ name, version, port }) {
|
|
3066
|
+
function header({ name, version, port, overridden }) {
|
|
3067
|
+
const portSource = overridden ? `${port} (override via ${MFE_APP_PORT_ENV2})` : port;
|
|
2898
3068
|
logger.error(`
|
|
2899
3069
|
\u25B2 ${name}@${version}
|
|
2900
|
-
\xB7 setting port to ${
|
|
3070
|
+
\xB7 setting port to ${portSource}
|
|
2901
3071
|
`);
|
|
2902
3072
|
}
|
|
2903
3073
|
|