@vercel/microfrontends 2.0.0-canary.0 → 2.0.0-canary.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 +12 -0
- package/README.md +21 -4
- package/dist/bin/cli.cjs +156 -20
- package/dist/config.cjs +123 -3
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.ts +33 -2
- package/dist/config.js +122 -2
- package/dist/config.js.map +1 -1
- package/dist/experimental/sveltekit.cjs +128 -4
- package/dist/experimental/sveltekit.cjs.map +1 -1
- package/dist/experimental/sveltekit.js +127 -3
- package/dist/experimental/sveltekit.js.map +1 -1
- package/dist/experimental/vite.cjs +128 -4
- package/dist/experimental/vite.cjs.map +1 -1
- package/dist/experimental/vite.js +127 -3
- package/dist/experimental/vite.js.map +1 -1
- package/dist/microfrontends/server.cjs +128 -4
- package/dist/microfrontends/server.cjs.map +1 -1
- package/dist/microfrontends/server.d.ts +4 -3
- package/dist/microfrontends/server.js +127 -3
- package/dist/microfrontends/server.js.map +1 -1
- package/dist/next/config.cjs +131 -131
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.d.ts +5 -0
- package/dist/next/config.js +130 -130
- package/dist/next/config.js.map +1 -1
- package/dist/next/middleware.cjs +125 -105
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +125 -105
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/testing.cjs +126 -6
- package/dist/next/testing.cjs.map +1 -1
- package/dist/next/testing.d.ts +2 -2
- package/dist/next/testing.js +124 -4
- package/dist/next/testing.js.map +1 -1
- package/dist/overrides.d.ts +3 -3
- package/dist/schema.d.ts +2 -2
- package/dist/{types-4299bff1.d.ts → types-88602303.d.ts} +1 -1
- package/dist/{types-0deb756b.d.ts → types-e7523e61.d.ts} +1 -1
- package/dist/utils/mfe-port.cjs +128 -4
- package/dist/utils/mfe-port.cjs.map +1 -1
- package/dist/utils/mfe-port.js +127 -3
- package/dist/utils/mfe-port.js.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/package.json +7 -2
package/dist/next/config.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ type TransformKeys = 'assetPrefix' | 'buildId' | 'draftMode' | 'redirects' | 're
|
|
|
5
5
|
interface WithMicrofrontendsOptions {
|
|
6
6
|
/**
|
|
7
7
|
* Explicitly set the name of the application instead of using the name from the package.json.
|
|
8
|
+
* This option is useful for cases where you are trying to import next.config.js in a different
|
|
9
|
+
* package, such as for the Storybook Next.js integration.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: This option should not be used in most cases. Issues on Vercel may occur
|
|
12
|
+
* if it differs from the project name.
|
|
8
13
|
*/
|
|
9
14
|
appName?: string;
|
|
10
15
|
isProduction?: () => boolean;
|
package/dist/next/config.js
CHANGED
|
@@ -368,8 +368,106 @@ function findConfig({ dir }) {
|
|
|
368
368
|
// src/config/microfrontends-config/isomorphic/index.ts
|
|
369
369
|
import { parse as parse2 } from "jsonc-parser";
|
|
370
370
|
|
|
371
|
+
// src/config/microfrontends-config/client/index.ts
|
|
372
|
+
import { pathToRegexp } from "path-to-regexp";
|
|
373
|
+
var regexpCache = /* @__PURE__ */ new Map();
|
|
374
|
+
var getRegexp = (path6) => {
|
|
375
|
+
const existing = regexpCache.get(path6);
|
|
376
|
+
if (existing) {
|
|
377
|
+
return existing;
|
|
378
|
+
}
|
|
379
|
+
const regexp = pathToRegexp(path6);
|
|
380
|
+
regexpCache.set(path6, regexp);
|
|
381
|
+
return regexp;
|
|
382
|
+
};
|
|
383
|
+
var MicrofrontendConfigClient = class {
|
|
384
|
+
constructor(config, opts) {
|
|
385
|
+
this.pathCache = {};
|
|
386
|
+
this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
|
|
387
|
+
for (const app of Object.values(config.applications)) {
|
|
388
|
+
if (app.routing) {
|
|
389
|
+
if (app.routing.some((match) => match.flag)) {
|
|
390
|
+
this.hasFlaggedPaths = true;
|
|
391
|
+
}
|
|
392
|
+
const newRouting = [];
|
|
393
|
+
const pathsWithoutFlags = [];
|
|
394
|
+
for (const group of app.routing) {
|
|
395
|
+
if (group.flag) {
|
|
396
|
+
if (opts?.removeFlaggedPaths) {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
if (group.group) {
|
|
400
|
+
delete group.group;
|
|
401
|
+
}
|
|
402
|
+
newRouting.push(group);
|
|
403
|
+
} else {
|
|
404
|
+
pathsWithoutFlags.push(...group.paths);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (pathsWithoutFlags.length > 0) {
|
|
408
|
+
newRouting.push({ paths: pathsWithoutFlags });
|
|
409
|
+
}
|
|
410
|
+
app.routing = newRouting;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
this.serialized = config;
|
|
414
|
+
if (this.hasFlaggedPaths) {
|
|
415
|
+
this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
|
|
416
|
+
}
|
|
417
|
+
this.applications = config.applications;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
421
|
+
* Config must be passed in to remain framework agnostic
|
|
422
|
+
*/
|
|
423
|
+
static fromEnv(config) {
|
|
424
|
+
if (!config) {
|
|
425
|
+
throw new Error(
|
|
426
|
+
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
return new MicrofrontendConfigClient(JSON.parse(config));
|
|
430
|
+
}
|
|
431
|
+
isEqual(other) {
|
|
432
|
+
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
433
|
+
}
|
|
434
|
+
getApplicationNameForPath(path6) {
|
|
435
|
+
if (!path6.startsWith("/")) {
|
|
436
|
+
throw new Error(`Path must start with a /`);
|
|
437
|
+
}
|
|
438
|
+
if (this.pathCache[path6]) {
|
|
439
|
+
return this.pathCache[path6];
|
|
440
|
+
}
|
|
441
|
+
const pathname = new URL(path6, "https://example.com").pathname;
|
|
442
|
+
for (const [name, application] of Object.entries(this.applications)) {
|
|
443
|
+
if (application.routing) {
|
|
444
|
+
for (const group of application.routing) {
|
|
445
|
+
for (const childPath of group.paths) {
|
|
446
|
+
const regexp = getRegexp(childPath);
|
|
447
|
+
if (regexp.test(pathname)) {
|
|
448
|
+
this.pathCache[path6] = name;
|
|
449
|
+
return name;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const defaultApplication = Object.entries(this.applications).find(
|
|
456
|
+
([, application]) => application.default
|
|
457
|
+
);
|
|
458
|
+
if (!defaultApplication) {
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
this.pathCache[path6] = defaultApplication[0];
|
|
462
|
+
return defaultApplication[0];
|
|
463
|
+
}
|
|
464
|
+
serialize() {
|
|
465
|
+
return this.serialized;
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
|
|
371
469
|
// src/config/microfrontends-config/isomorphic/validation.ts
|
|
372
|
-
import { pathToRegexp, parse as parsePathRegexp } from "path-to-regexp";
|
|
470
|
+
import { pathToRegexp as pathToRegexp2, parse as parsePathRegexp } from "path-to-regexp";
|
|
373
471
|
var LIST_FORMATTER = new Intl.ListFormat("en", {
|
|
374
472
|
style: "long",
|
|
375
473
|
type: "conjunction"
|
|
@@ -397,7 +495,7 @@ var validateConfigPaths = (applicationConfigsById) => {
|
|
|
397
495
|
} else {
|
|
398
496
|
pathsByApplicationId.set(path6, {
|
|
399
497
|
applications: [id],
|
|
400
|
-
matcher:
|
|
498
|
+
matcher: pathToRegexp2(path6),
|
|
401
499
|
applicationId: id
|
|
402
500
|
});
|
|
403
501
|
}
|
|
@@ -902,6 +1000,28 @@ var MicrofrontendConfigIsomorphic = class {
|
|
|
902
1000
|
getLocalProxyPort() {
|
|
903
1001
|
return this.config.options?.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
|
|
904
1002
|
}
|
|
1003
|
+
toClientConfig(options) {
|
|
1004
|
+
const applications = Object.fromEntries(
|
|
1005
|
+
Object.entries(this.childApplications).map(([name, application]) => [
|
|
1006
|
+
hashApplicationName(name),
|
|
1007
|
+
{
|
|
1008
|
+
default: false,
|
|
1009
|
+
routing: application.routing
|
|
1010
|
+
}
|
|
1011
|
+
])
|
|
1012
|
+
);
|
|
1013
|
+
applications[hashApplicationName(this.defaultApplication.name)] = {
|
|
1014
|
+
default: true
|
|
1015
|
+
};
|
|
1016
|
+
return new MicrofrontendConfigClient(
|
|
1017
|
+
{
|
|
1018
|
+
applications
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
removeFlaggedPaths: options?.removeFlaggedPaths
|
|
1022
|
+
}
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
905
1025
|
/**
|
|
906
1026
|
* Serializes the class back to the Schema type.
|
|
907
1027
|
*
|
|
@@ -1321,6 +1441,7 @@ var MicrofrontendsServer = class {
|
|
|
1321
1441
|
* This can return either a Child or Main configuration.
|
|
1322
1442
|
*/
|
|
1323
1443
|
static infer({
|
|
1444
|
+
appName,
|
|
1324
1445
|
directory,
|
|
1325
1446
|
filePath,
|
|
1326
1447
|
cookies
|
|
@@ -1333,7 +1454,10 @@ var MicrofrontendsServer = class {
|
|
|
1333
1454
|
}
|
|
1334
1455
|
try {
|
|
1335
1456
|
const packageRoot = findPackageRoot(directory);
|
|
1336
|
-
const applicationContext = getApplicationContext({
|
|
1457
|
+
const applicationContext = getApplicationContext({
|
|
1458
|
+
appName,
|
|
1459
|
+
packageRoot
|
|
1460
|
+
});
|
|
1337
1461
|
const maybeConfig = findConfig({ dir: packageRoot });
|
|
1338
1462
|
if (maybeConfig) {
|
|
1339
1463
|
return MicrofrontendsServer.fromFile({
|
|
@@ -1766,128 +1890,6 @@ var transforms = {
|
|
|
1766
1890
|
webpack: transform7
|
|
1767
1891
|
};
|
|
1768
1892
|
|
|
1769
|
-
// src/config/microfrontends-config/client/index.ts
|
|
1770
|
-
import { pathToRegexp as pathToRegexp2 } from "path-to-regexp";
|
|
1771
|
-
var regexpCache = /* @__PURE__ */ new Map();
|
|
1772
|
-
var getRegexp = (path6) => {
|
|
1773
|
-
const existing = regexpCache.get(path6);
|
|
1774
|
-
if (existing) {
|
|
1775
|
-
return existing;
|
|
1776
|
-
}
|
|
1777
|
-
const regexp = pathToRegexp2(path6);
|
|
1778
|
-
regexpCache.set(path6, regexp);
|
|
1779
|
-
return regexp;
|
|
1780
|
-
};
|
|
1781
|
-
var MicrofrontendConfigClient = class {
|
|
1782
|
-
constructor(config, opts) {
|
|
1783
|
-
this.pathCache = {};
|
|
1784
|
-
this.hasFlaggedPaths = config.hasFlaggedPaths ?? false;
|
|
1785
|
-
for (const app of Object.values(config.applications)) {
|
|
1786
|
-
if (app.routing) {
|
|
1787
|
-
if (app.routing.some((match) => match.flag)) {
|
|
1788
|
-
this.hasFlaggedPaths = true;
|
|
1789
|
-
}
|
|
1790
|
-
const newRouting = [];
|
|
1791
|
-
const pathsWithoutFlags = [];
|
|
1792
|
-
for (const group of app.routing) {
|
|
1793
|
-
if (group.flag) {
|
|
1794
|
-
if (opts?.removeFlaggedPaths) {
|
|
1795
|
-
continue;
|
|
1796
|
-
}
|
|
1797
|
-
if (group.group) {
|
|
1798
|
-
delete group.group;
|
|
1799
|
-
}
|
|
1800
|
-
newRouting.push(group);
|
|
1801
|
-
} else {
|
|
1802
|
-
pathsWithoutFlags.push(...group.paths);
|
|
1803
|
-
}
|
|
1804
|
-
}
|
|
1805
|
-
if (pathsWithoutFlags.length > 0) {
|
|
1806
|
-
newRouting.push({ paths: pathsWithoutFlags });
|
|
1807
|
-
}
|
|
1808
|
-
app.routing = newRouting;
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
this.serialized = config;
|
|
1812
|
-
if (this.hasFlaggedPaths) {
|
|
1813
|
-
this.serialized.hasFlaggedPaths = this.hasFlaggedPaths;
|
|
1814
|
-
}
|
|
1815
|
-
this.applications = config.applications;
|
|
1816
|
-
}
|
|
1817
|
-
/**
|
|
1818
|
-
* Create a new `MicrofrontendConfigClient` from a JSON string.
|
|
1819
|
-
* Config must be passed in to remain framework agnostic
|
|
1820
|
-
*/
|
|
1821
|
-
static fromEnv(config) {
|
|
1822
|
-
if (!config) {
|
|
1823
|
-
throw new Error(
|
|
1824
|
-
"Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
|
|
1825
|
-
);
|
|
1826
|
-
}
|
|
1827
|
-
return new MicrofrontendConfigClient(JSON.parse(config));
|
|
1828
|
-
}
|
|
1829
|
-
isEqual(other) {
|
|
1830
|
-
return this === other || JSON.stringify(this.applications) === JSON.stringify(other.applications);
|
|
1831
|
-
}
|
|
1832
|
-
getApplicationNameForPath(path6) {
|
|
1833
|
-
if (!path6.startsWith("/")) {
|
|
1834
|
-
throw new Error(`Path must start with a /`);
|
|
1835
|
-
}
|
|
1836
|
-
if (this.pathCache[path6]) {
|
|
1837
|
-
return this.pathCache[path6];
|
|
1838
|
-
}
|
|
1839
|
-
const pathname = new URL(path6, "https://example.com").pathname;
|
|
1840
|
-
for (const [name, application] of Object.entries(this.applications)) {
|
|
1841
|
-
if (application.routing) {
|
|
1842
|
-
for (const group of application.routing) {
|
|
1843
|
-
for (const childPath of group.paths) {
|
|
1844
|
-
const regexp = getRegexp(childPath);
|
|
1845
|
-
if (regexp.test(pathname)) {
|
|
1846
|
-
this.pathCache[path6] = name;
|
|
1847
|
-
return name;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
const defaultApplication = Object.entries(this.applications).find(
|
|
1854
|
-
([, application]) => application.default
|
|
1855
|
-
);
|
|
1856
|
-
if (!defaultApplication) {
|
|
1857
|
-
return null;
|
|
1858
|
-
}
|
|
1859
|
-
this.pathCache[path6] = defaultApplication[0];
|
|
1860
|
-
return defaultApplication[0];
|
|
1861
|
-
}
|
|
1862
|
-
serialize() {
|
|
1863
|
-
return this.serialized;
|
|
1864
|
-
}
|
|
1865
|
-
};
|
|
1866
|
-
|
|
1867
|
-
// src/config/microfrontends-config/client/from-isomorphic-config.ts
|
|
1868
|
-
function fromIsomorphicConfig(config, options) {
|
|
1869
|
-
const applications = Object.fromEntries(
|
|
1870
|
-
Object.entries(config.childApplications).map(([name, application]) => [
|
|
1871
|
-
hashApplicationName(name),
|
|
1872
|
-
{
|
|
1873
|
-
default: false,
|
|
1874
|
-
routing: application.routing
|
|
1875
|
-
}
|
|
1876
|
-
])
|
|
1877
|
-
);
|
|
1878
|
-
applications[hashApplicationName(config.defaultApplication.name)] = {
|
|
1879
|
-
default: true
|
|
1880
|
-
};
|
|
1881
|
-
return new MicrofrontendConfigClient(
|
|
1882
|
-
{
|
|
1883
|
-
applications
|
|
1884
|
-
},
|
|
1885
|
-
{
|
|
1886
|
-
removeFlaggedPaths: options?.removeFlaggedPaths
|
|
1887
|
-
}
|
|
1888
|
-
);
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
1893
|
// src/next/config/env.ts
|
|
1892
1894
|
function debugEnv(env) {
|
|
1893
1895
|
if (process.env.MFE_DEBUG) {
|
|
@@ -1913,7 +1915,7 @@ function setEnvironment({
|
|
|
1913
1915
|
NEXT_PUBLIC_MFE_CURRENT_APPLICATION: app.name,
|
|
1914
1916
|
NEXT_PUBLIC_MFE_CURRENT_APPLICATION_HASH: hashApplicationName(app.name),
|
|
1915
1917
|
NEXT_PUBLIC_MFE_CLIENT_CONFIG: JSON.stringify(
|
|
1916
|
-
|
|
1918
|
+
microfrontends.config.toClientConfig({
|
|
1917
1919
|
removeFlaggedPaths: true
|
|
1918
1920
|
}).serialize()
|
|
1919
1921
|
),
|
|
@@ -1923,10 +1925,7 @@ function setEnvironment({
|
|
|
1923
1925
|
};
|
|
1924
1926
|
const serverEnvs = {
|
|
1925
1927
|
MFE_CURRENT_APPLICATION: app.name,
|
|
1926
|
-
MFE_CONFIG: JSON.stringify(microfrontends.config.getConfig())
|
|
1927
|
-
MFE_CLIENT_CONFIG_FULL: JSON.stringify(
|
|
1928
|
-
fromIsomorphicConfig(microfrontends.config).serialize()
|
|
1929
|
-
)
|
|
1928
|
+
MFE_CONFIG: JSON.stringify(microfrontends.config.getConfig())
|
|
1930
1929
|
};
|
|
1931
1930
|
const allEnvs = { ...clientEnvs, ...serverEnvs };
|
|
1932
1931
|
for (const [key, value] of Object.entries(allEnvs)) {
|
|
@@ -1951,6 +1950,7 @@ function withMicrofrontends(nextConfig, opts) {
|
|
|
1951
1950
|
}
|
|
1952
1951
|
const { name: fromApp } = getApplicationContext(opts);
|
|
1953
1952
|
const microfrontends = MicrofrontendsServer.infer({
|
|
1953
|
+
appName: fromApp,
|
|
1954
1954
|
filePath: opts?.configPath
|
|
1955
1955
|
});
|
|
1956
1956
|
const app = microfrontends.config.getApplication(fromApp);
|