@module-federation/vite 1.20.2 → 1.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/buildPaths-BkaQHrd2.js +47 -0
- package/lib/index.js +102 -240
- package/lib/pathNormalization-DvgU8LIp.js +119 -0
- package/lib/{ssrEntryLoader-gVPDPAE8.js → ssrEntryLoader-Ccr0zMrr.js} +44 -14
- package/lib/{ssrVmStrategy-B34y11HE.js → ssrVmStrategy-DTJITp2Z.js} +23 -4
- package/lib/utils/injectExternalRuntimeCorePlugin.js +2 -2
- package/lib/utils/ssrEntryLoader.d.ts +4 -5
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +4 -38
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/utils/buildPaths.ts
|
|
2
|
+
/**
|
|
3
|
+
* Rebase an import path for a bootstrap file that moved from root into `dir`.
|
|
4
|
+
*
|
|
5
|
+
* When entryFileNames places entries in a subdirectory (e.g. `static/js/`),
|
|
6
|
+
* the bootstrap file moves there too. Paths that resolved from the HTML root
|
|
7
|
+
* must resolve from the new directory instead.
|
|
8
|
+
*
|
|
9
|
+
* Cases: `/static/js/hostInit.js` → `./hostInit.js` (strip dir prefix)
|
|
10
|
+
* `./src/main.tsx` → `../../src/main.tsx` (climb back up for each dir level)
|
|
11
|
+
* `https://cdn.example.com` → unchanged (absolute URL)
|
|
12
|
+
*/
|
|
13
|
+
function rebaseImport(importSrc, dir) {
|
|
14
|
+
if (!dir) return importSrc;
|
|
15
|
+
if (isAbsoluteUrl(importSrc)) return importSrc;
|
|
16
|
+
const normalizedDir = dir.replace(/^\/+|\/+$/g, "");
|
|
17
|
+
if (!normalizedDir) return importSrc;
|
|
18
|
+
const stripDirPrefix = (src, prefix) => {
|
|
19
|
+
if (src === prefix) return "";
|
|
20
|
+
if (src.startsWith(prefix + "/")) return src.slice(prefix.length);
|
|
21
|
+
};
|
|
22
|
+
const absoluteRemainder = stripDirPrefix(importSrc, "/" + normalizedDir);
|
|
23
|
+
if (absoluteRemainder !== void 0) {
|
|
24
|
+
const remainder = absoluteRemainder.replace(/^\/+/, "");
|
|
25
|
+
return remainder ? "./" + remainder : "./";
|
|
26
|
+
}
|
|
27
|
+
const relativeRemainder = stripDirPrefix(importSrc, normalizedDir);
|
|
28
|
+
if (relativeRemainder !== void 0) {
|
|
29
|
+
const remainder = relativeRemainder.replace(/^\/+/, "");
|
|
30
|
+
return remainder ? "./" + remainder : "./";
|
|
31
|
+
}
|
|
32
|
+
const upLevels = normalizedDir.split("/").filter(Boolean).length;
|
|
33
|
+
const prefix = upLevels > 0 ? "../".repeat(upLevels) : "./";
|
|
34
|
+
if (importSrc.startsWith("./")) return prefix + importSrc.slice(2);
|
|
35
|
+
if (importSrc.startsWith("/")) return prefix + importSrc.slice(1);
|
|
36
|
+
return prefix + importSrc;
|
|
37
|
+
}
|
|
38
|
+
function normalizePathForImport(path) {
|
|
39
|
+
return path.replace(/\\/g, "/");
|
|
40
|
+
}
|
|
41
|
+
const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i;
|
|
42
|
+
function isAbsoluteUrl(src) {
|
|
43
|
+
if (/^[a-z]:[\\/]/i.test(src)) return false;
|
|
44
|
+
return EXTERNAL_URL_RE.test(src);
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { normalizePathForImport as n, rebaseImport as r, EXTERNAL_URL_RE as t };
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { n as normalizePathForImport, r as rebaseImport } from "./buildPaths-BkaQHrd2.js";
|
|
2
|
+
import { a as getCommonSharedSubpaths, c as isNodeModulePath, d as normalizeNodeModulePath, f as resolvePublicPath, i as getCommonSharedSubpathFromNodeModulePath, l as isNuxtClientBase, n as filterId, o as getMatchingNodeModuleSubpath, r as getBasePath$2, s as isAssetLikeImport, t as ensureTrailingSlash, u as isViteOptimizableEntry } from "./pathNormalization-DvgU8LIp.js";
|
|
1
3
|
import { createRequire } from "node:module";
|
|
2
4
|
import * as fs$2 from "fs";
|
|
3
5
|
import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -25,52 +27,6 @@ var __exportAll = (all, no_symbols) => {
|
|
|
25
27
|
return target;
|
|
26
28
|
};
|
|
27
29
|
//#endregion
|
|
28
|
-
//#region src/utils/buildPaths.ts
|
|
29
|
-
/**
|
|
30
|
-
* Rebase an import path for a bootstrap file that moved from root into `dir`.
|
|
31
|
-
*
|
|
32
|
-
* When entryFileNames places entries in a subdirectory (e.g. `static/js/`),
|
|
33
|
-
* the bootstrap file moves there too. Paths that resolved from the HTML root
|
|
34
|
-
* must resolve from the new directory instead.
|
|
35
|
-
*
|
|
36
|
-
* Cases: `/static/js/hostInit.js` → `./hostInit.js` (strip dir prefix)
|
|
37
|
-
* `./src/main.tsx` → `../../src/main.tsx` (climb back up for each dir level)
|
|
38
|
-
* `https://cdn.example.com` → unchanged (absolute URL)
|
|
39
|
-
*/
|
|
40
|
-
function rebaseImport(importSrc, dir) {
|
|
41
|
-
if (!dir) return importSrc;
|
|
42
|
-
if (isAbsoluteUrl(importSrc)) return importSrc;
|
|
43
|
-
const normalizedDir = dir.replace(/^\/+|\/+$/g, "");
|
|
44
|
-
if (!normalizedDir) return importSrc;
|
|
45
|
-
const stripDirPrefix = (src, prefix) => {
|
|
46
|
-
if (src === prefix) return "";
|
|
47
|
-
if (src.startsWith(prefix + "/")) return src.slice(prefix.length);
|
|
48
|
-
};
|
|
49
|
-
const absoluteRemainder = stripDirPrefix(importSrc, "/" + normalizedDir);
|
|
50
|
-
if (absoluteRemainder !== void 0) {
|
|
51
|
-
const remainder = absoluteRemainder.replace(/^\/+/, "");
|
|
52
|
-
return remainder ? "./" + remainder : "./";
|
|
53
|
-
}
|
|
54
|
-
const relativeRemainder = stripDirPrefix(importSrc, normalizedDir);
|
|
55
|
-
if (relativeRemainder !== void 0) {
|
|
56
|
-
const remainder = relativeRemainder.replace(/^\/+/, "");
|
|
57
|
-
return remainder ? "./" + remainder : "./";
|
|
58
|
-
}
|
|
59
|
-
const upLevels = normalizedDir.split("/").filter(Boolean).length;
|
|
60
|
-
const prefix = upLevels > 0 ? "../".repeat(upLevels) : "./";
|
|
61
|
-
if (importSrc.startsWith("./")) return prefix + importSrc.slice(2);
|
|
62
|
-
if (importSrc.startsWith("/")) return prefix + importSrc.slice(1);
|
|
63
|
-
return prefix + importSrc;
|
|
64
|
-
}
|
|
65
|
-
function normalizePathForImport(path) {
|
|
66
|
-
return path.replace(/\\/g, "/");
|
|
67
|
-
}
|
|
68
|
-
const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i;
|
|
69
|
-
function isAbsoluteUrl(src) {
|
|
70
|
-
if (/^[a-z]:[\\/]/i.test(src)) return false;
|
|
71
|
-
return EXTERNAL_URL_RE.test(src);
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
30
|
//#region src/utils/codeRewriter.ts
|
|
75
31
|
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
76
32
|
var CodeRewriter = class {
|
|
@@ -851,124 +807,6 @@ function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || proce
|
|
|
851
807
|
}
|
|
852
808
|
}
|
|
853
809
|
//#endregion
|
|
854
|
-
//#region src/utils/pathNormalization.ts
|
|
855
|
-
const COMMON_SHARED_SUBPATHS = {
|
|
856
|
-
react: [
|
|
857
|
-
"react/jsx-runtime",
|
|
858
|
-
"react/jsx-dev-runtime",
|
|
859
|
-
"react/compiler-runtime"
|
|
860
|
-
],
|
|
861
|
-
"react-dom": [
|
|
862
|
-
"react-dom/client",
|
|
863
|
-
"react-dom/server",
|
|
864
|
-
"react-dom/server.browser"
|
|
865
|
-
],
|
|
866
|
-
"solid-js": [
|
|
867
|
-
"solid-js/web",
|
|
868
|
-
"solid-js/store",
|
|
869
|
-
"solid-js/html",
|
|
870
|
-
"solid-js/h"
|
|
871
|
-
],
|
|
872
|
-
zustand: ["zustand/vanilla", "zustand/react"]
|
|
873
|
-
};
|
|
874
|
-
const VITE_DEFAULT_ASSET_TYPES = [
|
|
875
|
-
"apng",
|
|
876
|
-
"bmp",
|
|
877
|
-
"png",
|
|
878
|
-
"jpe?g",
|
|
879
|
-
"jfif",
|
|
880
|
-
"pjpeg",
|
|
881
|
-
"pjp",
|
|
882
|
-
"gif",
|
|
883
|
-
"svg",
|
|
884
|
-
"ico",
|
|
885
|
-
"webp",
|
|
886
|
-
"avif",
|
|
887
|
-
"cur",
|
|
888
|
-
"jxl",
|
|
889
|
-
"mp4",
|
|
890
|
-
"webm",
|
|
891
|
-
"ogg",
|
|
892
|
-
"mp3",
|
|
893
|
-
"wav",
|
|
894
|
-
"flac",
|
|
895
|
-
"aac",
|
|
896
|
-
"opus",
|
|
897
|
-
"mov",
|
|
898
|
-
"m4a",
|
|
899
|
-
"vtt",
|
|
900
|
-
"woff2?",
|
|
901
|
-
"eot",
|
|
902
|
-
"ttf",
|
|
903
|
-
"otf",
|
|
904
|
-
"webmanifest",
|
|
905
|
-
"pdf",
|
|
906
|
-
"txt"
|
|
907
|
-
];
|
|
908
|
-
const ASSET_LIKE_IMPORT_RE = new RegExp(`\\.(${[...[
|
|
909
|
-
"css",
|
|
910
|
-
"scss",
|
|
911
|
-
"sass",
|
|
912
|
-
"less",
|
|
913
|
-
"styl",
|
|
914
|
-
"stylus"
|
|
915
|
-
], ...VITE_DEFAULT_ASSET_TYPES].join("|")})(?:[?#].*)?$`, "i");
|
|
916
|
-
function isAssetLikeImport(source) {
|
|
917
|
-
return ASSET_LIKE_IMPORT_RE.test(source);
|
|
918
|
-
}
|
|
919
|
-
const VITE_OPTIMIZABLE_ENTRY_RE = /\.[cm]?[jt]s$/;
|
|
920
|
-
function isViteOptimizableEntry(resolvedPath) {
|
|
921
|
-
return VITE_OPTIMIZABLE_ENTRY_RE.test(resolvedPath);
|
|
922
|
-
}
|
|
923
|
-
function removeTrailingSlash(value) {
|
|
924
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
925
|
-
}
|
|
926
|
-
function ensureTrailingSlash(value) {
|
|
927
|
-
return `${removeTrailingSlash(value)}/`;
|
|
928
|
-
}
|
|
929
|
-
function getBasePath$2(base) {
|
|
930
|
-
return removeTrailingSlash(base || "/");
|
|
931
|
-
}
|
|
932
|
-
function isNuxtClientBase(base) {
|
|
933
|
-
return getBasePath$2(base).endsWith("/_nuxt");
|
|
934
|
-
}
|
|
935
|
-
function normalizeNodeModulePath(source) {
|
|
936
|
-
const queryIndex = source.indexOf("?");
|
|
937
|
-
return (queryIndex === -1 ? source : source.slice(0, queryIndex)).replace(/\\/g, "/");
|
|
938
|
-
}
|
|
939
|
-
function isNodeModulePath(source) {
|
|
940
|
-
return source.includes("/node_modules/") || source.includes("\\node_modules\\");
|
|
941
|
-
}
|
|
942
|
-
function filterId(id) {
|
|
943
|
-
return typeof id === "string" && !id.includes("\0");
|
|
944
|
-
}
|
|
945
|
-
function getMatchingNodeModuleSubpath(source, candidates) {
|
|
946
|
-
const normalized = normalizeNodeModulePath(source);
|
|
947
|
-
return [...candidates].sort((a, b) => b.length - a.length).find((candidate) => normalized.includes(`/node_modules/${candidate}/`) || normalized.includes(`/node_modules/${candidate}.`));
|
|
948
|
-
}
|
|
949
|
-
function getCommonSharedSubpaths(sharedKey) {
|
|
950
|
-
return COMMON_SHARED_SUBPATHS[removeTrailingSlash(sharedKey)] || [];
|
|
951
|
-
}
|
|
952
|
-
function getCommonSharedSubpathFromNodeModulePath(source, sharedKey) {
|
|
953
|
-
return getMatchingNodeModuleSubpath(source, getCommonSharedSubpaths(removeTrailingSlash(sharedKey)));
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* Resolves the public path for remote entries
|
|
957
|
-
* @param options - Module Federation options
|
|
958
|
-
* @param viteBase - Vite's base config value
|
|
959
|
-
* @param originalBase - Original base config before any transformations
|
|
960
|
-
* @returns The resolved public path
|
|
961
|
-
*/
|
|
962
|
-
function resolvePublicPath(options, viteBase, originalBase) {
|
|
963
|
-
if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
|
|
964
|
-
if (!originalBase) return "auto";
|
|
965
|
-
if (viteBase) {
|
|
966
|
-
if (viteBase === "./") return "auto";
|
|
967
|
-
return ensureTrailingSlash(viteBase);
|
|
968
|
-
}
|
|
969
|
-
return "auto";
|
|
970
|
-
}
|
|
971
|
-
//#endregion
|
|
972
810
|
//#region src/utils/normalizeModuleFederationOptions.ts
|
|
973
811
|
const INTERNAL_NAME_PREFIX = "__mfe_internal__";
|
|
974
812
|
function toInternalModuleFederationName(name) {
|
|
@@ -1236,6 +1074,7 @@ function normalizeModuleFederationOptions(options) {
|
|
|
1236
1074
|
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
1237
1075
|
varFilename: options.varFilename,
|
|
1238
1076
|
target: options.target,
|
|
1077
|
+
ssrExternals: options.ssrExternals,
|
|
1239
1078
|
disableRemote: options.disableRemote,
|
|
1240
1079
|
disableShared: options.disableShared,
|
|
1241
1080
|
disableSnapshot: options.disableSnapshot,
|
|
@@ -1914,6 +1753,24 @@ ${exportStatement}
|
|
|
1914
1753
|
`);
|
|
1915
1754
|
}
|
|
1916
1755
|
//#endregion
|
|
1756
|
+
//#region src/plugins/pluginReactMixedModeGuard.ts
|
|
1757
|
+
function createReactMixedModeRuntimeGuard() {
|
|
1758
|
+
return `const __mfReactInternals = mod["__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE"];
|
|
1759
|
+
if (__mfReactInternals && "A" in __mfReactInternals) {
|
|
1760
|
+
let __mfReactDispatcher = __mfReactInternals.A;
|
|
1761
|
+
Object.defineProperty(__mfReactInternals, "A", {
|
|
1762
|
+
configurable: true,
|
|
1763
|
+
enumerable: true,
|
|
1764
|
+
get: () => __mfReactDispatcher,
|
|
1765
|
+
set: (next) => {
|
|
1766
|
+
if (next && typeof next.getOwner !== "function") next.getOwner = () => null;
|
|
1767
|
+
__mfReactDispatcher = next;
|
|
1768
|
+
},
|
|
1769
|
+
});
|
|
1770
|
+
__mfReactInternals.A = __mfReactDispatcher;
|
|
1771
|
+
}`;
|
|
1772
|
+
}
|
|
1773
|
+
//#endregion
|
|
1917
1774
|
//#region src/utils/treeShaking.ts
|
|
1918
1775
|
function shouldAnalyzeSharedExports(shareItem) {
|
|
1919
1776
|
return !!(shareItem && (shareItem.shareConfig.treeShaking || shareItem.shareConfig.import === false));
|
|
@@ -2476,32 +2333,55 @@ function resolveReExportModule(filePath, specifier, exportConditions) {
|
|
|
2476
2333
|
return;
|
|
2477
2334
|
}
|
|
2478
2335
|
}
|
|
2479
|
-
|
|
2336
|
+
/** Marks a template-literal frame whose text (not its interpolation) is being scanned. */
|
|
2337
|
+
const TEMPLATE_TEXT = Symbol("templateText");
|
|
2338
|
+
function getAdditionalTopLevelDeclaratorNames(source, start, codePositions) {
|
|
2339
|
+
const names = [];
|
|
2480
2340
|
let depth = 0;
|
|
2481
2341
|
let quote;
|
|
2482
2342
|
let escaped = false;
|
|
2483
2343
|
let canStartRegex = true;
|
|
2344
|
+
const templateFrames = [];
|
|
2345
|
+
const inTemplateText = () => templateFrames[templateFrames.length - 1] === TEMPLATE_TEXT;
|
|
2484
2346
|
for (let index = start; index < source.length; index++) {
|
|
2485
2347
|
const char = source[index];
|
|
2348
|
+
if (inTemplateText()) {
|
|
2349
|
+
if (escaped) escaped = false;
|
|
2350
|
+
else if (char === "\\") escaped = true;
|
|
2351
|
+
else if (char === "$" && source[index + 1] === "{") {
|
|
2352
|
+
templateFrames.push(depth);
|
|
2353
|
+
index++;
|
|
2354
|
+
canStartRegex = true;
|
|
2355
|
+
} else if (char === "`") {
|
|
2356
|
+
templateFrames.pop();
|
|
2357
|
+
canStartRegex = false;
|
|
2358
|
+
}
|
|
2359
|
+
continue;
|
|
2360
|
+
}
|
|
2486
2361
|
if (quote) {
|
|
2487
2362
|
if (escaped) escaped = false;
|
|
2488
2363
|
else if (char === "\\") escaped = true;
|
|
2489
2364
|
else if (char === quote) quote = void 0;
|
|
2490
2365
|
continue;
|
|
2491
2366
|
}
|
|
2492
|
-
if (char === "
|
|
2367
|
+
if (char === "`") {
|
|
2368
|
+
templateFrames.push(TEMPLATE_TEXT);
|
|
2369
|
+
canStartRegex = false;
|
|
2370
|
+
continue;
|
|
2371
|
+
}
|
|
2372
|
+
if (char === "\"" || char === "'") {
|
|
2493
2373
|
quote = char;
|
|
2494
2374
|
canStartRegex = false;
|
|
2495
2375
|
continue;
|
|
2496
2376
|
}
|
|
2497
2377
|
if (char === "/" && source[index + 1] === "/") {
|
|
2498
2378
|
index = source.indexOf("\n", index + 2);
|
|
2499
|
-
if (index === -1) return
|
|
2379
|
+
if (index === -1) return names;
|
|
2500
2380
|
continue;
|
|
2501
2381
|
}
|
|
2502
2382
|
if (char === "/" && source[index + 1] === "*") {
|
|
2503
2383
|
const commentEnd = source.indexOf("*/", index + 2);
|
|
2504
|
-
if (commentEnd === -1) return
|
|
2384
|
+
if (commentEnd === -1) return void 0;
|
|
2505
2385
|
index = commentEnd + 1;
|
|
2506
2386
|
continue;
|
|
2507
2387
|
}
|
|
@@ -2532,9 +2412,9 @@ function hasTopLevelDeclaratorComma(source, start, codePositions) {
|
|
|
2532
2412
|
while (/[$_\p{ID_Continue}]/u.test(source[index + 1] || "")) index++;
|
|
2533
2413
|
break;
|
|
2534
2414
|
}
|
|
2535
|
-
if (regexChar === "\n" || regexChar === "\r") return
|
|
2415
|
+
if (regexChar === "\n" || regexChar === "\r") return void 0;
|
|
2536
2416
|
}
|
|
2537
|
-
if (!closed) return
|
|
2417
|
+
if (!closed) return void 0;
|
|
2538
2418
|
canStartRegex = false;
|
|
2539
2419
|
continue;
|
|
2540
2420
|
}
|
|
@@ -2573,15 +2453,29 @@ function hasTopLevelDeclaratorComma(source, start, codePositions) {
|
|
|
2573
2453
|
continue;
|
|
2574
2454
|
}
|
|
2575
2455
|
if (char === ")" || char === "]" || char === "}") {
|
|
2456
|
+
if (char === "}" && templateFrames.length > 0 && templateFrames[templateFrames.length - 1] === depth) {
|
|
2457
|
+
templateFrames.pop();
|
|
2458
|
+
canStartRegex = false;
|
|
2459
|
+
continue;
|
|
2460
|
+
}
|
|
2576
2461
|
depth = Math.max(0, depth - 1);
|
|
2577
2462
|
canStartRegex = false;
|
|
2578
2463
|
continue;
|
|
2579
2464
|
}
|
|
2580
|
-
if (depth === 0 && char === ",")
|
|
2581
|
-
|
|
2465
|
+
if (templateFrames.length === 0 && depth === 0 && char === ",") {
|
|
2466
|
+
let bindingStart = index + 1;
|
|
2467
|
+
while (/\s/.test(source[bindingStart] || "")) bindingStart++;
|
|
2468
|
+
const binding = source.slice(bindingStart).match(new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u"));
|
|
2469
|
+
if (!binding || !isValidEsmExportName(binding[1])) return void 0;
|
|
2470
|
+
names.push(binding[1]);
|
|
2471
|
+
index = bindingStart + binding[1].length - 1;
|
|
2472
|
+
canStartRegex = false;
|
|
2473
|
+
continue;
|
|
2474
|
+
}
|
|
2475
|
+
if (templateFrames.length === 0 && depth === 0 && char === ";") return names;
|
|
2582
2476
|
if (!/\s/.test(char)) canStartRegex = char !== ".";
|
|
2583
2477
|
}
|
|
2584
|
-
return
|
|
2478
|
+
return names;
|
|
2585
2479
|
}
|
|
2586
2480
|
function hasUnsupportedBindingPattern(source, start) {
|
|
2587
2481
|
const opening = source[start];
|
|
@@ -2624,7 +2518,9 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
2624
2518
|
const exportedVariableDeclarationRegex = /export\s+(?:const|let|var)\s+/g;
|
|
2625
2519
|
while ((match = exportedVariableDeclarationRegex.exec(source)) !== null) {
|
|
2626
2520
|
if (!codePositions[match.index]) continue;
|
|
2627
|
-
|
|
2521
|
+
const additionalNames = getAdditionalTopLevelDeclaratorNames(source, exportedVariableDeclarationRegex.lastIndex, codePositions);
|
|
2522
|
+
if (additionalNames === void 0) scanState.complete = false;
|
|
2523
|
+
else for (const name of additionalNames) names.add(name);
|
|
2628
2524
|
if (hasUnsupportedBindingPattern(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
2629
2525
|
}
|
|
2630
2526
|
if (hasCodeMatch(source, /export\s+import\s+/g, codePositions) || hasCodeMatch(source, /export\s*=/g, codePositions)) scanState.complete = false;
|
|
@@ -3372,12 +3268,13 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3372
3268
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
3373
3269
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
3374
3270
|
const isDefaultShareScope = shareItem.scope === void 0 || shareItem.scope === "default" || Array.isArray(shareItem.scope) && shareItem.scope[0] === "default";
|
|
3375
|
-
const usesDeferredSingletonFallback = hasCompleteExportCoverage && (
|
|
3271
|
+
const usesDeferredSingletonFallback = hasCompleteExportCoverage && (isWorkspacePackage || command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer(resolvedOptions) && (shareItem.shareConfig.singleton === true ? !isDefaultShareScope : isDefaultShareScope));
|
|
3376
3272
|
const servesRemoteSingletonFallback = command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true;
|
|
3377
3273
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg, resolvedOptions);
|
|
3378
3274
|
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true && resolvedOptions.hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
|
|
3379
|
-
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && isConsumedByPeerSingleton;
|
|
3275
|
+
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && (isConsumedByPeerSingleton || shareItem.shareConfig.eager === true);
|
|
3380
3276
|
const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
|
|
3277
|
+
const reactMixedModeGuard = pkg === "react" ? createReactMixedModeRuntimeGuard() : "";
|
|
3381
3278
|
let exportLine;
|
|
3382
3279
|
let initBlock = "";
|
|
3383
3280
|
if (usesDeferredTreeShakingFallback) {
|
|
@@ -3403,13 +3300,17 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3403
3300
|
const namedExportVars = copiedNamedExports.map((_name, i) => `__mf_${i}`);
|
|
3404
3301
|
exportLine = `${["let __mfDefaultExport;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
|
|
3405
3302
|
const __mfApplySharedExports = (mod) => {
|
|
3406
|
-
${[
|
|
3303
|
+
${[
|
|
3304
|
+
...reactMixedModeGuard ? [reactMixedModeGuard] : [],
|
|
3305
|
+
...copiedNamedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`),
|
|
3306
|
+
`__mfDefaultExport = (() => {
|
|
3407
3307
|
${generateShareModuleUnwrapCode({
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
})();`
|
|
3308
|
+
source: "mod",
|
|
3309
|
+
preserveNamedExports: false,
|
|
3310
|
+
stopWithReturn: "defaultExport ?? current"
|
|
3311
|
+
})}
|
|
3312
|
+
})();`
|
|
3313
|
+
].join("\n ")}
|
|
3413
3314
|
};
|
|
3414
3315
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedExports);
|
|
3415
3316
|
__mfApplySharedExports(exportModule);
|
|
@@ -3437,6 +3338,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3437
3338
|
} else if (shareItem.shareConfig.singleton === true) {
|
|
3438
3339
|
exportLine = `let __mfDefaultExport;
|
|
3439
3340
|
const __mfApplySharedDefaultExport = (mod) => {
|
|
3341
|
+
${reactMixedModeGuard}
|
|
3440
3342
|
__mfDefaultExport = mod.default ?? mod;
|
|
3441
3343
|
};
|
|
3442
3344
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedDefaultExport);
|
|
@@ -3979,7 +3881,6 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy) {
|
|
|
3979
3881
|
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
|
|
3980
3882
|
if (cachedShare !== undefined) return false;
|
|
3981
3883
|
if (share.treeShaking || share.shareConfig?.import === false) return true;
|
|
3982
|
-
if (!share.shareConfig?.singleton) return false;
|
|
3983
3884
|
if (typeof __mfSelectExternalSharedProvider !== 'function') return false;
|
|
3984
3885
|
return Boolean(__mfSelectExternalSharedProvider(
|
|
3985
3886
|
initialShared[pkg],
|
|
@@ -4193,7 +4094,6 @@ function generateTreeShakingSnapshotPluginCode(enabled) {
|
|
|
4193
4094
|
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build") {
|
|
4194
4095
|
const needsSharedProviderSelectionHelper = Object.keys(options.shared ?? {}).length > 0;
|
|
4195
4096
|
const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
4196
|
-
const hasEagerShared = Object.values(options.shared ?? {}).some((share) => share?.shareConfig.eager === true && share.shareConfig.import !== false);
|
|
4197
4097
|
const hasMultipleShareScopes = Array.isArray(options.shareScope);
|
|
4198
4098
|
const runtimeImports = [
|
|
4199
4099
|
"init as runtimeInit",
|
|
@@ -4246,7 +4146,6 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4246
4146
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
4247
4147
|
}
|
|
4248
4148
|
import {${runtimeImports}} from "@module-federation/runtime";
|
|
4249
|
-
${hasEagerShared ? `import * as __mfLocalSharedImportMap from "${getLocalSharedImportMapPath(options)}";` : ""}
|
|
4250
4149
|
${runtimeHelperImports.length ? `import {${runtimeHelperImports.join(", ")}} from "@module-federation/runtime/helpers";` : ""}
|
|
4251
4150
|
${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => item[1]).join("\n")}
|
|
4252
4151
|
${command === "build" ? getRuntimeInitResolveBootstrapCode(false, options ? getRuntimeInitStatusImportId(options) : void 0) : getRuntimeInitBootstrapCode(false, options ? getRuntimeInitStatusImportId(options) : void 0) + "\n const { initResolve } = globalThis[globalKey];"}
|
|
@@ -4281,12 +4180,11 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4281
4180
|
${needsSharedProviderSelectionHelper ? externalSharedProviderSelectionHelperCode : ""}
|
|
4282
4181
|
|
|
4283
4182
|
async function getLocalSharedImportMap() {
|
|
4284
|
-
|
|
4285
|
-
${hasEagerShared ? "" : `if (!localSharedImportMapPromise) {
|
|
4183
|
+
if (!localSharedImportMapPromise) {
|
|
4286
4184
|
localSharedImportMapPromise = retrySharedInit(() => import("${getLocalSharedImportMapPath(options)}"))
|
|
4287
4185
|
.catch((e) => { localSharedImportMapPromise = undefined; throw e; });
|
|
4288
4186
|
}
|
|
4289
|
-
return localSharedImportMapPromise
|
|
4187
|
+
return localSharedImportMapPromise
|
|
4290
4188
|
}
|
|
4291
4189
|
|
|
4292
4190
|
async function getExposesMap() {
|
|
@@ -4721,6 +4619,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4721
4619
|
if (!providerEntry) return;
|
|
4722
4620
|
const selectedLocalProvider = __mfMatchesSharedProvider(selectedRuntimeProvider, usedShare);
|
|
4723
4621
|
const { version } = providerEntry;
|
|
4622
|
+
if (!usedShare.shareConfig?.singleton && version !== usedShare.version) return;
|
|
4724
4623
|
const passedProvider = passedVersionMap?.[version];
|
|
4725
4624
|
const resolvedExternalProvider = __mfResolveExternalSharedProvider(
|
|
4726
4625
|
federationInstances,
|
|
@@ -4738,10 +4637,6 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4738
4637
|
provider: selectedRuntimeProvider,
|
|
4739
4638
|
scopeRootProvider: undefined
|
|
4740
4639
|
};
|
|
4741
|
-
// Non-singleton proxies may have already snapshotted their local exports while
|
|
4742
|
-
// seeding shared dependencies. Late cache replacement is safe only for the
|
|
4743
|
-
// live-bound singleton proxies.
|
|
4744
|
-
if (!usedShare.shareConfig?.singleton) return;
|
|
4745
4640
|
if (usedShare.canLiveRebind === false) return;
|
|
4746
4641
|
// Preserve a singleton already selected by another container. The bridge may
|
|
4747
4642
|
// only replace the provisional local fallback seeded by this container.
|
|
@@ -8004,6 +7899,11 @@ function resolveDevHashEntryFileName(fileName) {
|
|
|
8004
7899
|
const baseName = path$1.basename(normalized);
|
|
8005
7900
|
return path$1.extname(baseName) ? normalized : `${normalized}.js`;
|
|
8006
7901
|
}
|
|
7902
|
+
function resolveAbsoluteDevRemoteEntryUrl(publicPath, fileName) {
|
|
7903
|
+
const base = new URL(publicPath);
|
|
7904
|
+
base.pathname = ensureTrailingSlash(base.pathname);
|
|
7905
|
+
return new URL(fileName, base).href;
|
|
7906
|
+
}
|
|
8007
7907
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId, getParsePromise = () => Promise.resolve() }) {
|
|
8008
7908
|
let viteConfig, _command, root, originalConfigBase;
|
|
8009
7909
|
let exposeRemoteDependencies = {};
|
|
@@ -8133,12 +8033,15 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8133
8033
|
if (_command === "serve") {
|
|
8134
8034
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
8135
8035
|
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base, originalConfigBase);
|
|
8136
|
-
const
|
|
8036
|
+
const devPublicPath = resolvedPublicPath === "auto" ? "/" : resolvedPublicPath;
|
|
8037
|
+
const remoteEntryFileName = resolveDevHashEntryFileName(options.filename);
|
|
8038
|
+
const isAbsolutePublicPath = /^https?:\/\//i.test(devPublicPath);
|
|
8039
|
+
const remoteEntryUrl = JSON.stringify(isAbsolutePublicPath ? resolveAbsoluteDevRemoteEntryUrl(devPublicPath, remoteEntryFileName) : `${ensureTrailingSlash(devPublicPath)}${remoteEntryFileName}`);
|
|
8137
8040
|
const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
|
|
8138
8041
|
const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
|
|
8139
8042
|
return `
|
|
8140
8043
|
const origin = typeof window !== 'undefined' && (${!options.ignoreOrigin}) ? window.origin : ${JSON.stringify(fallbackOrigin)};
|
|
8141
|
-
const remoteEntryImport = typeof window !== 'undefined' ? origin + ${
|
|
8044
|
+
const remoteEntryImport = typeof window !== 'undefined' ? ${isAbsolutePublicPath ? remoteEntryUrl : `origin + ${remoteEntryUrl}`} : ${JSON.stringify(ssrRemoteEntry)};
|
|
8142
8045
|
${generateHostAutoInitCode("remoteEntryImport", "serve", options)}
|
|
8143
8046
|
`;
|
|
8144
8047
|
}
|
|
@@ -8281,41 +8184,6 @@ function pluginProxyRemotes_default(options) {
|
|
|
8281
8184
|
};
|
|
8282
8185
|
}
|
|
8283
8186
|
//#endregion
|
|
8284
|
-
//#region src/plugins/pluginReactMixedModeGuard.ts
|
|
8285
|
-
const REACT_DEVELOPMENT_RUNTIME = /[\\/]react[\\/]cjs[\\/]react(?:-jsx-(?:dev-)?runtime)?\.development\.js$/;
|
|
8286
|
-
const UNSAFE_GET_OWNER = "return null === dispatcher ? null : dispatcher.getOwner();";
|
|
8287
|
-
const SAFE_GET_OWNER = "return typeof dispatcher?.getOwner === \"function\" ? dispatcher.getOwner() : null;";
|
|
8288
|
-
const REACT_MIXED_MODE_ROLLDOWN_PLUGIN = "module-federation:react-mixed-mode-rolldown";
|
|
8289
|
-
const REACT_MIXED_MODE_ESBUILD_PLUGIN = "module-federation:react-mixed-mode-esbuild";
|
|
8290
|
-
function patchReactDevelopmentRuntime(code, id) {
|
|
8291
|
-
if (!REACT_DEVELOPMENT_RUNTIME.test(id)) return;
|
|
8292
|
-
const patched = code.replaceAll(UNSAFE_GET_OWNER, SAFE_GET_OWNER);
|
|
8293
|
-
return patched === code ? void 0 : patched;
|
|
8294
|
-
}
|
|
8295
|
-
function createRolldownReactMixedModeGuard() {
|
|
8296
|
-
return {
|
|
8297
|
-
name: REACT_MIXED_MODE_ROLLDOWN_PLUGIN,
|
|
8298
|
-
transform(code, id) {
|
|
8299
|
-
return patchReactDevelopmentRuntime(code, id);
|
|
8300
|
-
}
|
|
8301
|
-
};
|
|
8302
|
-
}
|
|
8303
|
-
function createEsbuildReactMixedModeGuard() {
|
|
8304
|
-
return {
|
|
8305
|
-
name: REACT_MIXED_MODE_ESBUILD_PLUGIN,
|
|
8306
|
-
setup(build) {
|
|
8307
|
-
build.onLoad({ filter: REACT_DEVELOPMENT_RUNTIME }, (args) => {
|
|
8308
|
-
const patched = patchReactDevelopmentRuntime(readFileSync$1(args.path, "utf8"), args.path);
|
|
8309
|
-
if (patched === void 0) return;
|
|
8310
|
-
return {
|
|
8311
|
-
contents: patched,
|
|
8312
|
-
loader: "js"
|
|
8313
|
-
};
|
|
8314
|
-
});
|
|
8315
|
-
}
|
|
8316
|
-
};
|
|
8317
|
-
}
|
|
8318
|
-
//#endregion
|
|
8319
8187
|
//#region src/utils/PromiseStore.ts
|
|
8320
8188
|
/**
|
|
8321
8189
|
* example:
|
|
@@ -9242,12 +9110,8 @@ function pluginSSRRemoteEntry(options) {
|
|
|
9242
9110
|
ssrOutputFilename = getSsrRemoteEntryFileName(options.filename);
|
|
9243
9111
|
const environmentName = this.environment?.name;
|
|
9244
9112
|
const hasSsrEnvironment = Boolean(viteConfig?.environments?.ssr);
|
|
9245
|
-
const isLegacySsrBuild = Boolean(this.environment?.config?.build?.ssr);
|
|
9246
|
-
if (hasSsrEnvironment)
|
|
9247
|
-
if (isNuxtProject) {
|
|
9248
|
-
if (environmentName === "ssr") return;
|
|
9249
|
-
} else if (environmentName !== "ssr") return;
|
|
9250
|
-
} else if (isLegacySsrBuild) {} else if (environmentName && environmentName !== "client") return;
|
|
9113
|
+
const isLegacySsrBuild = Boolean(this.environment?.config?.build?.ssr ?? viteConfig?.build?.ssr);
|
|
9114
|
+
if (hasSsrEnvironment && environmentName !== "ssr" || !hasSsrEnvironment && !isLegacySsrBuild) return;
|
|
9251
9115
|
if (Object.keys(options.exposes).length === 0) return;
|
|
9252
9116
|
if (isRolldown) this.emitFile({
|
|
9253
9117
|
type: "chunk",
|
|
@@ -9481,7 +9345,7 @@ function stripEmptyPreloadCalls(code) {
|
|
|
9481
9345
|
}
|
|
9482
9346
|
nextCode = nextCode.replace(/import\s*["'][^"']*__loadShare__[^"']*["']\s*;?/g, "");
|
|
9483
9347
|
nextCode = nextCode.replace(helperImportRegex, (statement, local) => {
|
|
9484
|
-
return new RegExp(`\\b${local}\\
|
|
9348
|
+
return new RegExp(`\\b${local}\\b`).test(nextCode.replace(statement, "")) ? statement : "";
|
|
9485
9349
|
});
|
|
9486
9350
|
return nextCode;
|
|
9487
9351
|
}
|
|
@@ -9787,7 +9651,6 @@ function includeLinkedSharedEntries(optimizeDeps, shared, projectRoot, exposes,
|
|
|
9787
9651
|
function createEarlyVirtualModulesPlugin(options) {
|
|
9788
9652
|
const { shared, remotes } = options;
|
|
9789
9653
|
const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
|
|
9790
|
-
const shouldGuardReactMixedMode = Object.keys(remotes ?? {}).length > 0 && shared?.react?.shareConfig.singleton === true;
|
|
9791
9654
|
return {
|
|
9792
9655
|
name: "vite:module-federation-early-init",
|
|
9793
9656
|
enforce: "pre",
|
|
@@ -9815,7 +9678,6 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
9815
9678
|
if (isRolldown) {
|
|
9816
9679
|
optimizeDeps.rolldownOptions ??= {};
|
|
9817
9680
|
optimizeDeps.rolldownOptions.plugins ??= [];
|
|
9818
|
-
if (shouldGuardReactMixedMode) optimizeDeps.rolldownOptions.plugins.push(createRolldownReactMixedModeGuard());
|
|
9819
9681
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
9820
9682
|
name: "module-federation:optimize-shared-resolver",
|
|
9821
9683
|
load(id) {
|
|
@@ -9860,7 +9722,6 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
9860
9722
|
} else {
|
|
9861
9723
|
optimizeDeps.esbuildOptions ??= {};
|
|
9862
9724
|
optimizeDeps.esbuildOptions.plugins ??= [];
|
|
9863
|
-
if (shouldGuardReactMixedMode) optimizeDeps.esbuildOptions.plugins.push(createEsbuildReactMixedModeGuard());
|
|
9864
9725
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
9865
9726
|
name: "module-federation:optimize-shared-proxy",
|
|
9866
9727
|
setup(build) {
|
|
@@ -9935,7 +9796,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
9935
9796
|
else optimizeDeps.include.push(key);
|
|
9936
9797
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
9937
9798
|
const canResolveSubpath = canResolveSharedSubpath(subpath, root);
|
|
9938
|
-
if (
|
|
9799
|
+
if (["react/compiler-runtime", "react-dom/client"].includes(subpath) && !canResolveSubpath) {
|
|
9939
9800
|
optimizeDeps.exclude.push(subpath);
|
|
9940
9801
|
continue;
|
|
9941
9802
|
}
|
|
@@ -10289,6 +10150,7 @@ function federation(mfUserOptions) {
|
|
|
10289
10150
|
patchedManualChunks.add(mfChunkName);
|
|
10290
10151
|
if (!useCodeSplitting) {
|
|
10291
10152
|
const mfManualChunks = function(id) {
|
|
10153
|
+
if (PRELOAD_HELPER_TEST.test(id)) return PRELOAD_HELPER_CHUNK;
|
|
10292
10154
|
return mfChunkName(id) ?? void 0;
|
|
10293
10155
|
};
|
|
10294
10156
|
patchedManualChunks.add(mfManualChunks);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
//#region src/utils/pathNormalization.ts
|
|
2
|
+
const COMMON_SHARED_SUBPATHS = {
|
|
3
|
+
react: [
|
|
4
|
+
"react/jsx-runtime",
|
|
5
|
+
"react/jsx-dev-runtime",
|
|
6
|
+
"react/compiler-runtime"
|
|
7
|
+
],
|
|
8
|
+
"react-dom": [
|
|
9
|
+
"react-dom/client",
|
|
10
|
+
"react-dom/server",
|
|
11
|
+
"react-dom/server.browser"
|
|
12
|
+
],
|
|
13
|
+
"solid-js": [
|
|
14
|
+
"solid-js/web",
|
|
15
|
+
"solid-js/store",
|
|
16
|
+
"solid-js/html",
|
|
17
|
+
"solid-js/h"
|
|
18
|
+
],
|
|
19
|
+
zustand: ["zustand/vanilla", "zustand/react"]
|
|
20
|
+
};
|
|
21
|
+
const VITE_DEFAULT_ASSET_TYPES = [
|
|
22
|
+
"apng",
|
|
23
|
+
"bmp",
|
|
24
|
+
"png",
|
|
25
|
+
"jpe?g",
|
|
26
|
+
"jfif",
|
|
27
|
+
"pjpeg",
|
|
28
|
+
"pjp",
|
|
29
|
+
"gif",
|
|
30
|
+
"svg",
|
|
31
|
+
"ico",
|
|
32
|
+
"webp",
|
|
33
|
+
"avif",
|
|
34
|
+
"cur",
|
|
35
|
+
"jxl",
|
|
36
|
+
"mp4",
|
|
37
|
+
"webm",
|
|
38
|
+
"ogg",
|
|
39
|
+
"mp3",
|
|
40
|
+
"wav",
|
|
41
|
+
"flac",
|
|
42
|
+
"aac",
|
|
43
|
+
"opus",
|
|
44
|
+
"mov",
|
|
45
|
+
"m4a",
|
|
46
|
+
"vtt",
|
|
47
|
+
"woff2?",
|
|
48
|
+
"eot",
|
|
49
|
+
"ttf",
|
|
50
|
+
"otf",
|
|
51
|
+
"webmanifest",
|
|
52
|
+
"pdf",
|
|
53
|
+
"txt"
|
|
54
|
+
];
|
|
55
|
+
const ASSET_LIKE_IMPORT_RE = new RegExp(`\\.(${[...[
|
|
56
|
+
"css",
|
|
57
|
+
"scss",
|
|
58
|
+
"sass",
|
|
59
|
+
"less",
|
|
60
|
+
"styl",
|
|
61
|
+
"stylus"
|
|
62
|
+
], ...VITE_DEFAULT_ASSET_TYPES].join("|")})(?:[?#].*)?$`, "i");
|
|
63
|
+
function isAssetLikeImport(source) {
|
|
64
|
+
return ASSET_LIKE_IMPORT_RE.test(source);
|
|
65
|
+
}
|
|
66
|
+
const VITE_OPTIMIZABLE_ENTRY_RE = /\.[cm]?[jt]s$/;
|
|
67
|
+
function isViteOptimizableEntry(resolvedPath) {
|
|
68
|
+
return VITE_OPTIMIZABLE_ENTRY_RE.test(resolvedPath);
|
|
69
|
+
}
|
|
70
|
+
function removeTrailingSlash(value) {
|
|
71
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
72
|
+
}
|
|
73
|
+
function ensureTrailingSlash(value) {
|
|
74
|
+
return `${removeTrailingSlash(value)}/`;
|
|
75
|
+
}
|
|
76
|
+
function getBasePath(base) {
|
|
77
|
+
return removeTrailingSlash(base || "/");
|
|
78
|
+
}
|
|
79
|
+
function isNuxtClientBase(base) {
|
|
80
|
+
return getBasePath(base).endsWith("/_nuxt");
|
|
81
|
+
}
|
|
82
|
+
function normalizeNodeModulePath(source) {
|
|
83
|
+
const queryIndex = source.indexOf("?");
|
|
84
|
+
return (queryIndex === -1 ? source : source.slice(0, queryIndex)).replace(/\\/g, "/");
|
|
85
|
+
}
|
|
86
|
+
function isNodeModulePath(source) {
|
|
87
|
+
return source.includes("/node_modules/") || source.includes("\\node_modules\\");
|
|
88
|
+
}
|
|
89
|
+
function filterId(id) {
|
|
90
|
+
return typeof id === "string" && !id.includes("\0");
|
|
91
|
+
}
|
|
92
|
+
function getMatchingNodeModuleSubpath(source, candidates) {
|
|
93
|
+
const normalized = normalizeNodeModulePath(source);
|
|
94
|
+
return [...candidates].sort((a, b) => b.length - a.length).find((candidate) => normalized.includes(`/node_modules/${candidate}/`) || normalized.includes(`/node_modules/${candidate}.`));
|
|
95
|
+
}
|
|
96
|
+
function getCommonSharedSubpaths(sharedKey) {
|
|
97
|
+
return COMMON_SHARED_SUBPATHS[removeTrailingSlash(sharedKey)] || [];
|
|
98
|
+
}
|
|
99
|
+
function getCommonSharedSubpathFromNodeModulePath(source, sharedKey) {
|
|
100
|
+
return getMatchingNodeModuleSubpath(source, getCommonSharedSubpaths(removeTrailingSlash(sharedKey)));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolves the public path for remote entries
|
|
104
|
+
* @param options - Module Federation options
|
|
105
|
+
* @param viteBase - Vite's base config value
|
|
106
|
+
* @param originalBase - Original base config before any transformations
|
|
107
|
+
* @returns The resolved public path
|
|
108
|
+
*/
|
|
109
|
+
function resolvePublicPath(options, viteBase, originalBase) {
|
|
110
|
+
if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
|
|
111
|
+
if (!originalBase) return "auto";
|
|
112
|
+
if (viteBase) {
|
|
113
|
+
if (viteBase === "./") return "auto";
|
|
114
|
+
return ensureTrailingSlash(viteBase);
|
|
115
|
+
}
|
|
116
|
+
return "auto";
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { getCommonSharedSubpaths as a, isNodeModulePath as c, normalizeNodeModulePath as d, resolvePublicPath as f, getCommonSharedSubpathFromNodeModulePath as i, isNuxtClientBase as l, filterId as n, getMatchingNodeModuleSubpath as o, getBasePath as r, isAssetLikeImport as s, ensureTrailingSlash as t, isViteOptimizableEntry as u };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as EXTERNAL_URL_RE } from "./buildPaths-BkaQHrd2.js";
|
|
1
2
|
//#region src/utils/fetchWithTimeout.ts
|
|
2
3
|
const DEFAULT_SSR_FETCH_TIMEOUT_MS = 1e4;
|
|
3
4
|
const DEFAULT_SSR_FETCH_MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -116,11 +117,10 @@ async function readResponseTextBounded(res, maxBytes = DEFAULT_SSR_FETCH_MAX_BYT
|
|
|
116
117
|
* module source through Vite's plugin pipeline, avoiding serialisation which
|
|
117
118
|
* cannot faithfully represent React components or closures.
|
|
118
119
|
*
|
|
119
|
-
* Dev mode on Vite < 8 is NOT supported
|
|
120
|
-
* `
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* from `pluginSSRRemoteEntry.configureServer`.
|
|
120
|
+
* Dev mode on Vite < 8 is NOT supported by this integration because the
|
|
121
|
+
* cross-process `fetchModule` proxy uses Vite 8's environment APIs.
|
|
122
|
+
* `ModuleRunner` itself is available in earlier Vite versions, but an older
|
|
123
|
+
* remote needs a different transport and server endpoint.
|
|
124
124
|
*
|
|
125
125
|
* Exported as a plain factory function so it can be serialised into the
|
|
126
126
|
* generated runtimePlugins list in virtualRemotes.ts.
|
|
@@ -135,9 +135,12 @@ async function nodeImport(id) {
|
|
|
135
135
|
}
|
|
136
136
|
const isNodeServer = () => typeof globalThis.process?.versions?.node === "string";
|
|
137
137
|
const runnerCache = /* @__PURE__ */ new Map();
|
|
138
|
+
function getSortedRecordEntries(record) {
|
|
139
|
+
return Object.entries(record).sort(([left], [right]) => left.localeCompare(right));
|
|
140
|
+
}
|
|
138
141
|
/**
|
|
139
|
-
* Load `vite/module-runner`. Returns null
|
|
140
|
-
*
|
|
142
|
+
* Load `vite/module-runner`. Returns null when the installed Vite does not
|
|
143
|
+
* expose the module-runner entry point.
|
|
141
144
|
*/
|
|
142
145
|
async function getModuleRunnerModule() {
|
|
143
146
|
const moduleRunnerId = ["vite", "module-runner"].join("/");
|
|
@@ -156,11 +159,33 @@ async function getModuleRunnerModule() {
|
|
|
156
159
|
* `/__mf_runner__` endpoint. Each HTTP POST carries a `fetchModule` invoke
|
|
157
160
|
* payload; the remote responds with the transformed module source as JSON.
|
|
158
161
|
*
|
|
159
|
-
*
|
|
160
|
-
* the `/__mf_runner__` proxy
|
|
162
|
+
* The cross-process transport is Vite 8+ only because older versions do not
|
|
163
|
+
* expose the `/__mf_runner__` environment proxy used here.
|
|
161
164
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
function getRunnerCacheKey(remoteOrigin, resolvedShared, fetchTimeoutMs, fetchMaxBytes) {
|
|
166
|
+
return JSON.stringify([
|
|
167
|
+
remoteOrigin,
|
|
168
|
+
fetchTimeoutMs,
|
|
169
|
+
fetchMaxBytes,
|
|
170
|
+
getSortedRecordEntries(resolvedShared)
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
async function resolveSharedExternal(id, resolvedShared) {
|
|
174
|
+
if (typeof id !== "string") return null;
|
|
175
|
+
const resolved = resolvedShared[id];
|
|
176
|
+
if (!resolved) return null;
|
|
177
|
+
if (EXTERNAL_URL_RE.test(resolved)) return {
|
|
178
|
+
externalize: resolved,
|
|
179
|
+
type: "module"
|
|
180
|
+
};
|
|
181
|
+
const { pathToFileURL } = await _url();
|
|
182
|
+
return {
|
|
183
|
+
externalize: pathToFileURL(resolved).href,
|
|
184
|
+
type: "module"
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async function getOrCreateRunner(remoteOrigin, resolvedShared, fetchTimeoutMs, fetchMaxBytes) {
|
|
188
|
+
const cacheKey = getRunnerCacheKey(remoteOrigin, resolvedShared, fetchTimeoutMs, fetchMaxBytes);
|
|
164
189
|
if (runnerCache.has(cacheKey)) return runnerCache.get(cacheKey);
|
|
165
190
|
const promise = (async () => {
|
|
166
191
|
const viteRunner = await getModuleRunnerModule();
|
|
@@ -171,6 +196,10 @@ async function getOrCreateRunner(remoteOrigin, fetchTimeoutMs, fetchMaxBytes) {
|
|
|
171
196
|
return new ModuleRunner({
|
|
172
197
|
hmr: false,
|
|
173
198
|
transport: { async invoke(payload) {
|
|
199
|
+
if (payload.data.name === "fetchModule") {
|
|
200
|
+
const sharedExternal = await resolveSharedExternal(payload.data.data[0], resolvedShared);
|
|
201
|
+
if (sharedExternal) return { result: sharedExternal };
|
|
202
|
+
}
|
|
174
203
|
const text = await readResponseTextBounded(await fetchWithTimeout(runnerEndpoint, {
|
|
175
204
|
method: "POST",
|
|
176
205
|
headers: { "Content-Type": "application/json" },
|
|
@@ -190,6 +219,7 @@ const _path = () => nodeImport("path");
|
|
|
190
219
|
const _fs = () => nodeImport("fs");
|
|
191
220
|
const _crypto = () => nodeImport("crypto");
|
|
192
221
|
const _module = () => nodeImport("module");
|
|
222
|
+
const _url = () => nodeImport("url");
|
|
193
223
|
/**
|
|
194
224
|
* Version key for a resolved SSR entry. Derived from the remote's manifest
|
|
195
225
|
* content so a redeploy at the same URL produces a different key, which in
|
|
@@ -449,7 +479,7 @@ function revalidate(remoteEntryUrl) {
|
|
|
449
479
|
const tempFileCache = /* @__PURE__ */ new Map();
|
|
450
480
|
const tempFilePathCache = /* @__PURE__ */ new Map();
|
|
451
481
|
function getSsrTransformContextKey(resolvedShared, shareScopeName) {
|
|
452
|
-
return JSON.stringify([shareScopeName,
|
|
482
|
+
return JSON.stringify([shareScopeName, getSortedRecordEntries(resolvedShared)]);
|
|
453
483
|
}
|
|
454
484
|
let ssrCacheDirPromise;
|
|
455
485
|
async function getSSRCacheDir() {
|
|
@@ -573,7 +603,7 @@ async function importTempModule(filePath, versionKey) {
|
|
|
573
603
|
}
|
|
574
604
|
let warnedVmUnavailable = false;
|
|
575
605
|
async function tryVmStrategy(ssrEntry, options) {
|
|
576
|
-
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-
|
|
606
|
+
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-DTJITp2Z.js");
|
|
577
607
|
if (!await isVmStrategyAvailable()) {
|
|
578
608
|
if (!warnedVmUnavailable) {
|
|
579
609
|
warnedVmUnavailable = true;
|
|
@@ -605,7 +635,7 @@ async function loadSSRRemoteEntry(ssrEntry, options) {
|
|
|
605
635
|
const urlObj = new URL(url);
|
|
606
636
|
if (urlObj.pathname.includes("/__mf_ssr__/")) {
|
|
607
637
|
const remoteOrigin = urlObj.origin;
|
|
608
|
-
const runner = await getOrCreateRunner(remoteOrigin, options.fetchTimeoutMs, options.fetchMaxBytes);
|
|
638
|
+
const runner = await getOrCreateRunner(remoteOrigin, resolvedShared, options.fetchTimeoutMs, options.fetchMaxBytes);
|
|
609
639
|
if (!runner) {
|
|
610
640
|
if (process.env.NODE_ENV !== "production") return null;
|
|
611
641
|
} else try {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as getCommonSharedSubpaths } from "./pathNormalization-DvgU8LIp.js";
|
|
2
|
+
import { c as readResponseTextBounded, n as neutralizeBrowserPreloadHelpers, s as fetchWithTimeout, t as SsrEntryHttpError } from "./ssrEntryLoader-Ccr0zMrr.js";
|
|
2
3
|
//#region src/utils/ssrVmStrategy.ts
|
|
3
4
|
/**
|
|
4
5
|
* vm.SourceTextModule strategy for loading remote SSR entries.
|
|
@@ -39,6 +40,22 @@ async function getVmApi() {
|
|
|
39
40
|
async function isVmStrategyAvailable() {
|
|
40
41
|
return await getVmApi() !== null;
|
|
41
42
|
}
|
|
43
|
+
function findVmSharedKey(specifier, shared) {
|
|
44
|
+
if (!shared) return;
|
|
45
|
+
const keys = Object.keys(shared);
|
|
46
|
+
if (Object.prototype.hasOwnProperty.call(shared, specifier)) return specifier;
|
|
47
|
+
const vueKey = keys.find((key) => key.endsWith("/") ? key.slice(0, -1) === "vue" : key === "vue");
|
|
48
|
+
if (vueKey && (specifier === "vue/dist/vue.esm-bundler.js" || specifier === "vue/dist/vue.runtime.esm-bundler.js")) return vueKey;
|
|
49
|
+
const commonSubpathKey = keys.find((key) => {
|
|
50
|
+
return getCommonSharedSubpaths(key.endsWith("/") ? key.slice(0, -1) : key).includes(specifier);
|
|
51
|
+
});
|
|
52
|
+
if (commonSubpathKey) return commonSubpathKey;
|
|
53
|
+
return keys.find((key) => {
|
|
54
|
+
if (!key.endsWith("/")) return false;
|
|
55
|
+
const keyBase = key.slice(0, -1);
|
|
56
|
+
return specifier === keyBase || specifier.startsWith(`${keyBase}/`);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
42
59
|
function getFederationInstances() {
|
|
43
60
|
return globalThis.__FEDERATION__?.__INSTANCES__ ?? [];
|
|
44
61
|
}
|
|
@@ -51,9 +68,11 @@ async function loadBareModule(specifier, options) {
|
|
|
51
68
|
const instances = owner ? [owner] : getFederationInstances();
|
|
52
69
|
for (const instance of instances) {
|
|
53
70
|
if (typeof instance?.loadShare !== "function") continue;
|
|
54
|
-
const shared = instance.options?.shared
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
const shared = instance.options?.shared;
|
|
72
|
+
const sharedKey = findVmSharedKey(specifier, shared);
|
|
73
|
+
const shareConfig = sharedKey ? shared?.[sharedKey] : void 0;
|
|
74
|
+
if (!shareConfig) continue;
|
|
75
|
+
if (!(Array.isArray(shareConfig.scope) ? shareConfig.scope : [shareConfig.scope ?? "default"]).includes(options.shareScopeName)) continue;
|
|
57
76
|
try {
|
|
58
77
|
const factory = await instance.loadShare(specifier);
|
|
59
78
|
if (typeof factory === "function") {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import runtimePackage from "@module-federation/runtime/package.json" with { type: "json" };
|
|
1
2
|
import * as runtimeCore from "@module-federation/runtime/core";
|
|
2
3
|
//#region src/utils/injectExternalRuntimeCorePlugin.ts
|
|
3
4
|
/**
|
|
@@ -8,8 +9,7 @@ import * as runtimeCore from "@module-federation/runtime/core";
|
|
|
8
9
|
* Mirrors `@module-federation/inject-external-runtime-core-plugin` without
|
|
9
10
|
* adding that package (or `runtime-tools`) as a dependency of this plugin.
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
const PLUGIN_VERSION = "2.8.0";
|
|
12
|
+
const PLUGIN_VERSION = runtimePackage.version;
|
|
13
13
|
function getFederationGlobal() {
|
|
14
14
|
const globalRef = runtimeCore.Global;
|
|
15
15
|
if (!globalRef || typeof globalRef !== "object") return void 0;
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
* module source through Vite's plugin pipeline, avoiding serialisation which
|
|
18
18
|
* cannot faithfully represent React components or closures.
|
|
19
19
|
*
|
|
20
|
-
* Dev mode on Vite < 8 is NOT supported
|
|
21
|
-
* `
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* from `pluginSSRRemoteEntry.configureServer`.
|
|
20
|
+
* Dev mode on Vite < 8 is NOT supported by this integration because the
|
|
21
|
+
* cross-process `fetchModule` proxy uses Vite 8's environment APIs.
|
|
22
|
+
* `ModuleRunner` itself is available in earlier Vite versions, but an older
|
|
23
|
+
* remote needs a different transport and server endpoint.
|
|
25
24
|
*
|
|
26
25
|
* Exported as a plain factory function so it can be serialised into the
|
|
27
26
|
* generated runtimePlugins list in virtualRemotes.ts.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-
|
|
1
|
+
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-Ccr0zMrr.js";
|
|
2
2
|
export { SsrEntryHttpError, ssrEntryLoaderPlugin as default, neutralizeBrowserPreloadHelpers, revalidate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.4",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@module-federation/dts-plugin": "2.8.
|
|
81
|
-
"@module-federation/runtime": "2.8.
|
|
82
|
-
"@module-federation/sdk": "2.8.
|
|
80
|
+
"@module-federation/dts-plugin": "2.8.2",
|
|
81
|
+
"@module-federation/runtime": "2.8.2",
|
|
82
|
+
"@module-federation/sdk": "2.8.2"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@playwright/test": "1.62.0",
|
|
@@ -92,39 +92,5 @@
|
|
|
92
92
|
"typescript": "7.0.2",
|
|
93
93
|
"vite": "8.2.0",
|
|
94
94
|
"vitest": "4.1.10"
|
|
95
|
-
},
|
|
96
|
-
"pnpm": {
|
|
97
|
-
"overrides": {
|
|
98
|
-
"@babel/core@<7.29.6": "7.29.6",
|
|
99
|
-
"@babel/helpers@<7.26.10": "7.29.7",
|
|
100
|
-
"@babel/plugin-transform-modules-systemjs@<7.29.4": "7.29.4",
|
|
101
|
-
"@babel/runtime@<7.26.10": "7.29.7",
|
|
102
|
-
"adm-zip@<0.6.0": "0.6.0",
|
|
103
|
-
"ajv@>=6.0.0 <6.14.0": "6.14.0",
|
|
104
|
-
"ajv@>=8.0.0 <8.18.0": "8.20.0",
|
|
105
|
-
"body-parser@<1.20.6": "1.20.6",
|
|
106
|
-
"cross-spawn@<7.0.5": "7.0.6",
|
|
107
|
-
"esbuild@<0.28.1": "0.28.1",
|
|
108
|
-
"fast-uri@>=3.0.0 <3.1.4": "3.1.4",
|
|
109
|
-
"follow-redirects@<1.16.0": "1.16.0",
|
|
110
|
-
"http-proxy-middleware@>=2.0.0 <2.0.10": "2.0.10",
|
|
111
|
-
"immutable@<4.3.9": "4.3.9",
|
|
112
|
-
"js-yaml@>=4.0.0 <4.3.0": "4.3.0",
|
|
113
|
-
"lodash@<4.18.0": "4.18.1",
|
|
114
|
-
"path-to-regexp@<0.1.13": "0.1.13",
|
|
115
|
-
"postcss@<8.5.18": "8.5.25",
|
|
116
|
-
"qs@>=6.0.0 <6.15.2": "6.15.2",
|
|
117
|
-
"serialize-javascript@<7.0.5": "7.0.5",
|
|
118
|
-
"shell-quote@<1.9.0": "1.10.0",
|
|
119
|
-
"sucrase@<3.35.1": "3.35.1",
|
|
120
|
-
"undici@>=7.0.0 <7.28.0": "7.28.0",
|
|
121
|
-
"uuid@<11.1.1": "11.1.1",
|
|
122
|
-
"webpack-dev-server@<5.2.6": "5.2.6",
|
|
123
|
-
"webpack@<5.104.1": "5.109.2",
|
|
124
|
-
"websocket-driver@<0.7.5": "0.7.5",
|
|
125
|
-
"ws@>=8.0.0 <8.21.0": "8.21.0",
|
|
126
|
-
"yaml@>=1.0.0 <1.10.3": "1.10.3",
|
|
127
|
-
"yaml@>=2.0.0 <2.8.3": "2.8.3"
|
|
128
|
-
}
|
|
129
95
|
}
|
|
130
96
|
}
|