@module-federation/vite 1.16.11 → 1.16.13
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/README.md +10 -0
- package/lib/index.js +405 -179
- package/lib/{pluginDts-CrSsDUnT.js → pluginDts-CTAHkt4C.js} +50 -4
- package/lib/ssrVmStrategy-DtpfkCw1.js +152 -0
- package/lib/utils/ssrEntryLoader.d.ts +52 -2
- package/lib/utils/ssrEntryLoader.js +156 -40
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-CTAHkt4C.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import * as fs$
|
|
3
|
+
import * as fs$2 from "fs";
|
|
4
4
|
import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
5
5
|
import { createRequire as createRequire$1 } from "module";
|
|
6
6
|
import * as path$1 from "node:path";
|
|
@@ -8,6 +8,7 @@ import path, { basename } from "node:path";
|
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
9
9
|
import { version } from "vite";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
|
+
import * as fs$1 from "node:fs";
|
|
11
12
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
|
|
12
13
|
import { pathToFileURL as pathToFileURL$1 } from "node:url";
|
|
13
14
|
//#region src/utils/codeRewriter.ts
|
|
@@ -360,7 +361,7 @@ function normalizeShared(shared) {
|
|
|
360
361
|
const result = {};
|
|
361
362
|
const packageJsonPath = path$1.join(getPackageDetectionCwd(), "package.json");
|
|
362
363
|
try {
|
|
363
|
-
const packageJson = JSON.parse(fs$
|
|
364
|
+
const packageJson = JSON.parse(fs$2.readFileSync(packageJsonPath, "utf-8"));
|
|
364
365
|
if (packageJson.name === "@module-federation/vite") return result;
|
|
365
366
|
Object.keys(packageJson.dependencies || {}).filter((key) => shouldAutoShareDependency(key)).forEach((key) => {
|
|
366
367
|
result[key] = normalizeShareItem(key, {
|
|
@@ -434,7 +435,7 @@ function resolveRuntimeImplementation() {
|
|
|
434
435
|
const fallback = resolveImportPath("@module-federation/runtime");
|
|
435
436
|
try {
|
|
436
437
|
const packageJsonPath = resolveImportPath("@module-federation/runtime/package.json");
|
|
437
|
-
const packageJson = JSON.parse(fs$
|
|
438
|
+
const packageJson = JSON.parse(fs$2.readFileSync(packageJsonPath, "utf-8"));
|
|
438
439
|
const importExport = packageJson.exports?.["."];
|
|
439
440
|
const exportImport = typeof importExport === "object" ? typeof importExport.import === "string" ? importExport.import : importExport.import?.default : void 0;
|
|
440
441
|
const esmEntry = packageJson.module || exportImport;
|
|
@@ -573,6 +574,27 @@ var VirtualModule = class VirtualModule {
|
|
|
573
574
|
}
|
|
574
575
|
};
|
|
575
576
|
//#endregion
|
|
577
|
+
//#region src/utils/ssrCapabilities.ts
|
|
578
|
+
/** A browser-safe generated expression that is true only in Node.js. */
|
|
579
|
+
const SERVER_ENV_GUARD = "typeof process !== 'undefined' && !!process.versions && !!process.versions.node";
|
|
580
|
+
/**
|
|
581
|
+
* Single source of truth for SSR-related feature gates.
|
|
582
|
+
*
|
|
583
|
+
* - Vite 8+ dev: ModuleRunner + FetchableDevEnvironment for `/__mf_ssr__/` entries.
|
|
584
|
+
* - Any Vite major on build/preview: HTTP fetch + temp-file import via ssrEntryLoader.
|
|
585
|
+
*/
|
|
586
|
+
function getSsrCapabilities(viteMajor, command, hasRemotes) {
|
|
587
|
+
if (!hasRemotes) return {
|
|
588
|
+
enableSsrInitBootstrap: false,
|
|
589
|
+
injectSsrEntryLoader: false
|
|
590
|
+
};
|
|
591
|
+
const supported = command === "build" || command === "serve" && viteMajor >= 8;
|
|
592
|
+
return {
|
|
593
|
+
enableSsrInitBootstrap: supported,
|
|
594
|
+
injectSsrEntryLoader: supported
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
//#endregion
|
|
576
598
|
//#region src/utils/serializeRuntimeOptions.ts
|
|
577
599
|
/**
|
|
578
600
|
* Serializes a JavaScript object into a string of source code that can be evaluated.
|
|
@@ -628,7 +650,7 @@ function getExposesCssMapPlaceholder() {
|
|
|
628
650
|
function getVirtualExposesId(options) {
|
|
629
651
|
return `virtual:mf-exposes:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
630
652
|
}
|
|
631
|
-
function generateExposes(options) {
|
|
653
|
+
function generateExposes(options, remoteDependencyMap = {}, command = "build") {
|
|
632
654
|
return `
|
|
633
655
|
const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
|
|
634
656
|
const injectedCssHrefs = new Set();
|
|
@@ -661,8 +683,12 @@ function generateExposes(options) {
|
|
|
661
683
|
}
|
|
662
684
|
injectedCssHrefs.add(href);
|
|
663
685
|
|
|
686
|
+
// Check for any existing stylesheet with the same href, not just
|
|
687
|
+
// MF-injected ones. This prevents duplicate <link> tags when Vite's
|
|
688
|
+
// own CSS module injection or MF runtime's createLink has already
|
|
689
|
+
// created a <link rel="stylesheet"> for the same URL.
|
|
664
690
|
const existingLink = document.querySelector(
|
|
665
|
-
\`link[rel="stylesheet"][
|
|
691
|
+
\`link[rel="stylesheet"][href="\${href}"]\`
|
|
666
692
|
);
|
|
667
693
|
if (existingLink) {
|
|
668
694
|
return Promise.resolve();
|
|
@@ -672,7 +698,6 @@ function generateExposes(options) {
|
|
|
672
698
|
const link = document.createElement("link");
|
|
673
699
|
link.rel = "stylesheet";
|
|
674
700
|
link.href = href;
|
|
675
|
-
link.setAttribute("data-mf-href", href);
|
|
676
701
|
link.onload = () => resolve();
|
|
677
702
|
link.onerror = () => reject(new Error(\`[Module Federation] Failed to load CSS asset: \${href}\`));
|
|
678
703
|
document.head.appendChild(link);
|
|
@@ -683,12 +708,22 @@ function generateExposes(options) {
|
|
|
683
708
|
|
|
684
709
|
export default {
|
|
685
710
|
${Object.keys(options.exposes).map((key) => {
|
|
711
|
+
const remoteDependencyPreloads = (remoteDependencyMap[key] ?? []).map((remoteId) => {
|
|
712
|
+
const virtualRemote = getRemoteVirtualModule(remoteId, command);
|
|
713
|
+
return `import(${JSON.stringify(virtualRemote.getImportId())})
|
|
714
|
+
.then((mod) => mod.__mf_remote_pending)`;
|
|
715
|
+
}).join(",");
|
|
686
716
|
return `
|
|
687
717
|
${JSON.stringify(key)}: async () => {
|
|
688
718
|
await injectCssAssets(${JSON.stringify(key)})
|
|
719
|
+
await Promise.all([${remoteDependencyPreloads}])
|
|
689
720
|
const importModule = await importExposedModule(
|
|
690
721
|
() => import(${JSON.stringify(options.exposes[key].import)})
|
|
691
722
|
)
|
|
723
|
+
const dependencyPending = importModule && importModule.__mf_remote_dependency_pending;
|
|
724
|
+
if (dependencyPending && typeof dependencyPending.then === "function") {
|
|
725
|
+
await dependencyPending;
|
|
726
|
+
}
|
|
692
727
|
const exportModule = {}
|
|
693
728
|
Object.assign(exportModule, importModule)
|
|
694
729
|
Object.defineProperty(exportModule, "__esModule", {
|
|
@@ -722,7 +757,7 @@ function setSsrRemotes(remotes) {
|
|
|
722
757
|
}
|
|
723
758
|
function getSsrNoopResolveCode(enableSsrInit, hostInitImportId, initResolveExpression = "initResolve") {
|
|
724
759
|
if (!enableSsrInit) return "";
|
|
725
|
-
return `if (
|
|
760
|
+
return `if (${SERVER_ENV_GUARD}) {
|
|
726
761
|
var _noop = { loadRemote: function() { return Promise.resolve(undefined); }, loadShare: function() { return Promise.resolve(undefined); } };
|
|
727
762
|
${hostInitImportId ? `import(${JSON.stringify(hostInitImportId)})
|
|
728
763
|
.then(function(mod) { return mod.hostInitPromise; })
|
|
@@ -781,7 +816,7 @@ globalThis[globalKey] = {
|
|
|
781
816
|
};
|
|
782
817
|
}
|
|
783
818
|
${enableSsrInit ? `
|
|
784
|
-
if (
|
|
819
|
+
if (${SERVER_ENV_GUARD} && !globalThis[globalKey].ssrInitStarted) {
|
|
785
820
|
globalThis[globalKey].ssrInitStarted = true;
|
|
786
821
|
${getSsrNoopResolveCode(enableSsrInit, hostInitImportId, "globalThis[globalKey].initResolve")}
|
|
787
822
|
}` : ""}
|
|
@@ -862,6 +897,9 @@ function escapeGeneratedStringLiteral(value) {
|
|
|
862
897
|
}
|
|
863
898
|
});
|
|
864
899
|
}
|
|
900
|
+
function getSharedCacheDescriptorLiteral(pkg, shareItem) {
|
|
901
|
+
return JSON.stringify(getSharedCacheDescriptor(pkg, shareItem));
|
|
902
|
+
}
|
|
865
903
|
function isValidJsIdentifier(name) {
|
|
866
904
|
return JS_IDENTIFIER_REGEX.test(name);
|
|
867
905
|
}
|
|
@@ -1031,7 +1069,7 @@ function getSharedNamedExports(pkg, shareItem) {
|
|
|
1031
1069
|
}
|
|
1032
1070
|
function getLocalProviderImportPath(pkg) {
|
|
1033
1071
|
try {
|
|
1034
|
-
const resolved = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg);
|
|
1072
|
+
const resolved = resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg));
|
|
1035
1073
|
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
1036
1074
|
} catch {
|
|
1037
1075
|
const resolved = getInstalledPackageEntry(pkg, {
|
|
@@ -1052,7 +1090,7 @@ function getProjectResolvedImportPath(pkg) {
|
|
|
1052
1090
|
if (esmEntry) return esmEntry;
|
|
1053
1091
|
}
|
|
1054
1092
|
try {
|
|
1055
|
-
return createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg);
|
|
1093
|
+
return resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg));
|
|
1056
1094
|
} catch {
|
|
1057
1095
|
return;
|
|
1058
1096
|
}
|
|
@@ -1065,6 +1103,30 @@ function isWorkspaceFilePath(resolved) {
|
|
|
1065
1103
|
} catch {}
|
|
1066
1104
|
return !realResolved.includes("/node_modules/") && !realResolved.includes("\\node_modules\\");
|
|
1067
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* When createRequire resolves a workspace package to a CJS entry (e.g. dist/index.cjs),
|
|
1108
|
+
* re-resolve via getInstalledPackageEntry with ESM-preferring conditions.
|
|
1109
|
+
*
|
|
1110
|
+
* Workspace packages produce browser code, so they must use the ESM build — CJS files
|
|
1111
|
+
* contain `module.exports` which is undefined in the browser. createRequire().resolve()
|
|
1112
|
+
* follows Node.js CJS conditions ["node", "require"], which matches exports["."].require.default
|
|
1113
|
+
* and returns the .cjs path for packages with dual ESM/CJS exports.
|
|
1114
|
+
*/
|
|
1115
|
+
function resolveWorkspaceEsmEntry(pkg, resolved, cwd = getPackageDetectionCwd()) {
|
|
1116
|
+
if (!isWorkspaceFilePath(resolved)) return resolved;
|
|
1117
|
+
const esmEntry = getInstalledPackageEntry(pkg, {
|
|
1118
|
+
cwd,
|
|
1119
|
+
conditions: [
|
|
1120
|
+
"browser",
|
|
1121
|
+
"import",
|
|
1122
|
+
"module",
|
|
1123
|
+
"default"
|
|
1124
|
+
],
|
|
1125
|
+
resolveSubpathWithRequire: false
|
|
1126
|
+
});
|
|
1127
|
+
if (esmEntry && isWorkspaceFilePath(esmEntry)) return esmEntry;
|
|
1128
|
+
return resolved;
|
|
1129
|
+
}
|
|
1068
1130
|
function isWorkspacePackageEntry(pkg, resolved) {
|
|
1069
1131
|
if (!resolved || !path$1.isAbsolute(resolved) || !isWorkspaceFilePath(resolved)) return false;
|
|
1070
1132
|
return !!getInstalledPackageJson(pkg, {
|
|
@@ -1117,7 +1179,7 @@ function isWorkspaceSingletonConsumedByPeer(pkg) {
|
|
|
1117
1179
|
}
|
|
1118
1180
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
1119
1181
|
try {
|
|
1120
|
-
return createRequire$1(pathToFileURL(path$1.join(root, "package.json"))).resolve(pkg);
|
|
1182
|
+
return resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(root, "package.json"))).resolve(pkg), root);
|
|
1121
1183
|
} catch {
|
|
1122
1184
|
return;
|
|
1123
1185
|
}
|
|
@@ -1143,11 +1205,18 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1143
1205
|
preBuildShareItemMap[pkg] = shareItem;
|
|
1144
1206
|
const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
|
|
1145
1207
|
if (pkg === "react/compiler-runtime") {
|
|
1208
|
+
const reactCacheDescriptor = getSharedCacheDescriptorLiteral("react", shareItem ?? {
|
|
1209
|
+
name: "react",
|
|
1210
|
+
from: "",
|
|
1211
|
+
scope: "default",
|
|
1212
|
+
shareConfig: { singleton: true }
|
|
1213
|
+
});
|
|
1146
1214
|
preBuildCacheMap[pkg].writeSync(`
|
|
1215
|
+
${sharedCacheHelperCode}
|
|
1147
1216
|
const __mfCacheGlobalKey = "__mf_module_cache__";
|
|
1148
1217
|
export const c = function(size) {
|
|
1149
1218
|
const cache = globalThis[__mfCacheGlobalKey]?.share;
|
|
1150
|
-
const sharedReact = cache
|
|
1219
|
+
const sharedReact = cache && __mfReadSharedCache(cache, ${reactCacheDescriptor});
|
|
1151
1220
|
const reactExports = sharedReact?.default ?? sharedReact;
|
|
1152
1221
|
const internals = reactExports?.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1153
1222
|
return internals?.H?.useMemoCache(size);
|
|
@@ -1189,7 +1258,7 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1189
1258
|
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1190
1259
|
${declarations}
|
|
1191
1260
|
${namedExportLine}
|
|
1192
|
-
export default
|
|
1261
|
+
export default __mfPrebuildNamespace.default ?? __mfPrebuildNamespace;
|
|
1193
1262
|
`, true);
|
|
1194
1263
|
return;
|
|
1195
1264
|
}
|
|
@@ -1244,45 +1313,47 @@ function materializeCachedLoadShareModule(options) {
|
|
|
1244
1313
|
options.addUsedShares(pkg);
|
|
1245
1314
|
options.writeLocalSharedImportMap();
|
|
1246
1315
|
}
|
|
1247
|
-
function generateEagerWorkspaceSingletonExports(namedExports, importSource,
|
|
1248
|
-
const
|
|
1316
|
+
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor) {
|
|
1317
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1318
|
+
const namedExportAssignments = namedExports.length > 0 ? `\n ${namedExports.map((name, i) => `const ${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}` : "";
|
|
1319
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1249
1320
|
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
|
|
1250
|
-
let exportModule = __mfModuleCache.share
|
|
1321
|
+
let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
|
|
1251
1322
|
if (exportModule === undefined) {
|
|
1252
1323
|
Promise.resolve().then(() => {
|
|
1253
|
-
if (__mfModuleCache.share
|
|
1254
|
-
__mfModuleCache.share
|
|
1324
|
+
if (__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor}) === undefined) {
|
|
1325
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare));
|
|
1255
1326
|
}
|
|
1256
1327
|
});
|
|
1257
1328
|
exportModule = __mfLocalShare;
|
|
1258
1329
|
}
|
|
1259
|
-
const __mf_default = exportModule.default ?? exportModule
|
|
1330
|
+
const __mf_default = exportModule.default ?? exportModule;${namedExportAssignments}
|
|
1260
1331
|
export { __mf_default as default };${namedExportLine}`;
|
|
1261
1332
|
}
|
|
1262
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource,
|
|
1333
|
+
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, eagerLocalFallback) {
|
|
1263
1334
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1264
1335
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
1265
1336
|
const assignments = namedExports.length > 0 ? [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
|
|
1266
1337
|
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1267
1338
|
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1268
|
-
__mfModuleCache.share
|
|
1339
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1269
1340
|
__mfApplyLazyShareExports(exportModule);`;
|
|
1270
1341
|
const body = `${declarations}
|
|
1271
1342
|
const __mfApplyLazyShareExports = (mod) => {
|
|
1272
1343
|
${assignments}
|
|
1273
1344
|
};
|
|
1274
|
-
let exportModule = __mfModuleCache.share
|
|
1345
|
+
let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
|
|
1275
1346
|
if (exportModule === undefined) {
|
|
1276
1347
|
${eagerLocalFallback ? applyLocalFallback : `if (import.meta.env.SSR) {
|
|
1277
1348
|
${applyLocalFallback}
|
|
1278
1349
|
} else {
|
|
1279
|
-
initPromise.then(() =>
|
|
1350
|
+
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() =>
|
|
1280
1351
|
import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
|
|
1281
1352
|
exportModule = __mfNormalizeShareModule(mod);
|
|
1282
|
-
__mfModuleCache.share
|
|
1353
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1283
1354
|
__mfApplyLazyShareExports(exportModule);
|
|
1284
1355
|
})
|
|
1285
|
-
);
|
|
1356
|
+
));
|
|
1286
1357
|
}`}
|
|
1287
1358
|
} else {
|
|
1288
1359
|
__mfApplyLazyShareExports(exportModule);
|
|
@@ -1301,28 +1372,25 @@ function prependWorkspaceSingletonSsrImport(code) {
|
|
|
1301
1372
|
const quote = importMatch[1];
|
|
1302
1373
|
return `import * as __mfLocalShare from ${quote}${importMatch[2]}${quote};\n${code}`;
|
|
1303
1374
|
}
|
|
1304
|
-
function generateDeferredHostProvidedExports(namedExports, pkg,
|
|
1375
|
+
function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor) {
|
|
1305
1376
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1306
|
-
|
|
1307
|
-
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
1308
|
-
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1309
|
-
return `${declarations}
|
|
1377
|
+
return `${["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
|
|
1310
1378
|
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1311
|
-
${
|
|
1379
|
+
${[...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ")}
|
|
1312
1380
|
};
|
|
1313
|
-
let exportModule = __mfModuleCache.share
|
|
1381
|
+
let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
|
|
1314
1382
|
if (exportModule === undefined) {
|
|
1315
|
-
initPromise.then(() => {
|
|
1316
|
-
exportModule = __mfModuleCache.share
|
|
1383
|
+
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
|
|
1384
|
+
exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
|
|
1317
1385
|
if (exportModule === undefined) {
|
|
1318
1386
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1319
1387
|
}
|
|
1320
1388
|
__mfApplyHostProvidedExports(exportModule);
|
|
1321
|
-
});
|
|
1389
|
+
}));
|
|
1322
1390
|
} else {
|
|
1323
1391
|
__mfApplyHostProvidedExports(exportModule);
|
|
1324
1392
|
}
|
|
1325
|
-
export { __mf_default as default };${
|
|
1393
|
+
export { __mf_default as default };${namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : ""}`;
|
|
1326
1394
|
}
|
|
1327
1395
|
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1328
1396
|
return `let current = ${source};
|
|
@@ -1344,18 +1412,19 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
|
|
|
1344
1412
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
1345
1413
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
|
|
1346
1414
|
let importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1347
|
-
const
|
|
1415
|
+
const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
|
|
1348
1416
|
if (shareItem.shareConfig.import === false) {
|
|
1349
1417
|
const namedExports = getPackageNamedExports(pkg);
|
|
1350
1418
|
let exportLine;
|
|
1351
|
-
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg,
|
|
1419
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor);
|
|
1352
1420
|
else {
|
|
1353
1421
|
mfWarn(`Shared dependency "${pkg}" has import: false but is not installed locally.\n Named imports (e.g. import { ... } from '${pkg}') will not work in production builds.\n Install it as a devDependency to enable named export detection.`);
|
|
1354
|
-
exportLine = generateDeferredHostProvidedExports([], pkg,
|
|
1422
|
+
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor);
|
|
1355
1423
|
}
|
|
1356
1424
|
loadShareCacheMap[pkg].writeSync(`
|
|
1357
1425
|
${getRuntimeInitPromiseBootstrapCode()}
|
|
1358
1426
|
${importLine}
|
|
1427
|
+
${sharedCacheHelperCode}
|
|
1359
1428
|
${exportLine}
|
|
1360
1429
|
`, true);
|
|
1361
1430
|
return;
|
|
@@ -1372,10 +1441,10 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1372
1441
|
const namedExports = getSharedNamedExports(pkg, shareItem);
|
|
1373
1442
|
let exportLine;
|
|
1374
1443
|
let initBlock = "";
|
|
1375
|
-
if (usesEagerWorkspaceFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource,
|
|
1444
|
+
if (usesEagerWorkspaceFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor);
|
|
1376
1445
|
else if (isWorkspaceSingleton) {
|
|
1377
1446
|
importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
|
|
1378
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource,
|
|
1447
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, command !== "build");
|
|
1379
1448
|
} else if (namedExports.length > 0) {
|
|
1380
1449
|
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1381
1450
|
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
@@ -1390,11 +1459,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1390
1459
|
${destructure}
|
|
1391
1460
|
${namedExportLine}`;
|
|
1392
1461
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1393
|
-
__mfModuleCache.share
|
|
1462
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
|
|
1394
1463
|
} else {
|
|
1395
1464
|
exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
1396
1465
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1397
|
-
__mfModuleCache.share
|
|
1466
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
|
|
1398
1467
|
}
|
|
1399
1468
|
const prebuildImportLine = isWorkspaceSingleton || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1400
1469
|
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
@@ -1402,14 +1471,16 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1402
1471
|
${prebuildImportLine}
|
|
1403
1472
|
${devDynamicImportLine}
|
|
1404
1473
|
${importLine}
|
|
1474
|
+
${sharedCacheHelperCode}
|
|
1405
1475
|
${normalizeLocalShareModuleCode}
|
|
1406
1476
|
${exportLine}
|
|
1407
1477
|
` : `
|
|
1408
1478
|
${prebuildImportLine}
|
|
1409
1479
|
${devDynamicImportLine}
|
|
1410
1480
|
${importLine}
|
|
1481
|
+
${sharedCacheHelperCode}
|
|
1411
1482
|
${normalizeLocalShareModuleCode}
|
|
1412
|
-
let exportModule = __mfModuleCache.share
|
|
1483
|
+
let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})
|
|
1413
1484
|
if (exportModule === undefined) {
|
|
1414
1485
|
${initBlock}
|
|
1415
1486
|
}
|
|
@@ -1596,8 +1667,8 @@ function getShareItemForPreload(pkg) {
|
|
|
1596
1667
|
if (isExplicitSharedKey(wildcardKey)) return shared[wildcardKey];
|
|
1597
1668
|
}
|
|
1598
1669
|
function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
|
|
1599
|
-
const
|
|
1600
|
-
return `if (__mfModuleCache.share
|
|
1670
|
+
const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
1671
|
+
return `if (__mfReadSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}) === undefined) {
|
|
1601
1672
|
const mod = await import(${JSON.stringify(importPath)});
|
|
1602
1673
|
${normalizeRuntimeShareCode}
|
|
1603
1674
|
const normalizedModule = __mfNormalizeRuntimeShare(mod);
|
|
@@ -1606,14 +1677,9 @@ function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
|
|
|
1606
1677
|
value: true,
|
|
1607
1678
|
enumerable: false
|
|
1608
1679
|
});
|
|
1609
|
-
__mfModuleCache.share
|
|
1680
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule);
|
|
1610
1681
|
}`;
|
|
1611
1682
|
}
|
|
1612
|
-
const sharedCacheKeyHelperCode = `const __mfGetSharedCacheKey = (pkg, singleton, version, scope) => {
|
|
1613
|
-
const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
|
|
1614
|
-
const prefix = (normalizedScope || "default") + ":";
|
|
1615
|
-
return singleton || !version ? prefix + pkg : prefix + pkg + "@" + version;
|
|
1616
|
-
};`;
|
|
1617
1683
|
const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
1618
1684
|
let current = mod;
|
|
1619
1685
|
for (let i = 0; i < 5; i++) {
|
|
@@ -1767,7 +1833,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1767
1833
|
}
|
|
1768
1834
|
|
|
1769
1835
|
async function init(shared = {}, initScope = []) {
|
|
1770
|
-
${
|
|
1836
|
+
${sharedCacheHelperCode}
|
|
1771
1837
|
const {usedShared, usedRemotes} = await getLocalSharedImportMap()
|
|
1772
1838
|
try {
|
|
1773
1839
|
const allInstances = globalThis.__FEDERATION__?.__SHARE__;
|
|
@@ -1786,16 +1852,16 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1786
1852
|
: Object.entries(versionMap);
|
|
1787
1853
|
for (const [version, provider] of providerEntries) {
|
|
1788
1854
|
if (!provider.lib) continue;
|
|
1789
|
-
const
|
|
1790
|
-
if (__mfModuleCache.share
|
|
1855
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
|
|
1856
|
+
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
1791
1857
|
const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
|
|
1792
1858
|
const resolved = await Promise.resolve(mod);
|
|
1793
1859
|
const normalized = __mfNormalizeRuntimeShare(resolved);
|
|
1794
|
-
__mfModuleCache.share
|
|
1860
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalized);
|
|
1795
1861
|
if (provider.shareConfig?.singleton && usedShare) {
|
|
1796
|
-
const
|
|
1797
|
-
if (__mfModuleCache.share
|
|
1798
|
-
__mfModuleCache.share
|
|
1862
|
+
const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
|
|
1863
|
+
if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) === undefined) {
|
|
1864
|
+
__mfWriteSharedCache(__mfModuleCache.share, usedCacheDescriptor, normalized);
|
|
1799
1865
|
}
|
|
1800
1866
|
}
|
|
1801
1867
|
}
|
|
@@ -1806,11 +1872,12 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1806
1872
|
console.error('[Module Federation] Failed to bridge external shared modules', e)
|
|
1807
1873
|
}
|
|
1808
1874
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1809
|
-
const
|
|
1810
|
-
if (__mfModuleCache.share
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1813
|
-
|
|
1875
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
1876
|
+
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
1877
|
+
const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
|
|
1878
|
+
const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
|
|
1879
|
+
if (singletonModule !== undefined) {
|
|
1880
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, singletonModule);
|
|
1814
1881
|
}
|
|
1815
1882
|
}
|
|
1816
1883
|
${generateDirectSharedCacheSeedCode(command)}
|
|
@@ -1836,7 +1903,6 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1836
1903
|
if (initScope.indexOf(initToken) >= 0) return;
|
|
1837
1904
|
initScope.push(initToken);
|
|
1838
1905
|
initRes.initShareScopeMap('${options.shareScope}', shared);
|
|
1839
|
-
initResolve(initRes)
|
|
1840
1906
|
try {
|
|
1841
1907
|
await retrySharedInit(async () => {
|
|
1842
1908
|
await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
|
|
@@ -1849,8 +1915,8 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1849
1915
|
console.error('[Module Federation]', e)
|
|
1850
1916
|
}
|
|
1851
1917
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1852
|
-
const
|
|
1853
|
-
if (share.shareConfig?.import !== false || __mfModuleCache.share
|
|
1918
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
1919
|
+
if (share.shareConfig?.import !== false || __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
1854
1920
|
${normalizeRuntimeShareCode}
|
|
1855
1921
|
const versions = shared?.[pkg];
|
|
1856
1922
|
const provider = __mfSelectSharedProvider(versions, pkg, share, '${options.shareStrategy}');
|
|
@@ -1858,8 +1924,9 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1858
1924
|
const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
|
|
1859
1925
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
1860
1926
|
const resolved = await Promise.resolve(mod);
|
|
1861
|
-
__mfModuleCache.share
|
|
1927
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
|
|
1862
1928
|
}
|
|
1929
|
+
initResolve(initRes)
|
|
1863
1930
|
return initRes
|
|
1864
1931
|
}
|
|
1865
1932
|
|
|
@@ -1885,16 +1952,16 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1885
1952
|
async function initHost() {
|
|
1886
1953
|
if (!hostInitPromise) {
|
|
1887
1954
|
hostInitPromise = (async () => {
|
|
1955
|
+
${sharedCacheHelperCode}
|
|
1888
1956
|
${generateHostAutoInitSharedCacheSeedCode(_command)}
|
|
1889
1957
|
const remoteEntry = await import(${remoteEntryImport});
|
|
1890
1958
|
const runtime = await remoteEntry.init();
|
|
1891
1959
|
const usedShared = ${generateUsedSharedPreloadConfig()};
|
|
1892
|
-
${sharedCacheKeyHelperCode}
|
|
1893
1960
|
${normalizeRuntimeShareCode}
|
|
1894
1961
|
${shouldPreloadShares ? `
|
|
1895
1962
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1896
|
-
const
|
|
1897
|
-
if (__mfModuleCache.share
|
|
1963
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
1964
|
+
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) {
|
|
1898
1965
|
continue;
|
|
1899
1966
|
}
|
|
1900
1967
|
await runtime.loadShare(pkg, {
|
|
@@ -1902,7 +1969,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1902
1969
|
}).then((factory) => {
|
|
1903
1970
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
1904
1971
|
return Promise.resolve(mod).then((resolved) => {
|
|
1905
|
-
__mfModuleCache.share
|
|
1972
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
|
|
1906
1973
|
});
|
|
1907
1974
|
});
|
|
1908
1975
|
}
|
|
@@ -2162,7 +2229,7 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
2162
2229
|
const eagerLoadClientRemote = shouldEagerLoadClientRemoteInDev(command, enableSsrInit);
|
|
2163
2230
|
const eagerClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
|
|
2164
2231
|
const loadedFirstClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
|
|
2165
|
-
const environmentSplitInit = (clientInit, serverInit) => consumer === "client" ? clientInit : consumer === "server" ? serverInit : `if (
|
|
2232
|
+
const environmentSplitInit = (clientInit, serverInit) => consumer === "client" ? clientInit : consumer === "server" ? serverInit : `if (${SERVER_ENV_GUARD}) {
|
|
2166
2233
|
${serverInit}
|
|
2167
2234
|
} else {
|
|
2168
2235
|
${clientInit}
|
|
@@ -2218,10 +2285,10 @@ function injectHostInitPreloads(html, bundle, resolvePath) {
|
|
|
2218
2285
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
2219
2286
|
return entryFiles.find((file) => file.endsWith(".html"));
|
|
2220
2287
|
}
|
|
2221
|
-
function stripQueryAndHash(file) {
|
|
2288
|
+
function stripQueryAndHash$1(file) {
|
|
2222
2289
|
return file.split(/[?#]/)[0];
|
|
2223
2290
|
}
|
|
2224
|
-
function resolveDevHashEntryFileName(fileName) {
|
|
2291
|
+
function resolveDevHashEntryFileName$1(fileName) {
|
|
2225
2292
|
if (!fileName.includes("[hash")) return fileName;
|
|
2226
2293
|
const normalized = fileName.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
|
|
2227
2294
|
const baseName = path$1.basename(normalized);
|
|
@@ -2298,8 +2365,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2298
2365
|
});
|
|
2299
2366
|
}
|
|
2300
2367
|
function walkFiles(dir, predicate) {
|
|
2301
|
-
if (!fs$
|
|
2302
|
-
return fs$
|
|
2368
|
+
if (!fs$2.existsSync(dir)) return [];
|
|
2369
|
+
return fs$2.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
2303
2370
|
const entryPath = path$1.join(dir, entry.name);
|
|
2304
2371
|
if (entry.isDirectory()) return walkFiles(entryPath, predicate);
|
|
2305
2372
|
return entry.isFile() && predicate(entry.name) ? [entryPath] : [];
|
|
@@ -2315,17 +2382,17 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2315
2382
|
function patchSvelteKitStaticHtml() {
|
|
2316
2383
|
const buildDir = path$1.resolve(viteConfig.root, "build");
|
|
2317
2384
|
let initFile = emittedFileName ? path$1.resolve(buildDir, emittedFileName) : void 0;
|
|
2318
|
-
if (!initFile || !fs$
|
|
2319
|
-
const code = fs$
|
|
2385
|
+
if (!initFile || !fs$2.existsSync(initFile)) initFile = walkFiles(buildDir, (fileName) => fileName.endsWith(".js")).find((file) => {
|
|
2386
|
+
const code = fs$2.readFileSync(file, "utf-8");
|
|
2320
2387
|
return code.includes("hostInitPromise") && code.includes("initHost");
|
|
2321
2388
|
});
|
|
2322
2389
|
if (!initFile) return false;
|
|
2323
2390
|
let patched = false;
|
|
2324
2391
|
for (const htmlFile of walkHtmlFiles(buildDir)) {
|
|
2325
|
-
const html = fs$
|
|
2392
|
+
const html = fs$2.readFileSync(htmlFile, "utf-8");
|
|
2326
2393
|
const rewritten = rewriteSvelteKitInlineStart(html, toRelativeImport(htmlFile, initFile));
|
|
2327
2394
|
if (rewritten !== html) {
|
|
2328
|
-
fs$
|
|
2395
|
+
fs$2.writeFileSync(htmlFile, rewritten);
|
|
2329
2396
|
patched = true;
|
|
2330
2397
|
}
|
|
2331
2398
|
}
|
|
@@ -2365,6 +2432,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2365
2432
|
await __mfHostInit.__tla;
|
|
2366
2433
|
const { initHost } = __mfHostInit;
|
|
2367
2434
|
${preloadBlock}
|
|
2435
|
+
if (__mfModuleCache.pendingShareLoads) {
|
|
2436
|
+
await Promise.all(__mfModuleCache.pendingShareLoads);
|
|
2437
|
+
}
|
|
2368
2438
|
})().then(() => ${importExpression(entrySrc)});
|
|
2369
2439
|
`;
|
|
2370
2440
|
return [
|
|
@@ -2402,12 +2472,12 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2402
2472
|
if (!entryFiles.includes(normalized)) entryFiles.push(normalized);
|
|
2403
2473
|
}
|
|
2404
2474
|
function addHtmlScriptEntries(htmlPath) {
|
|
2405
|
-
if (!fs$
|
|
2406
|
-
const htmlContent = fs$
|
|
2475
|
+
if (!fs$2.existsSync(htmlPath)) return;
|
|
2476
|
+
const htmlContent = fs$2.readFileSync(htmlPath, "utf-8");
|
|
2407
2477
|
const scriptRegex = /<script\b(?=[^>]*\btype=["']module["'])(?=[^>]*\bsrc=["']([^"']+)["'])[^>]*>/gi;
|
|
2408
2478
|
let match;
|
|
2409
2479
|
while ((match = scriptRegex.exec(htmlContent)) !== null) {
|
|
2410
|
-
const scriptSrc = stripQueryAndHash(match[1]);
|
|
2480
|
+
const scriptSrc = stripQueryAndHash$1(match[1]);
|
|
2411
2481
|
if (/^(?:[a-z]+:)?\/\//i.test(scriptSrc)) continue;
|
|
2412
2482
|
addEntryFile(scriptSrc);
|
|
2413
2483
|
addEntryFile(scriptSrc.startsWith("/") ? path$1.resolve(viteConfig.root, scriptSrc.slice(1)) : path$1.resolve(path$1.dirname(htmlPath), scriptSrc));
|
|
@@ -2450,7 +2520,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2450
2520
|
next();
|
|
2451
2521
|
return;
|
|
2452
2522
|
}
|
|
2453
|
-
const devFileName = resolveDevHashEntryFileName(fileName);
|
|
2523
|
+
const devFileName = resolveDevHashEntryFileName$1(fileName);
|
|
2454
2524
|
if (devFileName !== fileName && req.url?.startsWith((viteConfig.base + devFileName).replace(/^\/?/, "/"))) req.url = req.url.replace(devFileName, fileName);
|
|
2455
2525
|
if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, "/"))) req.url = devEntryPath;
|
|
2456
2526
|
next();
|
|
@@ -2634,9 +2704,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2634
2704
|
const injection = `await import(${JSON.stringify(getEntryPath())}).then(({ initHost }) => initHost());\n `;
|
|
2635
2705
|
return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
|
|
2636
2706
|
}
|
|
2637
|
-
const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$
|
|
2707
|
+
const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !isFederationInternalVirtualId(id) && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && (/hydrateRoot|createRoot|ReactDOM\.render/.test(code) || /\.mount\s*\(\s*['"#]/.test(code) || /\.mount\s*\(/.test(code) && /createSSRApp|createApp/.test(code));
|
|
2638
2708
|
const isNuxtEntryAsyncModule = /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
|
|
2639
|
-
const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && (!htmlFilePath || !fs$
|
|
2709
|
+
const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && isNuxtEntryAsyncModule && !entryFiles.some((file) => projectId === file);
|
|
2640
2710
|
if (!(_command === "serve" && isNuxtEntryAsyncModule) && (injectedTransformIds.has(projectId) || injectEntry() && entryFiles.some((file) => projectId === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !skipHtmlDevFallback && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback)) {
|
|
2641
2711
|
clientInjected = true;
|
|
2642
2712
|
injectedTransformIds.add(projectId);
|
|
@@ -3783,6 +3853,7 @@ const Manifest = () => {
|
|
|
3783
3853
|
},
|
|
3784
3854
|
async generateBundle(_options, bundle) {
|
|
3785
3855
|
if (!mfManifestName) return;
|
|
3856
|
+
if (this.environment?.name === "ssr") return;
|
|
3786
3857
|
let filesMap = {};
|
|
3787
3858
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
3788
3859
|
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(foundRemoteEntryFile || mfOptions.filename);
|
|
@@ -4033,8 +4104,39 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
4033
4104
|
}
|
|
4034
4105
|
//#endregion
|
|
4035
4106
|
//#region src/plugins/pluginProxyRemoteEntry.ts
|
|
4107
|
+
function resolveDevHashEntryFileName(fileName) {
|
|
4108
|
+
if (!fileName.includes("[hash")) return fileName;
|
|
4109
|
+
const normalized = fileName.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
|
|
4110
|
+
const baseName = path$1.basename(normalized);
|
|
4111
|
+
return path$1.extname(baseName) ? normalized : `${normalized}.js`;
|
|
4112
|
+
}
|
|
4036
4113
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
4037
4114
|
let viteConfig, _command, root;
|
|
4115
|
+
let exposeRemoteDependencies = {};
|
|
4116
|
+
function isRemoteImport(source) {
|
|
4117
|
+
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
4118
|
+
}
|
|
4119
|
+
function collectRemoteDependencies(code) {
|
|
4120
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
4121
|
+
for (const match of code.matchAll(/(?:^|[;\n\r])\s*import\s+(?:[\s\S]*?\s+from\s+)?["']([^"']+)["']|import\(\s*["']([^"']+)["']\s*\)/g)) {
|
|
4122
|
+
const source = match[1] || match[2];
|
|
4123
|
+
if (source && isRemoteImport(source)) dependencies.add(source);
|
|
4124
|
+
}
|
|
4125
|
+
return Array.from(dependencies).sort();
|
|
4126
|
+
}
|
|
4127
|
+
async function refreshExposeRemoteDependencies(ctx) {
|
|
4128
|
+
const next = {};
|
|
4129
|
+
for (const [exposeKey, expose] of Object.entries(options.exposes)) {
|
|
4130
|
+
const resolved = await ctx.resolve(expose.import);
|
|
4131
|
+
if (!resolved?.id || resolved.id.includes("\0")) continue;
|
|
4132
|
+
try {
|
|
4133
|
+
next[exposeKey] = collectRemoteDependencies(readFileSync$1(resolved.id, "utf8"));
|
|
4134
|
+
} catch {
|
|
4135
|
+
next[exposeKey] = [];
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
exposeRemoteDependencies = next;
|
|
4139
|
+
}
|
|
4038
4140
|
return {
|
|
4039
4141
|
name: "proxyRemoteEntry",
|
|
4040
4142
|
enforce: "post",
|
|
@@ -4046,6 +4148,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4046
4148
|
_command = command;
|
|
4047
4149
|
},
|
|
4048
4150
|
async buildStart() {
|
|
4151
|
+
await refreshExposeRemoteDependencies(this);
|
|
4049
4152
|
if (_command !== "build") return;
|
|
4050
4153
|
for (const expose of Object.values(options.exposes)) {
|
|
4051
4154
|
const resolved = await this.resolve(expose.import);
|
|
@@ -4067,19 +4170,19 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4067
4170
|
},
|
|
4068
4171
|
load(id) {
|
|
4069
4172
|
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4070
|
-
if (id === virtualExposesId) return generateExposes(options);
|
|
4173
|
+
if (id === virtualExposesId) return generateExposes(options, exposeRemoteDependencies, _command);
|
|
4071
4174
|
if (_command === "serve" && id.includes(getHostAutoInitPath())) return id;
|
|
4072
4175
|
},
|
|
4073
4176
|
transform(code, id) {
|
|
4074
4177
|
return mapCodeToCodeWithSourcemap((() => {
|
|
4075
4178
|
if (!filterId(id)) return;
|
|
4076
4179
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4077
|
-
if (id === virtualExposesId) return generateExposes(options);
|
|
4180
|
+
if (id === virtualExposesId) return generateExposes(options, exposeRemoteDependencies, _command);
|
|
4078
4181
|
if (id.includes(getHostAutoInitPath())) {
|
|
4079
4182
|
if (_command === "serve") {
|
|
4080
4183
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
4081
4184
|
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base);
|
|
4082
|
-
const publicPath = JSON.stringify((resolvedPublicPath === "auto" ? "/" : resolvedPublicPath) + options.filename);
|
|
4185
|
+
const publicPath = JSON.stringify((resolvedPublicPath === "auto" ? "/" : resolvedPublicPath) + resolveDevHashEntryFileName(options.filename));
|
|
4083
4186
|
const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
|
|
4084
4187
|
const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
|
|
4085
4188
|
return `
|
|
@@ -4145,25 +4248,6 @@ function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
|
4145
4248
|
return "server";
|
|
4146
4249
|
}
|
|
4147
4250
|
//#endregion
|
|
4148
|
-
//#region src/utils/ssrCapabilities.ts
|
|
4149
|
-
/**
|
|
4150
|
-
* Single source of truth for SSR-related feature gates.
|
|
4151
|
-
*
|
|
4152
|
-
* - Vite 8+ dev: ModuleRunner + FetchableDevEnvironment for `/__mf_ssr__/` entries.
|
|
4153
|
-
* - Any Vite major on build/preview: HTTP fetch + temp-file import via ssrEntryLoader.
|
|
4154
|
-
*/
|
|
4155
|
-
function getSsrCapabilities(viteMajor, command, hasRemotes) {
|
|
4156
|
-
if (!hasRemotes) return {
|
|
4157
|
-
enableSsrInitBootstrap: false,
|
|
4158
|
-
injectSsrEntryLoader: false
|
|
4159
|
-
};
|
|
4160
|
-
const supported = command === "build" || command === "serve" && viteMajor >= 8;
|
|
4161
|
-
return {
|
|
4162
|
-
enableSsrInitBootstrap: supported,
|
|
4163
|
-
injectSsrEntryLoader: supported
|
|
4164
|
-
};
|
|
4165
|
-
}
|
|
4166
|
-
//#endregion
|
|
4167
4251
|
//#region src/plugins/pluginProxyRemotes.ts
|
|
4168
4252
|
function isNodeModulesImporter(importer) {
|
|
4169
4253
|
return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
|
|
@@ -4537,26 +4621,7 @@ function applyRewrites(code, imports, id) {
|
|
|
4537
4621
|
const ms = new CodeRewriter(code);
|
|
4538
4622
|
let changed = false;
|
|
4539
4623
|
let counter = 0;
|
|
4540
|
-
let namedProxyHelperDeclared = false;
|
|
4541
4624
|
const dependencyPendingIds = [];
|
|
4542
|
-
const namedProxyHelper = `function __mfCreateNamedRemoteProxy(ns, key) {
|
|
4543
|
-
const target = function (...args) {
|
|
4544
|
-
const value = ns[key];
|
|
4545
|
-
return typeof value === "function" ? value.apply(this, args) : value;
|
|
4546
|
-
};
|
|
4547
|
-
return new Proxy(target, {
|
|
4548
|
-
get(_target, prop) {
|
|
4549
|
-
if (prop === "then") return undefined;
|
|
4550
|
-
const value = ns[key];
|
|
4551
|
-
if (prop === Symbol.toPrimitive) return () => value;
|
|
4552
|
-
const item = value == null ? undefined : value[prop];
|
|
4553
|
-
return typeof item === "function" ? item.bind(value) : item;
|
|
4554
|
-
},
|
|
4555
|
-
apply(target, thisArg, args) {
|
|
4556
|
-
return target.apply(thisArg, args);
|
|
4557
|
-
}
|
|
4558
|
-
});
|
|
4559
|
-
}`;
|
|
4560
4625
|
for (const imp of imports) switch (imp.kind) {
|
|
4561
4626
|
case "static": {
|
|
4562
4627
|
const src = JSON.stringify(imp.source);
|
|
@@ -4574,20 +4639,8 @@ function applyRewrites(code, imports, id) {
|
|
|
4574
4639
|
importParts.push(`__mf_remote_pending as ${pendingId}`);
|
|
4575
4640
|
let rewrite = `import { ${importParts.join(", ")} } from ${src};`;
|
|
4576
4641
|
if (imp.named.length > 0) {
|
|
4577
|
-
const
|
|
4578
|
-
|
|
4579
|
-
const destructParts = imp.named.map((s, index) => `${s.imported}: ${tempNames[index]}`);
|
|
4580
|
-
const bindingLines = imp.named.map((s, index) => {
|
|
4581
|
-
const temp = tempNames[index];
|
|
4582
|
-
return `const ${s.local} = ${isProxyId} ? __mfCreateNamedRemoteProxy(${nsId}, ${JSON.stringify(s.imported)}) : ${temp};`;
|
|
4583
|
-
});
|
|
4584
|
-
if (!namedProxyHelperDeclared) {
|
|
4585
|
-
rewrite += `\n${namedProxyHelper}`;
|
|
4586
|
-
namedProxyHelperDeclared = true;
|
|
4587
|
-
}
|
|
4588
|
-
rewrite += `\nconst ${isProxyId} = ${nsId} && ${nsId}.__mf_is_remote_proxy;`;
|
|
4589
|
-
rewrite += `\nconst { ${destructParts.join(", ")} } = ${isProxyId} ? {} : ${nsId};`;
|
|
4590
|
-
rewrite += `\n${bindingLines.join("\n")}`;
|
|
4642
|
+
const destructParts = imp.named.map((s) => `${s.imported}: ${s.local}`);
|
|
4643
|
+
rewrite += `\nconst { ${destructParts.join(", ")} } = ${nsId};`;
|
|
4591
4644
|
}
|
|
4592
4645
|
ms.overwrite(imp.start, imp.end, rewrite);
|
|
4593
4646
|
}
|
|
@@ -4844,6 +4897,104 @@ function pluginRemoteNamedExports(options) {
|
|
|
4844
4897
|
}
|
|
4845
4898
|
//#endregion
|
|
4846
4899
|
//#region src/plugins/pluginSSRRemoteEntry.ts
|
|
4900
|
+
const MAX_RUNNER_BODY_BYTES = 1024 * 1024;
|
|
4901
|
+
const ALLOWED_RUNNER_INVOKE_NAMES = new Set(["fetchModule", "getBuiltins"]);
|
|
4902
|
+
const VITE_FS_PREFIX = "/@fs/";
|
|
4903
|
+
function isPlainObject(value) {
|
|
4904
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
4905
|
+
}
|
|
4906
|
+
function stripQueryAndHash(id) {
|
|
4907
|
+
const queryIndex = id.indexOf("?");
|
|
4908
|
+
const hashIndex = id.indexOf("#");
|
|
4909
|
+
const endIndex = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
|
|
4910
|
+
return endIndex === -1 ? id : id.slice(0, endIndex);
|
|
4911
|
+
}
|
|
4912
|
+
function decodeRunnerFilePath(filePath) {
|
|
4913
|
+
try {
|
|
4914
|
+
return decodeURIComponent(filePath);
|
|
4915
|
+
} catch {
|
|
4916
|
+
return;
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
function hasRelativeTraversal(id) {
|
|
4920
|
+
return id.split(/[\\/]+/).includes("..");
|
|
4921
|
+
}
|
|
4922
|
+
function getRealPathIfExists(filePath) {
|
|
4923
|
+
try {
|
|
4924
|
+
return fs$1.realpathSync.native(filePath);
|
|
4925
|
+
} catch {
|
|
4926
|
+
return;
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
function isPathWithinDirectory(filePath, directory) {
|
|
4930
|
+
const realFilePath = getRealPathIfExists(filePath) ?? path$1.resolve(filePath);
|
|
4931
|
+
const realDirectory = getRealPathIfExists(directory) ?? path$1.resolve(directory);
|
|
4932
|
+
const relative = path$1.relative(realDirectory, realFilePath);
|
|
4933
|
+
return relative === "" || !relative.startsWith("..") && !path$1.isAbsolute(relative);
|
|
4934
|
+
}
|
|
4935
|
+
function getRunnerAllowedDirectories(config) {
|
|
4936
|
+
return [config.root, ...config.server?.fs?.allow ?? []].map((directory) => path$1.resolve(directory));
|
|
4937
|
+
}
|
|
4938
|
+
function isPathWithinAllowedDirectories(filePath, allowedDirectories) {
|
|
4939
|
+
return allowedDirectories.some((directory) => isPathWithinDirectory(filePath, directory));
|
|
4940
|
+
}
|
|
4941
|
+
function isSafeRunnerFetchModuleId(id, config) {
|
|
4942
|
+
if (typeof id !== "string" || !id || id.includes("\0")) return false;
|
|
4943
|
+
const decoded = decodeViteId(id).replace(/^\0+/, "");
|
|
4944
|
+
if (!decoded || decoded.startsWith("virtual:")) return !!decoded;
|
|
4945
|
+
if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(decoded) || decoded.startsWith("//")) return false;
|
|
4946
|
+
const cleanId = decodeRunnerFilePath(stripQueryAndHash(decoded));
|
|
4947
|
+
if (!cleanId || hasRelativeTraversal(cleanId)) return false;
|
|
4948
|
+
const allowedDirectories = getRunnerAllowedDirectories(config);
|
|
4949
|
+
if (cleanId.startsWith(VITE_FS_PREFIX)) {
|
|
4950
|
+
const fsPath = cleanId.slice(5);
|
|
4951
|
+
return path$1.isAbsolute(fsPath) && isPathWithinAllowedDirectories(fsPath, allowedDirectories);
|
|
4952
|
+
}
|
|
4953
|
+
if (path$1.isAbsolute(cleanId)) {
|
|
4954
|
+
if (isPathWithinAllowedDirectories(cleanId, allowedDirectories)) return true;
|
|
4955
|
+
return !fs$1.existsSync(cleanId);
|
|
4956
|
+
}
|
|
4957
|
+
return true;
|
|
4958
|
+
}
|
|
4959
|
+
function isRunnerInvokePayload(payload, config) {
|
|
4960
|
+
if (!payload || typeof payload !== "object") return false;
|
|
4961
|
+
if (payload.type !== "custom" || payload.event !== "vite:invoke") return false;
|
|
4962
|
+
const data = payload.data;
|
|
4963
|
+
if (!data || typeof data !== "object") return false;
|
|
4964
|
+
const name = data.name;
|
|
4965
|
+
const args = data.data;
|
|
4966
|
+
if (typeof name !== "string" || !ALLOWED_RUNNER_INVOKE_NAMES.has(name) || !Array.isArray(args)) return false;
|
|
4967
|
+
if (name === "getBuiltins") return args.length === 0;
|
|
4968
|
+
if (args.length < 1 || args.length > 3) return false;
|
|
4969
|
+
const [id, importer, opts] = args;
|
|
4970
|
+
return isSafeRunnerFetchModuleId(id, config) && (importer === void 0 || importer === null || isSafeRunnerFetchModuleId(importer, config)) && (opts === void 0 || isPlainObject(opts));
|
|
4971
|
+
}
|
|
4972
|
+
function readBoundedRunnerBody(req, res) {
|
|
4973
|
+
return new Promise((resolve) => {
|
|
4974
|
+
const chunks = [];
|
|
4975
|
+
let size = 0;
|
|
4976
|
+
let done = false;
|
|
4977
|
+
const fail = (statusCode, message) => {
|
|
4978
|
+
if (done) return;
|
|
4979
|
+
done = true;
|
|
4980
|
+
res.statusCode = statusCode;
|
|
4981
|
+
res.end(message);
|
|
4982
|
+
resolve(void 0);
|
|
4983
|
+
};
|
|
4984
|
+
req.on("data", (chunk) => {
|
|
4985
|
+
if (done) return;
|
|
4986
|
+
size += chunk.length;
|
|
4987
|
+
if (size > MAX_RUNNER_BODY_BYTES) return fail(413, "Payload too large");
|
|
4988
|
+
chunks.push(chunk);
|
|
4989
|
+
});
|
|
4990
|
+
req.on("end", () => {
|
|
4991
|
+
if (done) return;
|
|
4992
|
+
done = true;
|
|
4993
|
+
resolve(Buffer.concat(chunks));
|
|
4994
|
+
});
|
|
4995
|
+
req.on("error", () => fail(400, "Bad request"));
|
|
4996
|
+
});
|
|
4997
|
+
}
|
|
4847
4998
|
/**
|
|
4848
4999
|
* Emits a Node-compatible SSR remote entry alongside the browser entry.
|
|
4849
5000
|
*
|
|
@@ -4861,6 +5012,9 @@ function pluginSSRRemoteEntry(options) {
|
|
|
4861
5012
|
const virtualExposesSSRId = getVirtualExposesSSRId(options);
|
|
4862
5013
|
let isRolldown = false;
|
|
4863
5014
|
let ssrOutputFilename = "";
|
|
5015
|
+
let ssrOutputFiles = /* @__PURE__ */ new Set();
|
|
5016
|
+
let ssrOutputDir = "";
|
|
5017
|
+
let clientOutputDir = "";
|
|
4864
5018
|
const ssrOnlyExternals = [
|
|
4865
5019
|
"@module-federation/runtime",
|
|
4866
5020
|
"@module-federation/runtime-core",
|
|
@@ -4912,6 +5066,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
4912
5066
|
}
|
|
4913
5067
|
}, {
|
|
4914
5068
|
name: "mf:ssr-remote-entry",
|
|
5069
|
+
sharedDuringBuild: true,
|
|
4915
5070
|
configResolved(config) {
|
|
4916
5071
|
viteConfig = config;
|
|
4917
5072
|
isNuxtProject = isNuxtProjectRoot(config.root);
|
|
@@ -4926,7 +5081,8 @@ function pluginSSRRemoteEntry(options) {
|
|
|
4926
5081
|
});
|
|
4927
5082
|
const ssrEnv = server.environments?.ssr;
|
|
4928
5083
|
const clientEnv = server.environments?.client;
|
|
4929
|
-
|
|
5084
|
+
const runnerEnv = typeof ssrEnv?.hot?.handleInvoke === "function" ? ssrEnv : typeof clientEnv?.hot?.handleInvoke === "function" ? clientEnv : void 0;
|
|
5085
|
+
if (typeof (ssrEnv?.fetchModule ?? clientEnv?.fetchModule) === "function" && runnerEnv) server.middlewares.use("/__mf_runner__", async (req, res) => {
|
|
4930
5086
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
4931
5087
|
if (req.method === "OPTIONS") {
|
|
4932
5088
|
res.setHeader("Access-Control-Allow-Methods", "POST");
|
|
@@ -4941,46 +5097,37 @@ function pluginSSRRemoteEntry(options) {
|
|
|
4941
5097
|
return;
|
|
4942
5098
|
}
|
|
4943
5099
|
try {
|
|
4944
|
-
const
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
}
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
const builtins = (clientEnv ?? ssrEnv)?.config?.resolve?.builtins ?? [];
|
|
4953
|
-
res.setHeader("Content-Type", "application/json");
|
|
4954
|
-
res.end(JSON.stringify({ result: builtins }));
|
|
5100
|
+
const rawBody = await readBoundedRunnerBody(req, res);
|
|
5101
|
+
if (!rawBody) return;
|
|
5102
|
+
let body;
|
|
5103
|
+
try {
|
|
5104
|
+
body = JSON.parse(rawBody.toString("utf8"));
|
|
5105
|
+
} catch {
|
|
5106
|
+
res.statusCode = 400;
|
|
5107
|
+
res.end(JSON.stringify({ error: { message: "Invalid JSON" } }));
|
|
4955
5108
|
return;
|
|
4956
5109
|
}
|
|
4957
|
-
if (body.
|
|
5110
|
+
if (!isRunnerInvokePayload(body, server.config)) {
|
|
4958
5111
|
res.statusCode = 400;
|
|
4959
|
-
res.end(JSON.stringify({ error: { message:
|
|
5112
|
+
res.end(JSON.stringify({ error: { message: "Invalid runner invoke" } }));
|
|
4960
5113
|
return;
|
|
4961
5114
|
}
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
result = await fetchFn(id, importer, opts);
|
|
4968
|
-
} catch (fetchErr) {
|
|
4969
|
-
const bareId = decodeViteId(id);
|
|
4970
|
-
try {
|
|
5115
|
+
let result = await runnerEnv.hot.handleInvoke(body);
|
|
5116
|
+
if ("error" in result && body.data.name === "fetchModule") {
|
|
5117
|
+
const id = body.data.data[0];
|
|
5118
|
+
const bareId = typeof id === "string" ? decodeViteId(id).replace(/^\0/, "") : "";
|
|
5119
|
+
if (bareId && !bareId.startsWith(".") && !bareId.startsWith("/") && !bareId.startsWith("file:") && !/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(bareId)) try {
|
|
4971
5120
|
const { createRequire } = await import("module");
|
|
4972
5121
|
const path = await import("path");
|
|
4973
5122
|
const { pathToFileURL } = await import("url");
|
|
4974
|
-
result = {
|
|
4975
|
-
externalize: pathToFileURL(createRequire(pathToFileURL(path.join(server.config.root, "package.json"))).resolve(bareId
|
|
5123
|
+
result = { result: {
|
|
5124
|
+
externalize: pathToFileURL(createRequire(pathToFileURL(path.join(server.config.root, "package.json"))).resolve(bareId)).href,
|
|
4976
5125
|
type: "module"
|
|
4977
|
-
};
|
|
4978
|
-
} catch {
|
|
4979
|
-
throw fetchErr;
|
|
4980
|
-
}
|
|
5126
|
+
} };
|
|
5127
|
+
} catch {}
|
|
4981
5128
|
}
|
|
4982
5129
|
res.setHeader("Content-Type", "application/json");
|
|
4983
|
-
res.end(JSON.stringify(
|
|
5130
|
+
res.end(JSON.stringify(result));
|
|
4984
5131
|
} catch (e) {
|
|
4985
5132
|
res.setHeader("Content-Type", "application/json");
|
|
4986
5133
|
res.end(JSON.stringify({ error: { message: String(e instanceof Error ? e.message : e) } }));
|
|
@@ -5041,11 +5188,62 @@ function pluginSSRRemoteEntry(options) {
|
|
|
5041
5188
|
const exposesChunk = findNuxtExposesChunk(bundle);
|
|
5042
5189
|
const ssrAsset = bundle[ssrOutputFilename];
|
|
5043
5190
|
if (exposesChunk && ssrAsset?.type === "asset" && typeof ssrAsset.source === "string") ssrAsset.source = ssrAsset.source.replace(/import\("virtual:mf-exposes-ssr:[^"]+"\)/g, `import("./${exposesChunk}")`);
|
|
5191
|
+
if (this.environment?.name === "ssr") ssrOutputFiles = collectEntryOutputFiles(bundle, ssrOutputFilename);
|
|
5044
5192
|
if (!isRolldown) return;
|
|
5045
5193
|
const chunk = bundle[ssrOutputFilename];
|
|
5046
5194
|
if (!chunk || chunk.type !== "chunk") return;
|
|
5195
|
+
},
|
|
5196
|
+
writeBundle(outputOptions) {
|
|
5197
|
+
const environmentName = this.environment?.name;
|
|
5198
|
+
if (environmentName === "ssr" && outputOptions.dir) ssrOutputDir = outputOptions.dir;
|
|
5199
|
+
else if (environmentName === "client" && outputOptions.dir) clientOutputDir = outputOptions.dir;
|
|
5200
|
+
publishSsrOutputFiles(ssrOutputDir, clientOutputDir || viteConfig?.environments?.client?.build?.outDir);
|
|
5047
5201
|
}
|
|
5048
5202
|
}];
|
|
5203
|
+
function publishSsrOutputFiles(ssrOutDir, clientOutDir) {
|
|
5204
|
+
if (ssrOutputFiles.size === 0 || !ssrOutDir || !clientOutDir) return;
|
|
5205
|
+
const root = viteConfig?.root ?? process.cwd();
|
|
5206
|
+
const ssrDir = path$1.resolve(root, ssrOutDir);
|
|
5207
|
+
const clientDir = path$1.resolve(root, clientOutDir);
|
|
5208
|
+
if (ssrDir === clientDir || !fs$1.existsSync(ssrDir)) return;
|
|
5209
|
+
fs$1.mkdirSync(clientDir, { recursive: true });
|
|
5210
|
+
for (const fileName of ssrOutputFiles) {
|
|
5211
|
+
const source = path$1.resolve(ssrDir, fileName);
|
|
5212
|
+
const destination = path$1.resolve(clientDir, fileName);
|
|
5213
|
+
if (!isWithinDirectory(source, ssrDir) || !isWithinDirectory(destination, clientDir)) continue;
|
|
5214
|
+
if (!fs$1.existsSync(source) || fs$1.existsSync(destination)) continue;
|
|
5215
|
+
fs$1.mkdirSync(path$1.dirname(destination), { recursive: true });
|
|
5216
|
+
fs$1.copyFileSync(source, destination);
|
|
5217
|
+
}
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
const RELATIVE_IMPORT_RE = /(?:\bfrom|\bimport\s*(?:\(\s*)?|\bexport\s*\*\s*from)\s*["'`](\.\.?\/[^"'`]+)["'`]/g;
|
|
5221
|
+
function collectEntryOutputFiles(bundle, entryFileName) {
|
|
5222
|
+
const files = /* @__PURE__ */ new Set();
|
|
5223
|
+
const visit = (fileName) => {
|
|
5224
|
+
if (files.has(fileName)) return;
|
|
5225
|
+
const file = bundle[fileName];
|
|
5226
|
+
if (!file) return;
|
|
5227
|
+
files.add(fileName);
|
|
5228
|
+
const dependencies = new Set([
|
|
5229
|
+
...file.imports || [],
|
|
5230
|
+
...file.dynamicImports || [],
|
|
5231
|
+
...file.implicitlyLoadedBefore || [],
|
|
5232
|
+
...file.referencedFiles || []
|
|
5233
|
+
]);
|
|
5234
|
+
const source = typeof file.code === "string" ? file.code : typeof file.source === "string" ? file.source : "";
|
|
5235
|
+
if (source) {
|
|
5236
|
+
const directory = path$1.posix.dirname(fileName);
|
|
5237
|
+
for (const match of source.matchAll(RELATIVE_IMPORT_RE)) dependencies.add(path$1.posix.normalize(path$1.posix.join(directory, match[1])));
|
|
5238
|
+
}
|
|
5239
|
+
for (const dependency of dependencies) visit(dependency);
|
|
5240
|
+
};
|
|
5241
|
+
visit(entryFileName);
|
|
5242
|
+
return files;
|
|
5243
|
+
}
|
|
5244
|
+
function isWithinDirectory(filePath, directory) {
|
|
5245
|
+
const relative = path$1.relative(directory, filePath);
|
|
5246
|
+
return relative !== "" && !relative.startsWith(`..${path$1.sep}`) && relative !== "..";
|
|
5049
5247
|
}
|
|
5050
5248
|
//#endregion
|
|
5051
5249
|
//#region src/plugins/pluginVarRemoteEntry.ts
|
|
@@ -5367,14 +5565,32 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
5367
5565
|
optimizeDeps.rolldownOptions.plugins ??= [];
|
|
5368
5566
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
5369
5567
|
name: "module-federation:optimize-shared-resolver",
|
|
5568
|
+
load(id) {
|
|
5569
|
+
if (id !== "module-federation:optimized-require-react") return;
|
|
5570
|
+
const optimizedLoadSharePath = toViteOptimizedDepVirtualId(getLoadShareModulePath("react", isRolldown));
|
|
5571
|
+
const source = JSON.stringify(optimizedLoadSharePath);
|
|
5572
|
+
return "import * as __mfShared from " + source + ";\nexport * from " + source + ";\nexport default __mfShared.default ?? __mfShared;";
|
|
5573
|
+
},
|
|
5370
5574
|
resolveId(source, importer, options) {
|
|
5371
|
-
if (
|
|
5575
|
+
if (createViteEncodedIdPrefixRegExp("virtual:mf:").test(source)) return {
|
|
5576
|
+
id: source,
|
|
5577
|
+
external: true
|
|
5578
|
+
};
|
|
5372
5579
|
if (isSharedResolverInternalImporter(importer)) return;
|
|
5373
|
-
if (isCommonJsImporter(importer)) return;
|
|
5374
5580
|
const key = findSharedKey(source, shared);
|
|
5375
5581
|
if (!key) return;
|
|
5376
5582
|
if (source.endsWith(".css")) return;
|
|
5377
5583
|
const shareItem = shared[key];
|
|
5584
|
+
const isReactSingleton = source === "react" && key === "react" && shareItem.shareConfig?.singleton === true;
|
|
5585
|
+
const isReactRequire = options?.kind?.startsWith("require") && isReactSingleton;
|
|
5586
|
+
if (options?.kind?.startsWith("require") && !isReactSingleton) return;
|
|
5587
|
+
if (isCommonJsImporter(importer) && !isReactSingleton) return;
|
|
5588
|
+
if (isReactRequire) {
|
|
5589
|
+
writeLoadShareModule(source, shareItem, _command, isRolldown);
|
|
5590
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem);
|
|
5591
|
+
addUsedShares(source);
|
|
5592
|
+
return { id: "module-federation:optimized-require-react" };
|
|
5593
|
+
}
|
|
5378
5594
|
const loadSharePath = getLoadShareModulePath(source, isRolldown);
|
|
5379
5595
|
writeLoadShareModule(source, shareItem, _command, isRolldown);
|
|
5380
5596
|
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem);
|
|
@@ -5455,7 +5671,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5455
5671
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
5456
5672
|
optimizeDeps.include ??= [];
|
|
5457
5673
|
optimizeDeps.exclude ??= [];
|
|
5458
|
-
const shouldBypassOptimizeDep = isLitShare(key) || key === "react" &&
|
|
5674
|
+
const shouldBypassOptimizeDep = isLitShare(key) || key === "react" && shareItem.shareConfig?.singleton === true;
|
|
5459
5675
|
if (optimizeDeps.include.includes(key)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== key);
|
|
5460
5676
|
else if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
|
|
5461
5677
|
else optimizeDeps.include.push(key);
|
|
@@ -5510,7 +5726,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5510
5726
|
const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
5511
5727
|
function loadPluginDts(options) {
|
|
5512
5728
|
if (options.dts === false) return [];
|
|
5513
|
-
return [import("./pluginDts-
|
|
5729
|
+
return [import("./pluginDts-CTAHkt4C.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
|
|
5514
5730
|
}
|
|
5515
5731
|
function federation(mfUserOptions) {
|
|
5516
5732
|
if (isTestEnv()) return [];
|
|
@@ -5755,7 +5971,9 @@ function federation(mfUserOptions) {
|
|
|
5755
5971
|
},
|
|
5756
5972
|
load(id) {
|
|
5757
5973
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
5758
|
-
|
|
5974
|
+
const virtualModule = VirtualModule.findById(id);
|
|
5975
|
+
if (!virtualModule?.code) return null;
|
|
5976
|
+
let code = virtualModule.code;
|
|
5759
5977
|
const environmentName = this.environment?.name;
|
|
5760
5978
|
if (environmentName && environmentName !== "client" || !environmentName && isSsrBuild) code = prependWorkspaceSingletonSsrImport(code);
|
|
5761
5979
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
@@ -5839,7 +6057,15 @@ function federation(mfUserOptions) {
|
|
|
5839
6057
|
options.runtimePlugins.forEach((p) => {
|
|
5840
6058
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
5841
6059
|
if (SSR_ONLY_PLUGINS.has(pluginPath)) return;
|
|
5842
|
-
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:"))
|
|
6060
|
+
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) {
|
|
6061
|
+
let optimizeDep = pluginPath;
|
|
6062
|
+
if (pluginPath === "@module-federation/dts-plugin/dynamic-remote-type-hints-plugin") try {
|
|
6063
|
+
optimizeDep = normalizePathForImport(resolveImportPath(pluginPath));
|
|
6064
|
+
} catch {
|
|
6065
|
+
optimizeDep = pluginPath;
|
|
6066
|
+
}
|
|
6067
|
+
config.optimizeDeps.include.push(optimizeDep);
|
|
6068
|
+
}
|
|
5843
6069
|
});
|
|
5844
6070
|
if (isRolldown) {
|
|
5845
6071
|
config.build ??= {};
|