@module-federation/vite 1.15.2 → 1.15.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/index.cjs +189 -131
- package/lib/index.mjs +193 -135
- package/package.json +2 -1
package/lib/index.cjs
CHANGED
|
@@ -544,7 +544,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
544
544
|
shareConfig: {
|
|
545
545
|
import: shareItem.import,
|
|
546
546
|
singleton: shareItem.singleton || false,
|
|
547
|
-
requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
|
|
547
|
+
requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
|
|
548
548
|
strictVersion: !!shareItem.strictVersion
|
|
549
549
|
}
|
|
550
550
|
};
|
|
@@ -661,35 +661,6 @@ function normalizeModuleFederationOptions(options) {
|
|
|
661
661
|
}
|
|
662
662
|
//#endregion
|
|
663
663
|
//#region src/utils/VirtualModule.ts
|
|
664
|
-
/**
|
|
665
|
-
* Initialize virtual module infrastructure BEFORE VirtualModule class is used.
|
|
666
|
-
* This must be called in the config hook to ensure the directory exists
|
|
667
|
-
* before Vite's optimization phase.
|
|
668
|
-
*/
|
|
669
|
-
function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
|
|
670
|
-
const virtualPackagePath = (0, pathe.join)((0, pathe.join)(root, "node_modules"), virtualModuleDir);
|
|
671
|
-
(0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
|
|
672
|
-
(0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "empty.js"), "");
|
|
673
|
-
(0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "package.json"), JSON.stringify({
|
|
674
|
-
name: virtualModuleDir,
|
|
675
|
-
main: "empty.js"
|
|
676
|
-
}));
|
|
677
|
-
}
|
|
678
|
-
let rootDir;
|
|
679
|
-
function findNodeModulesDir(root = process.cwd()) {
|
|
680
|
-
let currentDir = root;
|
|
681
|
-
while (currentDir !== (0, pathe.parse)(currentDir).root) {
|
|
682
|
-
const nodeModulesPath = (0, pathe.join)(currentDir, "node_modules");
|
|
683
|
-
if ((0, fs.existsSync)(nodeModulesPath)) return nodeModulesPath;
|
|
684
|
-
currentDir = (0, pathe.dirname)(currentDir);
|
|
685
|
-
}
|
|
686
|
-
return "";
|
|
687
|
-
}
|
|
688
|
-
let cachedNodeModulesDir;
|
|
689
|
-
function getNodeModulesDir() {
|
|
690
|
-
if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
|
|
691
|
-
return cachedNodeModulesDir;
|
|
692
|
-
}
|
|
693
664
|
function getSuffix(name) {
|
|
694
665
|
const base = (0, pathe.basename)(name);
|
|
695
666
|
const dotIndex = base.lastIndexOf(".");
|
|
@@ -698,9 +669,6 @@ function getSuffix(name) {
|
|
|
698
669
|
}
|
|
699
670
|
const patternMap = {};
|
|
700
671
|
const cacheMap = {};
|
|
701
|
-
/**
|
|
702
|
-
* Physically generate files as virtual modules under node_modules/__mf__virtual/*
|
|
703
|
-
*/
|
|
704
672
|
function assertModuleFound(tag, str = "") {
|
|
705
673
|
const module = VirtualModule.findModule(tag, str);
|
|
706
674
|
if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
|
|
@@ -711,33 +679,16 @@ var VirtualModule = class {
|
|
|
711
679
|
tag;
|
|
712
680
|
suffix;
|
|
713
681
|
inited = false;
|
|
714
|
-
|
|
715
|
-
* Set the root path for finding node_modules
|
|
716
|
-
* @param root - Root path
|
|
717
|
-
*/
|
|
718
|
-
static setRoot(root) {
|
|
719
|
-
rootDir = root;
|
|
720
|
-
cachedNodeModulesDir = void 0;
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Ensure virtual package directory exists
|
|
724
|
-
*/
|
|
725
|
-
static ensureVirtualPackageExists() {
|
|
726
|
-
const nodeModulesDir = getNodeModulesDir();
|
|
727
|
-
const { virtualModuleDir } = getNormalizeModuleFederationOptions();
|
|
728
|
-
const virtualPackagePath = (0, pathe.resolve)(nodeModulesDir, virtualModuleDir);
|
|
729
|
-
(0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
|
|
730
|
-
(0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "empty.js"), "");
|
|
731
|
-
(0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "package.json"), JSON.stringify({
|
|
732
|
-
name: virtualModuleDir,
|
|
733
|
-
main: "empty.js"
|
|
734
|
-
}));
|
|
735
|
-
}
|
|
682
|
+
code;
|
|
736
683
|
static findModule(tag, str = "") {
|
|
737
684
|
if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
|
|
738
685
|
const moduleName = (str.match(patternMap[tag]) || [])[2];
|
|
739
686
|
if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
|
|
740
687
|
}
|
|
688
|
+
static findById(id) {
|
|
689
|
+
const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
|
|
690
|
+
for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
|
|
691
|
+
}
|
|
741
692
|
constructor(name, tag = "__mf_v__", suffix = "") {
|
|
742
693
|
this.name = name;
|
|
743
694
|
this.tag = tag;
|
|
@@ -745,24 +696,20 @@ var VirtualModule = class {
|
|
|
745
696
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
746
697
|
cacheMap[this.tag][this.name] = this;
|
|
747
698
|
}
|
|
748
|
-
getPath() {
|
|
749
|
-
return (0, pathe.resolve)(getNodeModulesDir(), this.getImportId());
|
|
750
|
-
}
|
|
751
699
|
getImportId() {
|
|
752
|
-
const { internalName: mfName
|
|
753
|
-
return
|
|
700
|
+
const { internalName: mfName } = getNormalizeModuleFederationOptions();
|
|
701
|
+
return `virtual:mf:${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
|
|
702
|
+
}
|
|
703
|
+
getResolvedId() {
|
|
704
|
+
return `\0${this.getImportId()}`;
|
|
754
705
|
}
|
|
755
706
|
writeSync(code, force) {
|
|
756
707
|
if (!force && this.inited) return;
|
|
757
708
|
if (!this.inited) this.inited = true;
|
|
758
|
-
|
|
759
|
-
(0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
|
|
760
|
-
(0, fs.writeFileSync)(path, code);
|
|
709
|
+
this.code = code;
|
|
761
710
|
}
|
|
762
711
|
write(code) {
|
|
763
|
-
|
|
764
|
-
(0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
|
|
765
|
-
(0, fs.writeFile)(path, code, function() {});
|
|
712
|
+
this.writeSync(code, true);
|
|
766
713
|
}
|
|
767
714
|
};
|
|
768
715
|
//#endregion
|
|
@@ -964,6 +911,14 @@ globalThis[__mfCacheGlobalKey].remote ||= {};
|
|
|
964
911
|
const __mfModuleCache = globalThis[__mfCacheGlobalKey];
|
|
965
912
|
`;
|
|
966
913
|
}
|
|
914
|
+
function getRuntimeInitPromiseBootstrapCode() {
|
|
915
|
+
return getRuntimeInitStateBootstrapCode({
|
|
916
|
+
globalKeyVar: "__mfPromiseGlobalKey",
|
|
917
|
+
stateVar: "__mfPromiseState",
|
|
918
|
+
exposedConst: "initPromise",
|
|
919
|
+
exposedProperty: "initPromise"
|
|
920
|
+
});
|
|
921
|
+
}
|
|
967
922
|
function getRuntimeInitResolveBootstrapCode() {
|
|
968
923
|
return getRuntimeInitStateBootstrapCode({
|
|
969
924
|
globalKeyVar: "__mfResolveGlobalKey",
|
|
@@ -1208,6 +1163,20 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1208
1163
|
export const jsx = __mfPrebuildExports.jsx;
|
|
1209
1164
|
export const jsxs = __mfPrebuildExports.jsxs;
|
|
1210
1165
|
export default __mfPrebuildExports;
|
|
1166
|
+
`, true);
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
const namedExports = getPackageNamedExports(pkg);
|
|
1170
|
+
if (namedExports.length > 0) {
|
|
1171
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1172
|
+
const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
|
|
1173
|
+
const namedExportLine = `export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };`;
|
|
1174
|
+
preBuildCacheMap[pkg].writeSync(`
|
|
1175
|
+
import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
|
|
1176
|
+
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1177
|
+
${declarations}
|
|
1178
|
+
${namedExportLine}
|
|
1179
|
+
export default __mfPrebuildExports;
|
|
1211
1180
|
`, true);
|
|
1212
1181
|
return;
|
|
1213
1182
|
}
|
|
@@ -1235,25 +1204,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
|
|
|
1235
1204
|
}
|
|
1236
1205
|
function getLoadShareModulePath(pkg, isRolldown) {
|
|
1237
1206
|
if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
|
|
1238
|
-
return loadShareCacheMap[pkg].
|
|
1207
|
+
return loadShareCacheMap[pkg].getImportId();
|
|
1239
1208
|
}
|
|
1209
|
+
function generateDeferredHostProvidedExports(namedExports, pkg) {
|
|
1210
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1211
|
+
const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
|
|
1212
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
1213
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1214
|
+
return `${declarations}
|
|
1215
|
+
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1216
|
+
${assignments}
|
|
1217
|
+
};
|
|
1218
|
+
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1219
|
+
if (exportModule === undefined) {
|
|
1220
|
+
initPromise.then(() => {
|
|
1221
|
+
exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1222
|
+
if (exportModule === undefined) {
|
|
1223
|
+
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1224
|
+
}
|
|
1225
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1226
|
+
});
|
|
1227
|
+
} else {
|
|
1228
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1229
|
+
}
|
|
1230
|
+
export { __mf_default as default };${namedExportLine}`;
|
|
1231
|
+
}
|
|
1232
|
+
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1233
|
+
return `let current = ${source};
|
|
1234
|
+
for (let i = 0; i < 5; i++) {
|
|
1235
|
+
const defaultExport = current?.default;
|
|
1236
|
+
${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
|
|
1237
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1238
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
|
|
1239
|
+
current = defaultExport;
|
|
1240
|
+
}
|
|
1241
|
+
return current;`;
|
|
1242
|
+
}
|
|
1243
|
+
const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
|
|
1244
|
+
${generateShareModuleUnwrapCode({
|
|
1245
|
+
source: "mod",
|
|
1246
|
+
preserveNamedExports: true
|
|
1247
|
+
})}
|
|
1248
|
+
};`;
|
|
1240
1249
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
1241
1250
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
|
|
1242
1251
|
const importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1243
1252
|
if (shareItem.shareConfig.import === false) {
|
|
1244
1253
|
const namedExports = getPackageNamedExports(pkg);
|
|
1245
1254
|
let exportLine;
|
|
1246
|
-
if (namedExports.length > 0) exportLine =
|
|
1255
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
|
|
1247
1256
|
else {
|
|
1248
1257
|
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.`);
|
|
1249
|
-
exportLine =
|
|
1258
|
+
exportLine = generateDeferredHostProvidedExports([], pkg);
|
|
1250
1259
|
}
|
|
1251
1260
|
loadShareCacheMap[pkg].writeSync(`
|
|
1261
|
+
${getRuntimeInitPromiseBootstrapCode()}
|
|
1252
1262
|
${importLine}
|
|
1253
|
-
const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1254
|
-
if (exportModule === undefined) {
|
|
1255
|
-
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
|
|
1256
|
-
}
|
|
1257
1263
|
${exportLine}
|
|
1258
1264
|
`, true);
|
|
1259
1265
|
return;
|
|
@@ -1268,8 +1274,20 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1268
1274
|
const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
1269
1275
|
const namedExports = getPackageNamedExports(pkg);
|
|
1270
1276
|
let exportLine;
|
|
1271
|
-
if (namedExports.length > 0)
|
|
1272
|
-
|
|
1277
|
+
if (namedExports.length > 0) {
|
|
1278
|
+
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1279
|
+
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
1280
|
+
exportLine = `const __mfDefaultExport = (() => {
|
|
1281
|
+
${generateShareModuleUnwrapCode({
|
|
1282
|
+
source: "exportModule",
|
|
1283
|
+
preserveNamedExports: false,
|
|
1284
|
+
stopWithReturn: "defaultExport ?? current"
|
|
1285
|
+
})}
|
|
1286
|
+
})();
|
|
1287
|
+
export default __mfDefaultExport;
|
|
1288
|
+
${destructure}
|
|
1289
|
+
${namedExportLine}`;
|
|
1290
|
+
} else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
|
|
1273
1291
|
else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
1274
1292
|
const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1275
1293
|
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
@@ -1277,10 +1295,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1277
1295
|
${prebuildImportLine}
|
|
1278
1296
|
${devDynamicImportLine}
|
|
1279
1297
|
${importLine}
|
|
1298
|
+
${normalizeLocalShareModuleCode}
|
|
1280
1299
|
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1281
1300
|
if (exportModule === undefined) {
|
|
1282
|
-
${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
|
|
1283
|
-
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
|
|
1301
|
+
${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
|
|
1302
|
+
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1284
1303
|
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
|
|
1285
1304
|
}
|
|
1286
1305
|
${exportLine}
|
|
@@ -1438,9 +1457,9 @@ function getShareItemForPreload(pkg) {
|
|
|
1438
1457
|
function generateSharedCacheSeedItem(pkg, importPath) {
|
|
1439
1458
|
return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
|
|
1440
1459
|
const mod = await import(${JSON.stringify(importPath)});
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1460
|
+
${normalizeRuntimeShareCode}
|
|
1461
|
+
const normalizedModule = __mfNormalizeRuntimeShare(mod);
|
|
1462
|
+
const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
|
|
1444
1463
|
Object.defineProperty(exportModule, "__esModule", {
|
|
1445
1464
|
value: true,
|
|
1446
1465
|
enumerable: false
|
|
@@ -1448,6 +1467,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
|
|
|
1448
1467
|
__mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
|
|
1449
1468
|
}`;
|
|
1450
1469
|
}
|
|
1470
|
+
const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
1471
|
+
let current = mod;
|
|
1472
|
+
for (let i = 0; i < 5; i++) {
|
|
1473
|
+
const defaultExport = current?.default;
|
|
1474
|
+
if (!defaultExport || typeof defaultExport !== "object") break;
|
|
1475
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1476
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
|
|
1477
|
+
current = defaultExport;
|
|
1478
|
+
}
|
|
1479
|
+
return current;
|
|
1480
|
+
};`;
|
|
1451
1481
|
function generateDirectSharedCacheSeedCode(command = "build") {
|
|
1452
1482
|
return getOrderedUsedShares().map((pkg) => {
|
|
1453
1483
|
const shareItem = getShareItemForPreload(pkg);
|
|
@@ -1470,7 +1500,8 @@ function getHostAutoInitSharedSeedItems() {
|
|
|
1470
1500
|
return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
|
|
1471
1501
|
});
|
|
1472
1502
|
}
|
|
1473
|
-
function generateHostAutoInitSharedCacheSeedCode() {
|
|
1503
|
+
function generateHostAutoInitSharedCacheSeedCode(command = "build") {
|
|
1504
|
+
if (command === "build") return "";
|
|
1474
1505
|
return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
|
|
1475
1506
|
if (!shareItem) return null;
|
|
1476
1507
|
return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
|
|
@@ -1502,14 +1533,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1502
1533
|
if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
|
|
1503
1534
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
1504
1535
|
}
|
|
1505
|
-
import {
|
|
1536
|
+
import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
|
|
1506
1537
|
${pluginImportNames.map((item) => item[1]).join("\n")}
|
|
1507
1538
|
${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
|
|
1508
1539
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
1509
1540
|
const initTokens = {}
|
|
1510
1541
|
const shareScopeName = ${JSON.stringify(options.shareScope)}
|
|
1511
1542
|
const mfName = ${JSON.stringify(options.internalName)}
|
|
1512
|
-
let runtimeInstance
|
|
1513
1543
|
let localSharedImportMapPromise
|
|
1514
1544
|
let exposesMapPromise
|
|
1515
1545
|
const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
|
|
@@ -1552,19 +1582,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1552
1582
|
async function init(shared = {}, initScope = []) {
|
|
1553
1583
|
const {usedShared, usedRemotes} = await getLocalSharedImportMap()
|
|
1554
1584
|
${generateDirectSharedCacheSeedCode(command)}
|
|
1555
|
-
const
|
|
1585
|
+
const initRes = runtimeInit({
|
|
1556
1586
|
name: mfName,
|
|
1557
1587
|
remotes: usedRemotes,
|
|
1558
1588
|
shared: usedShared,
|
|
1559
1589
|
plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
|
|
1560
1590
|
${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
|
|
1561
|
-
};
|
|
1562
|
-
if (!runtimeInstance) {
|
|
1563
|
-
runtimeInstance = createInstance(runtimeOptions);
|
|
1564
|
-
} else {
|
|
1565
|
-
runtimeInstance.initOptions(runtimeOptions);
|
|
1566
|
-
}
|
|
1567
|
-
const initRes = runtimeInstance;
|
|
1591
|
+
});
|
|
1568
1592
|
// handling circular init calls
|
|
1569
1593
|
var initToken = initTokens[shareScopeName];
|
|
1570
1594
|
if (!initToken)
|
|
@@ -1584,6 +1608,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1584
1608
|
} catch (e) {
|
|
1585
1609
|
console.error('[Module Federation]', e)
|
|
1586
1610
|
}
|
|
1611
|
+
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1612
|
+
if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
|
|
1613
|
+
${normalizeRuntimeShareCode}
|
|
1614
|
+
const versions = shared?.[pkg];
|
|
1615
|
+
const provider = versions && versions[Object.keys(versions)[0]];
|
|
1616
|
+
if (!provider) continue;
|
|
1617
|
+
const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
|
|
1618
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
1619
|
+
const resolved = await Promise.resolve(mod);
|
|
1620
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1621
|
+
}
|
|
1587
1622
|
return initRes
|
|
1588
1623
|
}
|
|
1589
1624
|
|
|
@@ -1608,10 +1643,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1608
1643
|
async function initHost() {
|
|
1609
1644
|
if (!hostInitPromise) {
|
|
1610
1645
|
hostInitPromise = (async () => {
|
|
1611
|
-
${generateHostAutoInitSharedCacheSeedCode()}
|
|
1646
|
+
${generateHostAutoInitSharedCacheSeedCode(_command)}
|
|
1612
1647
|
const remoteEntry = await import(${remoteEntryImport});
|
|
1613
1648
|
const runtime = await remoteEntry.init();
|
|
1614
1649
|
const usedShared = ${generateUsedSharedPreloadConfig()};
|
|
1650
|
+
${normalizeRuntimeShareCode}
|
|
1615
1651
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1616
1652
|
if (__mfModuleCache.share[pkg] !== undefined) {
|
|
1617
1653
|
continue;
|
|
@@ -1621,7 +1657,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1621
1657
|
}).then((factory) => {
|
|
1622
1658
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
1623
1659
|
return Promise.resolve(mod).then((resolved) => {
|
|
1624
|
-
__mfModuleCache.share[pkg] = resolved;
|
|
1660
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1625
1661
|
});
|
|
1626
1662
|
});
|
|
1627
1663
|
}
|
|
@@ -1650,7 +1686,7 @@ function getHostAutoInitImportId() {
|
|
|
1650
1686
|
return hostAutoInitModule.getImportId();
|
|
1651
1687
|
}
|
|
1652
1688
|
function getHostAutoInitPath() {
|
|
1653
|
-
return hostAutoInitModule.
|
|
1689
|
+
return hostAutoInitModule.getImportId();
|
|
1654
1690
|
}
|
|
1655
1691
|
//#endregion
|
|
1656
1692
|
//#region src/virtualModules/virtualRemotes.ts
|
|
@@ -1673,7 +1709,9 @@ function getUsedRemotesMap() {
|
|
|
1673
1709
|
}
|
|
1674
1710
|
function generateRemotes(id, command) {
|
|
1675
1711
|
const useReactProxy = command === "serve" && hasPackageDependency("react");
|
|
1676
|
-
const reactImportLine = useReactProxy ? `import
|
|
1712
|
+
const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
|
|
1713
|
+
import * as __mfReactNamespace from "react";
|
|
1714
|
+
const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
|
|
1677
1715
|
const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
|
|
1678
1716
|
import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
|
|
1679
1717
|
const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
|
|
@@ -1683,13 +1721,13 @@ function generateRemotes(id, command) {
|
|
|
1683
1721
|
}
|
|
1684
1722
|
export const __moduleExports = exportModule;
|
|
1685
1723
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1686
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1724
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1687
1725
|
const mod = await __mfRemotePending;
|
|
1688
1726
|
if (mod !== undefined) exportModule = mod;
|
|
1689
1727
|
}
|
|
1690
1728
|
export const __moduleExports = exportModule;
|
|
1691
1729
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1692
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1730
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1693
1731
|
return `
|
|
1694
1732
|
${reactImportLine}
|
|
1695
1733
|
${importLine}
|
|
@@ -1889,6 +1927,9 @@ ${importHelper}(async () => {
|
|
|
1889
1927
|
if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
|
|
1890
1928
|
return inject === "entry" || !htmlFilePath;
|
|
1891
1929
|
}
|
|
1930
|
+
function normalizeDevHtmlProxyId(id) {
|
|
1931
|
+
return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
|
|
1932
|
+
}
|
|
1892
1933
|
return [{
|
|
1893
1934
|
name: "add-entry",
|
|
1894
1935
|
apply: "serve",
|
|
@@ -1907,7 +1948,20 @@ ${importHelper}(async () => {
|
|
|
1907
1948
|
}
|
|
1908
1949
|
},
|
|
1909
1950
|
configureServer(server) {
|
|
1910
|
-
server.middlewares.use((req,
|
|
1951
|
+
server.middlewares.use((req, res, next) => {
|
|
1952
|
+
const rawUrl = req.url?.split("#")[0] ?? "";
|
|
1953
|
+
if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
|
|
1954
|
+
const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
|
|
1955
|
+
const params = new URLSearchParams(query);
|
|
1956
|
+
const initSrc = params.get("init");
|
|
1957
|
+
const entrySrc = params.get("entry");
|
|
1958
|
+
if (initSrc && entrySrc) {
|
|
1959
|
+
res.statusCode = 200;
|
|
1960
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
1961
|
+
res.end(getBootstrapSource(initSrc, entrySrc));
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1911
1965
|
if (!fileName) {
|
|
1912
1966
|
next();
|
|
1913
1967
|
return;
|
|
@@ -1924,7 +1978,7 @@ ${importHelper}(async () => {
|
|
|
1924
1978
|
const base = viteConfig.base.replace(/\/$/, "");
|
|
1925
1979
|
const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
|
|
1926
1980
|
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
1927
|
-
return `/@id
|
|
1981
|
+
return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
1928
1982
|
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
1929
1983
|
entry: sanitizeDevEntryPath(stripBase(originalSrc))
|
|
1930
1984
|
}).toString()}`;
|
|
@@ -1933,11 +1987,12 @@ ${importHelper}(async () => {
|
|
|
1933
1987
|
}
|
|
1934
1988
|
},
|
|
1935
1989
|
resolveId(id) {
|
|
1936
|
-
if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1990
|
+
if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1937
1991
|
},
|
|
1938
1992
|
load(id) {
|
|
1939
|
-
|
|
1940
|
-
|
|
1993
|
+
const normalizedId = normalizeDevHtmlProxyId(id);
|
|
1994
|
+
if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
|
|
1995
|
+
const params = new URLSearchParams(normalizedId.slice(28));
|
|
1941
1996
|
const initSrc = params.get("init");
|
|
1942
1997
|
const entrySrc = params.get("entry");
|
|
1943
1998
|
if (!initSrc || !entrySrc) return;
|
|
@@ -2744,7 +2799,7 @@ function collectSystemProxyInfos(proxyChunks, loadShareTag) {
|
|
|
2744
2799
|
for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
|
|
2745
2800
|
const exported = m[1];
|
|
2746
2801
|
const expression = m[2];
|
|
2747
|
-
for (const [local, exportName] of Object.entries(loadShareBindings)) if (new RegExp(`\\b${local}\\b`).test(expression)) {
|
|
2802
|
+
for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
|
|
2748
2803
|
exportMap[exported] = {
|
|
2749
2804
|
type: "reexport",
|
|
2750
2805
|
exportName
|
|
@@ -3508,7 +3563,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
3508
3563
|
const remoteModule = getRemoteVirtualModule(source, command);
|
|
3509
3564
|
addUsedRemote(remoteName, source);
|
|
3510
3565
|
refreshHostAutoInit();
|
|
3511
|
-
return remoteModule.
|
|
3566
|
+
return remoteModule.getImportId();
|
|
3512
3567
|
}
|
|
3513
3568
|
return {
|
|
3514
3569
|
name: "proxyRemotes",
|
|
@@ -4330,12 +4385,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
4330
4385
|
return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
|
|
4331
4386
|
}
|
|
4332
4387
|
/**
|
|
4333
|
-
* Plugin that runs FIRST to
|
|
4334
|
-
* This prevents 504 "Outdated Optimize Dep" errors by ensuring
|
|
4388
|
+
* Plugin that runs FIRST to register generated virtual modules in the config hook.
|
|
4389
|
+
* This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
|
|
4335
4390
|
* before Vite's optimization phase.
|
|
4336
4391
|
*/
|
|
4337
4392
|
function createEarlyVirtualModulesPlugin(options) {
|
|
4338
|
-
const { shared, remotes
|
|
4393
|
+
const { shared, remotes } = options;
|
|
4339
4394
|
const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
|
|
4340
4395
|
return {
|
|
4341
4396
|
name: "vite:module-federation-early-init",
|
|
@@ -4345,9 +4400,6 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
4345
4400
|
const root = config.root || process.cwd();
|
|
4346
4401
|
setPackageDetectionCwd(root);
|
|
4347
4402
|
const isVinext = hasPackageDependency("vinext");
|
|
4348
|
-
initVirtualModuleInfrastructure(root, virtualModuleDir);
|
|
4349
|
-
VirtualModule.setRoot(root);
|
|
4350
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
4351
4403
|
initVirtualModules(_command, getRemoteEntryId(options));
|
|
4352
4404
|
const isRolldown = getIsRolldown(this);
|
|
4353
4405
|
if (remotes && Object.keys(remotes).length > 0) {
|
|
@@ -4393,6 +4445,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
4393
4445
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
4394
4446
|
name: "module-federation:optimize-shared-proxy",
|
|
4395
4447
|
setup(build) {
|
|
4448
|
+
build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
|
|
4449
|
+
path: args.path,
|
|
4450
|
+
external: true
|
|
4451
|
+
}));
|
|
4396
4452
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
4397
4453
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
4398
4454
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
@@ -4424,7 +4480,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4424
4480
|
}
|
|
4425
4481
|
});
|
|
4426
4482
|
}
|
|
4427
|
-
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
4428
4483
|
}
|
|
4429
4484
|
for (const key of Object.keys(shared)) {
|
|
4430
4485
|
const shareItem = shared[key];
|
|
@@ -4435,7 +4490,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4435
4490
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4436
4491
|
writePreBuildLibPath(subpath, shareItem);
|
|
4437
4492
|
optimizeDeps.include.push(subpath);
|
|
4438
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4439
4493
|
}
|
|
4440
4494
|
}
|
|
4441
4495
|
continue;
|
|
@@ -4452,14 +4506,11 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4452
4506
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
4453
4507
|
optimizeDeps.include ??= [];
|
|
4454
4508
|
optimizeDeps.exclude ??= [];
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
|
|
4458
|
-
optimizeDeps.include.push(getPreBuildLibImportId(key));
|
|
4509
|
+
if (isLitShare(key)) optimizeDeps.exclude.push(key);
|
|
4510
|
+
else optimizeDeps.include.push(key);
|
|
4459
4511
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4460
4512
|
writePreBuildLibPath(subpath, shareItem);
|
|
4461
4513
|
optimizeDeps.include.push(subpath);
|
|
4462
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4463
4514
|
}
|
|
4464
4515
|
}
|
|
4465
4516
|
}
|
|
@@ -4479,6 +4530,21 @@ function federation(mfUserOptions) {
|
|
|
4479
4530
|
let command;
|
|
4480
4531
|
let desiredRolldownOutput;
|
|
4481
4532
|
return [
|
|
4533
|
+
{
|
|
4534
|
+
name: "vite:module-federation-virtual-modules",
|
|
4535
|
+
enforce: "pre",
|
|
4536
|
+
resolveId(id) {
|
|
4537
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4538
|
+
if (!virtualModule) return;
|
|
4539
|
+
return virtualModule.getResolvedId();
|
|
4540
|
+
},
|
|
4541
|
+
load(id) {
|
|
4542
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4543
|
+
if (!virtualModule) return;
|
|
4544
|
+
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
4545
|
+
return virtualModule.code;
|
|
4546
|
+
}
|
|
4547
|
+
},
|
|
4482
4548
|
createEarlyVirtualModulesPlugin(options),
|
|
4483
4549
|
...isVinext ? [{
|
|
4484
4550
|
name: "module-federation-vinext-react-server-build-alias",
|
|
@@ -4503,9 +4569,7 @@ function federation(mfUserOptions) {
|
|
|
4503
4569
|
config(_config, env) {
|
|
4504
4570
|
command = env.command;
|
|
4505
4571
|
},
|
|
4506
|
-
configResolved(
|
|
4507
|
-
VirtualModule.setRoot(config.root);
|
|
4508
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
4572
|
+
configResolved() {
|
|
4509
4573
|
initVirtualModules(command, remoteEntryId);
|
|
4510
4574
|
}
|
|
4511
4575
|
},
|
|
@@ -4648,9 +4712,8 @@ function federation(mfUserOptions) {
|
|
|
4648
4712
|
}
|
|
4649
4713
|
},
|
|
4650
4714
|
load(id) {
|
|
4651
|
-
if (id.startsWith("\0")) return;
|
|
4652
4715
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
4653
|
-
let code = (0, fs.readFileSync)(id, "utf-8");
|
|
4716
|
+
let code = VirtualModule.findById(id)?.code ?? (0, fs.readFileSync)(id, "utf-8");
|
|
4654
4717
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4655
4718
|
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4656
4719
|
/**
|
|
@@ -4669,7 +4732,10 @@ function federation(mfUserOptions) {
|
|
|
4669
4732
|
*
|
|
4670
4733
|
* @see https://rollupjs.org/plugin-development/#synthetic-named-exports
|
|
4671
4734
|
*/
|
|
4672
|
-
if (
|
|
4735
|
+
if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
|
|
4736
|
+
const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
|
|
4737
|
+
code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
|
|
4738
|
+
}
|
|
4673
4739
|
if (getIsRolldown(this)) return { code };
|
|
4674
4740
|
return {
|
|
4675
4741
|
code,
|
|
@@ -4734,14 +4800,9 @@ function federation(mfUserOptions) {
|
|
|
4734
4800
|
config.build ||= {};
|
|
4735
4801
|
config.build.commonjsOptions ||= {};
|
|
4736
4802
|
config.build.commonjsOptions.strictRequires ??= "auto";
|
|
4737
|
-
const virtualDir = options.virtualModuleDir;
|
|
4738
4803
|
config.optimizeDeps ||= {};
|
|
4739
4804
|
config.optimizeDeps.include ||= [];
|
|
4740
4805
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
4741
|
-
if (!isRolldown) config.optimizeDeps.include.push(virtualDir);
|
|
4742
|
-
config.ssr ||= {};
|
|
4743
|
-
config.ssr.noExternal ||= [];
|
|
4744
|
-
if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
|
|
4745
4806
|
options.runtimePlugins.forEach((p) => {
|
|
4746
4807
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
4747
4808
|
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
|
|
@@ -4749,9 +4810,6 @@ function federation(mfUserOptions) {
|
|
|
4749
4810
|
if (isRolldown) {
|
|
4750
4811
|
config.build ??= {};
|
|
4751
4812
|
config.build.target ??= "esnext";
|
|
4752
|
-
} else {
|
|
4753
|
-
config.optimizeDeps.needsInterop ||= [];
|
|
4754
|
-
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
4755
4813
|
}
|
|
4756
4814
|
const isAstro = hasPackageDependency("astro");
|
|
4757
4815
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
package/lib/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import * as fs$1 from "fs";
|
|
3
|
-
import fs, { existsSync,
|
|
3
|
+
import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
4
4
|
import { createRequire as createRequire$1 } from "module";
|
|
5
5
|
import * as path$1 from "pathe";
|
|
6
|
-
import path, { basename
|
|
6
|
+
import path, { basename } from "pathe";
|
|
7
7
|
import { normalizeOptions } from "@module-federation/sdk";
|
|
8
8
|
import { consumeTypesAPI, generateTypesAPI, isTSProject, normalizeConsumeTypesOptions, normalizeDtsOptions, normalizeGenerateTypesOptions } from "@module-federation/dts-plugin";
|
|
9
9
|
import { rpc } from "@module-federation/dts-plugin/core";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
|
-
import { init, parse
|
|
11
|
+
import { init, parse } from "es-module-lexer";
|
|
12
12
|
//#region \0rolldown/runtime.js
|
|
13
13
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
14
14
|
//#endregion
|
|
@@ -524,7 +524,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
524
524
|
shareConfig: {
|
|
525
525
|
import: shareItem.import,
|
|
526
526
|
singleton: shareItem.singleton || false,
|
|
527
|
-
requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
|
|
527
|
+
requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
|
|
528
528
|
strictVersion: !!shareItem.strictVersion
|
|
529
529
|
}
|
|
530
530
|
};
|
|
@@ -641,35 +641,6 @@ function normalizeModuleFederationOptions(options) {
|
|
|
641
641
|
}
|
|
642
642
|
//#endregion
|
|
643
643
|
//#region src/utils/VirtualModule.ts
|
|
644
|
-
/**
|
|
645
|
-
* Initialize virtual module infrastructure BEFORE VirtualModule class is used.
|
|
646
|
-
* This must be called in the config hook to ensure the directory exists
|
|
647
|
-
* before Vite's optimization phase.
|
|
648
|
-
*/
|
|
649
|
-
function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
|
|
650
|
-
const virtualPackagePath = join(join(root, "node_modules"), virtualModuleDir);
|
|
651
|
-
mkdirSync(virtualPackagePath, { recursive: true });
|
|
652
|
-
writeFileSync(join(virtualPackagePath, "empty.js"), "");
|
|
653
|
-
writeFileSync(join(virtualPackagePath, "package.json"), JSON.stringify({
|
|
654
|
-
name: virtualModuleDir,
|
|
655
|
-
main: "empty.js"
|
|
656
|
-
}));
|
|
657
|
-
}
|
|
658
|
-
let rootDir;
|
|
659
|
-
function findNodeModulesDir(root = process.cwd()) {
|
|
660
|
-
let currentDir = root;
|
|
661
|
-
while (currentDir !== parse(currentDir).root) {
|
|
662
|
-
const nodeModulesPath = join(currentDir, "node_modules");
|
|
663
|
-
if (existsSync(nodeModulesPath)) return nodeModulesPath;
|
|
664
|
-
currentDir = dirname(currentDir);
|
|
665
|
-
}
|
|
666
|
-
return "";
|
|
667
|
-
}
|
|
668
|
-
let cachedNodeModulesDir;
|
|
669
|
-
function getNodeModulesDir() {
|
|
670
|
-
if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
|
|
671
|
-
return cachedNodeModulesDir;
|
|
672
|
-
}
|
|
673
644
|
function getSuffix(name) {
|
|
674
645
|
const base = basename(name);
|
|
675
646
|
const dotIndex = base.lastIndexOf(".");
|
|
@@ -678,9 +649,6 @@ function getSuffix(name) {
|
|
|
678
649
|
}
|
|
679
650
|
const patternMap = {};
|
|
680
651
|
const cacheMap = {};
|
|
681
|
-
/**
|
|
682
|
-
* Physically generate files as virtual modules under node_modules/__mf__virtual/*
|
|
683
|
-
*/
|
|
684
652
|
function assertModuleFound(tag, str = "") {
|
|
685
653
|
const module = VirtualModule.findModule(tag, str);
|
|
686
654
|
if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
|
|
@@ -691,33 +659,16 @@ var VirtualModule = class {
|
|
|
691
659
|
tag;
|
|
692
660
|
suffix;
|
|
693
661
|
inited = false;
|
|
694
|
-
|
|
695
|
-
* Set the root path for finding node_modules
|
|
696
|
-
* @param root - Root path
|
|
697
|
-
*/
|
|
698
|
-
static setRoot(root) {
|
|
699
|
-
rootDir = root;
|
|
700
|
-
cachedNodeModulesDir = void 0;
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Ensure virtual package directory exists
|
|
704
|
-
*/
|
|
705
|
-
static ensureVirtualPackageExists() {
|
|
706
|
-
const nodeModulesDir = getNodeModulesDir();
|
|
707
|
-
const { virtualModuleDir } = getNormalizeModuleFederationOptions();
|
|
708
|
-
const virtualPackagePath = resolve(nodeModulesDir, virtualModuleDir);
|
|
709
|
-
mkdirSync(virtualPackagePath, { recursive: true });
|
|
710
|
-
writeFileSync(resolve(virtualPackagePath, "empty.js"), "");
|
|
711
|
-
writeFileSync(resolve(virtualPackagePath, "package.json"), JSON.stringify({
|
|
712
|
-
name: virtualModuleDir,
|
|
713
|
-
main: "empty.js"
|
|
714
|
-
}));
|
|
715
|
-
}
|
|
662
|
+
code;
|
|
716
663
|
static findModule(tag, str = "") {
|
|
717
664
|
if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
|
|
718
665
|
const moduleName = (str.match(patternMap[tag]) || [])[2];
|
|
719
666
|
if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
|
|
720
667
|
}
|
|
668
|
+
static findById(id) {
|
|
669
|
+
const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
|
|
670
|
+
for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
|
|
671
|
+
}
|
|
721
672
|
constructor(name, tag = "__mf_v__", suffix = "") {
|
|
722
673
|
this.name = name;
|
|
723
674
|
this.tag = tag;
|
|
@@ -725,24 +676,20 @@ var VirtualModule = class {
|
|
|
725
676
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
726
677
|
cacheMap[this.tag][this.name] = this;
|
|
727
678
|
}
|
|
728
|
-
getPath() {
|
|
729
|
-
return resolve(getNodeModulesDir(), this.getImportId());
|
|
730
|
-
}
|
|
731
679
|
getImportId() {
|
|
732
|
-
const { internalName: mfName
|
|
733
|
-
return
|
|
680
|
+
const { internalName: mfName } = getNormalizeModuleFederationOptions();
|
|
681
|
+
return `virtual:mf:${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
|
|
682
|
+
}
|
|
683
|
+
getResolvedId() {
|
|
684
|
+
return `\0${this.getImportId()}`;
|
|
734
685
|
}
|
|
735
686
|
writeSync(code, force) {
|
|
736
687
|
if (!force && this.inited) return;
|
|
737
688
|
if (!this.inited) this.inited = true;
|
|
738
|
-
|
|
739
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
740
|
-
writeFileSync(path, code);
|
|
689
|
+
this.code = code;
|
|
741
690
|
}
|
|
742
691
|
write(code) {
|
|
743
|
-
|
|
744
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
745
|
-
writeFile(path, code, function() {});
|
|
692
|
+
this.writeSync(code, true);
|
|
746
693
|
}
|
|
747
694
|
};
|
|
748
695
|
//#endregion
|
|
@@ -944,6 +891,14 @@ globalThis[__mfCacheGlobalKey].remote ||= {};
|
|
|
944
891
|
const __mfModuleCache = globalThis[__mfCacheGlobalKey];
|
|
945
892
|
`;
|
|
946
893
|
}
|
|
894
|
+
function getRuntimeInitPromiseBootstrapCode() {
|
|
895
|
+
return getRuntimeInitStateBootstrapCode({
|
|
896
|
+
globalKeyVar: "__mfPromiseGlobalKey",
|
|
897
|
+
stateVar: "__mfPromiseState",
|
|
898
|
+
exposedConst: "initPromise",
|
|
899
|
+
exposedProperty: "initPromise"
|
|
900
|
+
});
|
|
901
|
+
}
|
|
947
902
|
function getRuntimeInitResolveBootstrapCode() {
|
|
948
903
|
return getRuntimeInitStateBootstrapCode({
|
|
949
904
|
globalKeyVar: "__mfResolveGlobalKey",
|
|
@@ -1188,6 +1143,20 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1188
1143
|
export const jsx = __mfPrebuildExports.jsx;
|
|
1189
1144
|
export const jsxs = __mfPrebuildExports.jsxs;
|
|
1190
1145
|
export default __mfPrebuildExports;
|
|
1146
|
+
`, true);
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
const namedExports = getPackageNamedExports(pkg);
|
|
1150
|
+
if (namedExports.length > 0) {
|
|
1151
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1152
|
+
const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
|
|
1153
|
+
const namedExportLine = `export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };`;
|
|
1154
|
+
preBuildCacheMap[pkg].writeSync(`
|
|
1155
|
+
import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
|
|
1156
|
+
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1157
|
+
${declarations}
|
|
1158
|
+
${namedExportLine}
|
|
1159
|
+
export default __mfPrebuildExports;
|
|
1191
1160
|
`, true);
|
|
1192
1161
|
return;
|
|
1193
1162
|
}
|
|
@@ -1215,25 +1184,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
|
|
|
1215
1184
|
}
|
|
1216
1185
|
function getLoadShareModulePath(pkg, isRolldown) {
|
|
1217
1186
|
if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
|
|
1218
|
-
return loadShareCacheMap[pkg].
|
|
1187
|
+
return loadShareCacheMap[pkg].getImportId();
|
|
1219
1188
|
}
|
|
1189
|
+
function generateDeferredHostProvidedExports(namedExports, pkg) {
|
|
1190
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1191
|
+
const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
|
|
1192
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
1193
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1194
|
+
return `${declarations}
|
|
1195
|
+
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1196
|
+
${assignments}
|
|
1197
|
+
};
|
|
1198
|
+
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1199
|
+
if (exportModule === undefined) {
|
|
1200
|
+
initPromise.then(() => {
|
|
1201
|
+
exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1202
|
+
if (exportModule === undefined) {
|
|
1203
|
+
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1204
|
+
}
|
|
1205
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1206
|
+
});
|
|
1207
|
+
} else {
|
|
1208
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1209
|
+
}
|
|
1210
|
+
export { __mf_default as default };${namedExportLine}`;
|
|
1211
|
+
}
|
|
1212
|
+
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1213
|
+
return `let current = ${source};
|
|
1214
|
+
for (let i = 0; i < 5; i++) {
|
|
1215
|
+
const defaultExport = current?.default;
|
|
1216
|
+
${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
|
|
1217
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1218
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
|
|
1219
|
+
current = defaultExport;
|
|
1220
|
+
}
|
|
1221
|
+
return current;`;
|
|
1222
|
+
}
|
|
1223
|
+
const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
|
|
1224
|
+
${generateShareModuleUnwrapCode({
|
|
1225
|
+
source: "mod",
|
|
1226
|
+
preserveNamedExports: true
|
|
1227
|
+
})}
|
|
1228
|
+
};`;
|
|
1220
1229
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
1221
1230
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
|
|
1222
1231
|
const importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1223
1232
|
if (shareItem.shareConfig.import === false) {
|
|
1224
1233
|
const namedExports = getPackageNamedExports(pkg);
|
|
1225
1234
|
let exportLine;
|
|
1226
|
-
if (namedExports.length > 0) exportLine =
|
|
1235
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
|
|
1227
1236
|
else {
|
|
1228
1237
|
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.`);
|
|
1229
|
-
exportLine =
|
|
1238
|
+
exportLine = generateDeferredHostProvidedExports([], pkg);
|
|
1230
1239
|
}
|
|
1231
1240
|
loadShareCacheMap[pkg].writeSync(`
|
|
1241
|
+
${getRuntimeInitPromiseBootstrapCode()}
|
|
1232
1242
|
${importLine}
|
|
1233
|
-
const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1234
|
-
if (exportModule === undefined) {
|
|
1235
|
-
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
|
|
1236
|
-
}
|
|
1237
1243
|
${exportLine}
|
|
1238
1244
|
`, true);
|
|
1239
1245
|
return;
|
|
@@ -1248,8 +1254,20 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1248
1254
|
const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
1249
1255
|
const namedExports = getPackageNamedExports(pkg);
|
|
1250
1256
|
let exportLine;
|
|
1251
|
-
if (namedExports.length > 0)
|
|
1252
|
-
|
|
1257
|
+
if (namedExports.length > 0) {
|
|
1258
|
+
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1259
|
+
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
1260
|
+
exportLine = `const __mfDefaultExport = (() => {
|
|
1261
|
+
${generateShareModuleUnwrapCode({
|
|
1262
|
+
source: "exportModule",
|
|
1263
|
+
preserveNamedExports: false,
|
|
1264
|
+
stopWithReturn: "defaultExport ?? current"
|
|
1265
|
+
})}
|
|
1266
|
+
})();
|
|
1267
|
+
export default __mfDefaultExport;
|
|
1268
|
+
${destructure}
|
|
1269
|
+
${namedExportLine}`;
|
|
1270
|
+
} else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
|
|
1253
1271
|
else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
1254
1272
|
const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1255
1273
|
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
@@ -1257,10 +1275,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1257
1275
|
${prebuildImportLine}
|
|
1258
1276
|
${devDynamicImportLine}
|
|
1259
1277
|
${importLine}
|
|
1278
|
+
${normalizeLocalShareModuleCode}
|
|
1260
1279
|
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1261
1280
|
if (exportModule === undefined) {
|
|
1262
|
-
${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
|
|
1263
|
-
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
|
|
1281
|
+
${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
|
|
1282
|
+
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1264
1283
|
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
|
|
1265
1284
|
}
|
|
1266
1285
|
${exportLine}
|
|
@@ -1418,9 +1437,9 @@ function getShareItemForPreload(pkg) {
|
|
|
1418
1437
|
function generateSharedCacheSeedItem(pkg, importPath) {
|
|
1419
1438
|
return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
|
|
1420
1439
|
const mod = await import(${JSON.stringify(importPath)});
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1440
|
+
${normalizeRuntimeShareCode}
|
|
1441
|
+
const normalizedModule = __mfNormalizeRuntimeShare(mod);
|
|
1442
|
+
const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
|
|
1424
1443
|
Object.defineProperty(exportModule, "__esModule", {
|
|
1425
1444
|
value: true,
|
|
1426
1445
|
enumerable: false
|
|
@@ -1428,6 +1447,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
|
|
|
1428
1447
|
__mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
|
|
1429
1448
|
}`;
|
|
1430
1449
|
}
|
|
1450
|
+
const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
1451
|
+
let current = mod;
|
|
1452
|
+
for (let i = 0; i < 5; i++) {
|
|
1453
|
+
const defaultExport = current?.default;
|
|
1454
|
+
if (!defaultExport || typeof defaultExport !== "object") break;
|
|
1455
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1456
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
|
|
1457
|
+
current = defaultExport;
|
|
1458
|
+
}
|
|
1459
|
+
return current;
|
|
1460
|
+
};`;
|
|
1431
1461
|
function generateDirectSharedCacheSeedCode(command = "build") {
|
|
1432
1462
|
return getOrderedUsedShares().map((pkg) => {
|
|
1433
1463
|
const shareItem = getShareItemForPreload(pkg);
|
|
@@ -1450,7 +1480,8 @@ function getHostAutoInitSharedSeedItems() {
|
|
|
1450
1480
|
return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
|
|
1451
1481
|
});
|
|
1452
1482
|
}
|
|
1453
|
-
function generateHostAutoInitSharedCacheSeedCode() {
|
|
1483
|
+
function generateHostAutoInitSharedCacheSeedCode(command = "build") {
|
|
1484
|
+
if (command === "build") return "";
|
|
1454
1485
|
return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
|
|
1455
1486
|
if (!shareItem) return null;
|
|
1456
1487
|
return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
|
|
@@ -1482,14 +1513,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1482
1513
|
if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
|
|
1483
1514
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
1484
1515
|
}
|
|
1485
|
-
import {
|
|
1516
|
+
import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
|
|
1486
1517
|
${pluginImportNames.map((item) => item[1]).join("\n")}
|
|
1487
1518
|
${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
|
|
1488
1519
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
1489
1520
|
const initTokens = {}
|
|
1490
1521
|
const shareScopeName = ${JSON.stringify(options.shareScope)}
|
|
1491
1522
|
const mfName = ${JSON.stringify(options.internalName)}
|
|
1492
|
-
let runtimeInstance
|
|
1493
1523
|
let localSharedImportMapPromise
|
|
1494
1524
|
let exposesMapPromise
|
|
1495
1525
|
const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
|
|
@@ -1532,19 +1562,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1532
1562
|
async function init(shared = {}, initScope = []) {
|
|
1533
1563
|
const {usedShared, usedRemotes} = await getLocalSharedImportMap()
|
|
1534
1564
|
${generateDirectSharedCacheSeedCode(command)}
|
|
1535
|
-
const
|
|
1565
|
+
const initRes = runtimeInit({
|
|
1536
1566
|
name: mfName,
|
|
1537
1567
|
remotes: usedRemotes,
|
|
1538
1568
|
shared: usedShared,
|
|
1539
1569
|
plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
|
|
1540
1570
|
${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
|
|
1541
|
-
};
|
|
1542
|
-
if (!runtimeInstance) {
|
|
1543
|
-
runtimeInstance = createInstance(runtimeOptions);
|
|
1544
|
-
} else {
|
|
1545
|
-
runtimeInstance.initOptions(runtimeOptions);
|
|
1546
|
-
}
|
|
1547
|
-
const initRes = runtimeInstance;
|
|
1571
|
+
});
|
|
1548
1572
|
// handling circular init calls
|
|
1549
1573
|
var initToken = initTokens[shareScopeName];
|
|
1550
1574
|
if (!initToken)
|
|
@@ -1564,6 +1588,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1564
1588
|
} catch (e) {
|
|
1565
1589
|
console.error('[Module Federation]', e)
|
|
1566
1590
|
}
|
|
1591
|
+
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1592
|
+
if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
|
|
1593
|
+
${normalizeRuntimeShareCode}
|
|
1594
|
+
const versions = shared?.[pkg];
|
|
1595
|
+
const provider = versions && versions[Object.keys(versions)[0]];
|
|
1596
|
+
if (!provider) continue;
|
|
1597
|
+
const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
|
|
1598
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
1599
|
+
const resolved = await Promise.resolve(mod);
|
|
1600
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1601
|
+
}
|
|
1567
1602
|
return initRes
|
|
1568
1603
|
}
|
|
1569
1604
|
|
|
@@ -1588,10 +1623,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1588
1623
|
async function initHost() {
|
|
1589
1624
|
if (!hostInitPromise) {
|
|
1590
1625
|
hostInitPromise = (async () => {
|
|
1591
|
-
${generateHostAutoInitSharedCacheSeedCode()}
|
|
1626
|
+
${generateHostAutoInitSharedCacheSeedCode(_command)}
|
|
1592
1627
|
const remoteEntry = await import(${remoteEntryImport});
|
|
1593
1628
|
const runtime = await remoteEntry.init();
|
|
1594
1629
|
const usedShared = ${generateUsedSharedPreloadConfig()};
|
|
1630
|
+
${normalizeRuntimeShareCode}
|
|
1595
1631
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1596
1632
|
if (__mfModuleCache.share[pkg] !== undefined) {
|
|
1597
1633
|
continue;
|
|
@@ -1601,7 +1637,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1601
1637
|
}).then((factory) => {
|
|
1602
1638
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
1603
1639
|
return Promise.resolve(mod).then((resolved) => {
|
|
1604
|
-
__mfModuleCache.share[pkg] = resolved;
|
|
1640
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1605
1641
|
});
|
|
1606
1642
|
});
|
|
1607
1643
|
}
|
|
@@ -1630,7 +1666,7 @@ function getHostAutoInitImportId() {
|
|
|
1630
1666
|
return hostAutoInitModule.getImportId();
|
|
1631
1667
|
}
|
|
1632
1668
|
function getHostAutoInitPath() {
|
|
1633
|
-
return hostAutoInitModule.
|
|
1669
|
+
return hostAutoInitModule.getImportId();
|
|
1634
1670
|
}
|
|
1635
1671
|
//#endregion
|
|
1636
1672
|
//#region src/virtualModules/virtualRemotes.ts
|
|
@@ -1653,7 +1689,9 @@ function getUsedRemotesMap() {
|
|
|
1653
1689
|
}
|
|
1654
1690
|
function generateRemotes(id, command) {
|
|
1655
1691
|
const useReactProxy = command === "serve" && hasPackageDependency("react");
|
|
1656
|
-
const reactImportLine = useReactProxy ? `import
|
|
1692
|
+
const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
|
|
1693
|
+
import * as __mfReactNamespace from "react";
|
|
1694
|
+
const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
|
|
1657
1695
|
const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
|
|
1658
1696
|
import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
|
|
1659
1697
|
const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
|
|
@@ -1663,13 +1701,13 @@ function generateRemotes(id, command) {
|
|
|
1663
1701
|
}
|
|
1664
1702
|
export const __moduleExports = exportModule;
|
|
1665
1703
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1666
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1704
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1667
1705
|
const mod = await __mfRemotePending;
|
|
1668
1706
|
if (mod !== undefined) exportModule = mod;
|
|
1669
1707
|
}
|
|
1670
1708
|
export const __moduleExports = exportModule;
|
|
1671
1709
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1672
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1710
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1673
1711
|
return `
|
|
1674
1712
|
${reactImportLine}
|
|
1675
1713
|
${importLine}
|
|
@@ -1869,6 +1907,9 @@ ${importHelper}(async () => {
|
|
|
1869
1907
|
if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
|
|
1870
1908
|
return inject === "entry" || !htmlFilePath;
|
|
1871
1909
|
}
|
|
1910
|
+
function normalizeDevHtmlProxyId(id) {
|
|
1911
|
+
return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
|
|
1912
|
+
}
|
|
1872
1913
|
return [{
|
|
1873
1914
|
name: "add-entry",
|
|
1874
1915
|
apply: "serve",
|
|
@@ -1887,7 +1928,20 @@ ${importHelper}(async () => {
|
|
|
1887
1928
|
}
|
|
1888
1929
|
},
|
|
1889
1930
|
configureServer(server) {
|
|
1890
|
-
server.middlewares.use((req,
|
|
1931
|
+
server.middlewares.use((req, res, next) => {
|
|
1932
|
+
const rawUrl = req.url?.split("#")[0] ?? "";
|
|
1933
|
+
if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
|
|
1934
|
+
const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
|
|
1935
|
+
const params = new URLSearchParams(query);
|
|
1936
|
+
const initSrc = params.get("init");
|
|
1937
|
+
const entrySrc = params.get("entry");
|
|
1938
|
+
if (initSrc && entrySrc) {
|
|
1939
|
+
res.statusCode = 200;
|
|
1940
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
1941
|
+
res.end(getBootstrapSource(initSrc, entrySrc));
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1891
1945
|
if (!fileName) {
|
|
1892
1946
|
next();
|
|
1893
1947
|
return;
|
|
@@ -1904,7 +1958,7 @@ ${importHelper}(async () => {
|
|
|
1904
1958
|
const base = viteConfig.base.replace(/\/$/, "");
|
|
1905
1959
|
const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
|
|
1906
1960
|
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
1907
|
-
return `/@id
|
|
1961
|
+
return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
1908
1962
|
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
1909
1963
|
entry: sanitizeDevEntryPath(stripBase(originalSrc))
|
|
1910
1964
|
}).toString()}`;
|
|
@@ -1913,11 +1967,12 @@ ${importHelper}(async () => {
|
|
|
1913
1967
|
}
|
|
1914
1968
|
},
|
|
1915
1969
|
resolveId(id) {
|
|
1916
|
-
if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1970
|
+
if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1917
1971
|
},
|
|
1918
1972
|
load(id) {
|
|
1919
|
-
|
|
1920
|
-
|
|
1973
|
+
const normalizedId = normalizeDevHtmlProxyId(id);
|
|
1974
|
+
if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
|
|
1975
|
+
const params = new URLSearchParams(normalizedId.slice(28));
|
|
1921
1976
|
const initSrc = params.get("init");
|
|
1922
1977
|
const entrySrc = params.get("entry");
|
|
1923
1978
|
if (!initSrc || !entrySrc) return;
|
|
@@ -2724,7 +2779,7 @@ function collectSystemProxyInfos(proxyChunks, loadShareTag) {
|
|
|
2724
2779
|
for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
|
|
2725
2780
|
const exported = m[1];
|
|
2726
2781
|
const expression = m[2];
|
|
2727
|
-
for (const [local, exportName] of Object.entries(loadShareBindings)) if (new RegExp(`\\b${local}\\b`).test(expression)) {
|
|
2782
|
+
for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
|
|
2728
2783
|
exportMap[exported] = {
|
|
2729
2784
|
type: "reexport",
|
|
2730
2785
|
exportName
|
|
@@ -3488,7 +3543,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
3488
3543
|
const remoteModule = getRemoteVirtualModule(source, command);
|
|
3489
3544
|
addUsedRemote(remoteName, source);
|
|
3490
3545
|
refreshHostAutoInit();
|
|
3491
|
-
return remoteModule.
|
|
3546
|
+
return remoteModule.getImportId();
|
|
3492
3547
|
}
|
|
3493
3548
|
return {
|
|
3494
3549
|
name: "proxyRemotes",
|
|
@@ -3890,7 +3945,7 @@ async function collectFromEsLexer(code, isRemoteImport) {
|
|
|
3890
3945
|
await init;
|
|
3891
3946
|
let imports;
|
|
3892
3947
|
try {
|
|
3893
|
-
[imports] = parse
|
|
3948
|
+
[imports] = parse(code);
|
|
3894
3949
|
} catch {
|
|
3895
3950
|
return;
|
|
3896
3951
|
}
|
|
@@ -4310,12 +4365,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
4310
4365
|
return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
|
|
4311
4366
|
}
|
|
4312
4367
|
/**
|
|
4313
|
-
* Plugin that runs FIRST to
|
|
4314
|
-
* This prevents 504 "Outdated Optimize Dep" errors by ensuring
|
|
4368
|
+
* Plugin that runs FIRST to register generated virtual modules in the config hook.
|
|
4369
|
+
* This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
|
|
4315
4370
|
* before Vite's optimization phase.
|
|
4316
4371
|
*/
|
|
4317
4372
|
function createEarlyVirtualModulesPlugin(options) {
|
|
4318
|
-
const { shared, remotes
|
|
4373
|
+
const { shared, remotes } = options;
|
|
4319
4374
|
const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
|
|
4320
4375
|
return {
|
|
4321
4376
|
name: "vite:module-federation-early-init",
|
|
@@ -4325,9 +4380,6 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
4325
4380
|
const root = config.root || process.cwd();
|
|
4326
4381
|
setPackageDetectionCwd(root);
|
|
4327
4382
|
const isVinext = hasPackageDependency("vinext");
|
|
4328
|
-
initVirtualModuleInfrastructure(root, virtualModuleDir);
|
|
4329
|
-
VirtualModule.setRoot(root);
|
|
4330
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
4331
4383
|
initVirtualModules(_command, getRemoteEntryId(options));
|
|
4332
4384
|
const isRolldown = getIsRolldown(this);
|
|
4333
4385
|
if (remotes && Object.keys(remotes).length > 0) {
|
|
@@ -4373,6 +4425,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
4373
4425
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
4374
4426
|
name: "module-federation:optimize-shared-proxy",
|
|
4375
4427
|
setup(build) {
|
|
4428
|
+
build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
|
|
4429
|
+
path: args.path,
|
|
4430
|
+
external: true
|
|
4431
|
+
}));
|
|
4376
4432
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
4377
4433
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
4378
4434
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
@@ -4404,7 +4460,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4404
4460
|
}
|
|
4405
4461
|
});
|
|
4406
4462
|
}
|
|
4407
|
-
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
4408
4463
|
}
|
|
4409
4464
|
for (const key of Object.keys(shared)) {
|
|
4410
4465
|
const shareItem = shared[key];
|
|
@@ -4415,7 +4470,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4415
4470
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4416
4471
|
writePreBuildLibPath(subpath, shareItem);
|
|
4417
4472
|
optimizeDeps.include.push(subpath);
|
|
4418
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4419
4473
|
}
|
|
4420
4474
|
}
|
|
4421
4475
|
continue;
|
|
@@ -4432,14 +4486,11 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4432
4486
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
4433
4487
|
optimizeDeps.include ??= [];
|
|
4434
4488
|
optimizeDeps.exclude ??= [];
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
|
|
4438
|
-
optimizeDeps.include.push(getPreBuildLibImportId(key));
|
|
4489
|
+
if (isLitShare(key)) optimizeDeps.exclude.push(key);
|
|
4490
|
+
else optimizeDeps.include.push(key);
|
|
4439
4491
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4440
4492
|
writePreBuildLibPath(subpath, shareItem);
|
|
4441
4493
|
optimizeDeps.include.push(subpath);
|
|
4442
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4443
4494
|
}
|
|
4444
4495
|
}
|
|
4445
4496
|
}
|
|
@@ -4459,6 +4510,21 @@ function federation(mfUserOptions) {
|
|
|
4459
4510
|
let command;
|
|
4460
4511
|
let desiredRolldownOutput;
|
|
4461
4512
|
return [
|
|
4513
|
+
{
|
|
4514
|
+
name: "vite:module-federation-virtual-modules",
|
|
4515
|
+
enforce: "pre",
|
|
4516
|
+
resolveId(id) {
|
|
4517
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4518
|
+
if (!virtualModule) return;
|
|
4519
|
+
return virtualModule.getResolvedId();
|
|
4520
|
+
},
|
|
4521
|
+
load(id) {
|
|
4522
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4523
|
+
if (!virtualModule) return;
|
|
4524
|
+
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
4525
|
+
return virtualModule.code;
|
|
4526
|
+
}
|
|
4527
|
+
},
|
|
4462
4528
|
createEarlyVirtualModulesPlugin(options),
|
|
4463
4529
|
...isVinext ? [{
|
|
4464
4530
|
name: "module-federation-vinext-react-server-build-alias",
|
|
@@ -4483,9 +4549,7 @@ function federation(mfUserOptions) {
|
|
|
4483
4549
|
config(_config, env) {
|
|
4484
4550
|
command = env.command;
|
|
4485
4551
|
},
|
|
4486
|
-
configResolved(
|
|
4487
|
-
VirtualModule.setRoot(config.root);
|
|
4488
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
4552
|
+
configResolved() {
|
|
4489
4553
|
initVirtualModules(command, remoteEntryId);
|
|
4490
4554
|
}
|
|
4491
4555
|
},
|
|
@@ -4628,9 +4692,8 @@ function federation(mfUserOptions) {
|
|
|
4628
4692
|
}
|
|
4629
4693
|
},
|
|
4630
4694
|
load(id) {
|
|
4631
|
-
if (id.startsWith("\0")) return;
|
|
4632
4695
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
4633
|
-
let code = readFileSync(id, "utf-8");
|
|
4696
|
+
let code = VirtualModule.findById(id)?.code ?? readFileSync(id, "utf-8");
|
|
4634
4697
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4635
4698
|
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4636
4699
|
/**
|
|
@@ -4649,7 +4712,10 @@ function federation(mfUserOptions) {
|
|
|
4649
4712
|
*
|
|
4650
4713
|
* @see https://rollupjs.org/plugin-development/#synthetic-named-exports
|
|
4651
4714
|
*/
|
|
4652
|
-
if (
|
|
4715
|
+
if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
|
|
4716
|
+
const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
|
|
4717
|
+
code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
|
|
4718
|
+
}
|
|
4653
4719
|
if (getIsRolldown(this)) return { code };
|
|
4654
4720
|
return {
|
|
4655
4721
|
code,
|
|
@@ -4714,14 +4780,9 @@ function federation(mfUserOptions) {
|
|
|
4714
4780
|
config.build ||= {};
|
|
4715
4781
|
config.build.commonjsOptions ||= {};
|
|
4716
4782
|
config.build.commonjsOptions.strictRequires ??= "auto";
|
|
4717
|
-
const virtualDir = options.virtualModuleDir;
|
|
4718
4783
|
config.optimizeDeps ||= {};
|
|
4719
4784
|
config.optimizeDeps.include ||= [];
|
|
4720
4785
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
4721
|
-
if (!isRolldown) config.optimizeDeps.include.push(virtualDir);
|
|
4722
|
-
config.ssr ||= {};
|
|
4723
|
-
config.ssr.noExternal ||= [];
|
|
4724
|
-
if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
|
|
4725
4786
|
options.runtimePlugins.forEach((p) => {
|
|
4726
4787
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
4727
4788
|
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
|
|
@@ -4729,9 +4790,6 @@ function federation(mfUserOptions) {
|
|
|
4729
4790
|
if (isRolldown) {
|
|
4730
4791
|
config.build ??= {};
|
|
4731
4792
|
config.build.target ??= "esnext";
|
|
4732
|
-
} else {
|
|
4733
|
-
config.optimizeDeps.needsInterop ||= [];
|
|
4734
|
-
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
4735
4793
|
}
|
|
4736
4794
|
const isAstro = hasPackageDependency("astro");
|
|
4737
4795
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.4",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.cjs",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"oxfmt": "^0.36.0",
|
|
85
85
|
"rollup": "^4.47.1",
|
|
86
86
|
"tsdown": "^0.21.0",
|
|
87
|
+
"typescript": "5.9.3",
|
|
87
88
|
"vite": "^8.0.10",
|
|
88
89
|
"vitest": "^4.0.18"
|
|
89
90
|
}
|