@module-federation/vite 1.15.1 → 1.15.3

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 CHANGED
@@ -21,29 +21,150 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
- let defu = require("defu");
25
- defu = __toESM(defu);
26
24
  let fs = require("fs");
27
25
  fs = __toESM(fs);
28
26
  let module$1 = require("module");
29
27
  let pathe = require("pathe");
30
28
  pathe = __toESM(pathe);
31
- let magic_string = require("magic-string");
32
- magic_string = __toESM(magic_string);
33
29
  let _module_federation_sdk = require("@module-federation/sdk");
34
30
  let _module_federation_dts_plugin = require("@module-federation/dts-plugin");
35
31
  let _module_federation_dts_plugin_core = require("@module-federation/dts-plugin/core");
36
- let _rollup_pluginutils = require("@rollup/pluginutils");
37
32
  let url = require("url");
38
33
  let es_module_lexer = require("es-module-lexer");
34
+ //#region src/utils/codeRewriter.ts
35
+ const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
36
+ var CodeRewriter = class {
37
+ replacements = [];
38
+ constructor(original) {
39
+ this.original = original;
40
+ }
41
+ overwrite(start, end, content) {
42
+ if (start < 0 || end < start || end > this.original.length) throw new Error(`Invalid overwrite range: ${start}-${end}`);
43
+ this.replacements.push({
44
+ start,
45
+ end,
46
+ content
47
+ });
48
+ }
49
+ toString() {
50
+ return applyReplacements(this.original, this.getSortedReplacements()).code;
51
+ }
52
+ generateMap(source = "") {
53
+ const { code, replacements } = applyReplacements(this.original, this.getSortedReplacements());
54
+ return {
55
+ version: 3,
56
+ sources: [source],
57
+ sourcesContent: [this.original],
58
+ names: [],
59
+ mappings: generateLineMappings(code, this.original, replacements)
60
+ };
61
+ }
62
+ getSortedReplacements() {
63
+ return [...this.replacements].sort((a, b) => a.start - b.start || a.end - b.end);
64
+ }
65
+ };
66
+ function createSourceMap(code, source = "") {
67
+ return {
68
+ version: 3,
69
+ sources: [source],
70
+ sourcesContent: [code],
71
+ names: [],
72
+ mappings: generateLineMappings(code, code, [])
73
+ };
74
+ }
75
+ function applyReplacements(original, replacements) {
76
+ let code = "";
77
+ let cursor = 0;
78
+ let delta = 0;
79
+ const applied = [];
80
+ for (const replacement of replacements) {
81
+ if (replacement.start < cursor) throw new Error("Overlapping overwrite ranges are not supported");
82
+ code += original.slice(cursor, replacement.start);
83
+ const generatedStart = replacement.start + delta;
84
+ code += replacement.content;
85
+ const generatedEnd = generatedStart + replacement.content.length;
86
+ applied.push({
87
+ ...replacement,
88
+ generatedStart,
89
+ generatedEnd
90
+ });
91
+ cursor = replacement.end;
92
+ delta += replacement.content.length - (replacement.end - replacement.start);
93
+ }
94
+ code += original.slice(cursor);
95
+ return {
96
+ code,
97
+ replacements: applied
98
+ };
99
+ }
100
+ function generateLineMappings(generated, original, replacements) {
101
+ const generatedLineStarts = getLineStarts(generated);
102
+ const originalLineStarts = getLineStarts(original);
103
+ let previousOriginalLine = 0;
104
+ let previousOriginalColumn = 0;
105
+ let mappings = "";
106
+ generatedLineStarts.forEach((generatedOffset, lineIndex) => {
107
+ if (lineIndex > 0) mappings += ";";
108
+ const originalOffset = generatedOffsetToOriginalOffset(generatedOffset, replacements);
109
+ const originalLine = findLine(originalLineStarts, originalOffset);
110
+ const originalColumn = originalOffset - originalLineStarts[originalLine];
111
+ mappings += encodeSegment([
112
+ 0,
113
+ 0,
114
+ originalLine - previousOriginalLine,
115
+ originalColumn - previousOriginalColumn
116
+ ]);
117
+ previousOriginalLine = originalLine;
118
+ previousOriginalColumn = originalColumn;
119
+ });
120
+ return mappings;
121
+ }
122
+ function generatedOffsetToOriginalOffset(offset, replacements) {
123
+ let delta = 0;
124
+ for (const replacement of replacements) {
125
+ if (offset < replacement.generatedStart) break;
126
+ if (offset < replacement.generatedEnd) return replacement.start;
127
+ delta += replacement.content.length - (replacement.end - replacement.start);
128
+ }
129
+ return offset - delta;
130
+ }
131
+ function getLineStarts(code) {
132
+ const starts = [0];
133
+ for (let i = 0; i < code.length; i++) if (code.charCodeAt(i) === 10) starts.push(i + 1);
134
+ return starts;
135
+ }
136
+ function findLine(lineStarts, offset) {
137
+ let low = 0;
138
+ let high = lineStarts.length - 1;
139
+ while (low <= high) {
140
+ const mid = low + high >> 1;
141
+ if (lineStarts[mid] <= offset) low = mid + 1;
142
+ else high = mid - 1;
143
+ }
144
+ return Math.max(0, high);
145
+ }
146
+ function encodeSegment(values) {
147
+ return values.map(encodeVlq).join("");
148
+ }
149
+ function encodeVlq(value) {
150
+ let vlq = value < 0 ? (-value << 1) + 1 : value << 1;
151
+ let encoded = "";
152
+ do {
153
+ let digit = vlq & 31;
154
+ vlq >>>= 5;
155
+ if (vlq > 0) digit |= 32;
156
+ encoded += BASE64_CHARS[digit];
157
+ } while (vlq > 0);
158
+ return encoded;
159
+ }
160
+ //#endregion
39
161
  //#region src/utils/mapCodeToCodeWithSourcemap.ts
40
162
  async function mapCodeToCodeWithSourcemap(code) {
41
163
  const resolvedCode = await code;
42
164
  if (resolvedCode === void 0) return;
43
- const s = new magic_string.default(resolvedCode);
44
165
  return {
45
- code: s.toString(),
46
- map: s.generateMap({ hires: true })
166
+ code: resolvedCode,
167
+ map: createSourceMap(resolvedCode)
47
168
  };
48
169
  }
49
170
  //#endregion
@@ -423,7 +544,7 @@ function normalizeShareItem(key, shareItem) {
423
544
  shareConfig: {
424
545
  import: shareItem.import,
425
546
  singleton: shareItem.singleton || false,
426
- requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
547
+ requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
427
548
  strictVersion: !!shareItem.strictVersion
428
549
  }
429
550
  };
@@ -540,35 +661,6 @@ function normalizeModuleFederationOptions(options) {
540
661
  }
541
662
  //#endregion
542
663
  //#region src/utils/VirtualModule.ts
543
- /**
544
- * Initialize virtual module infrastructure BEFORE VirtualModule class is used.
545
- * This must be called in the config hook to ensure the directory exists
546
- * before Vite's optimization phase.
547
- */
548
- function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
549
- const virtualPackagePath = (0, pathe.join)((0, pathe.join)(root, "node_modules"), virtualModuleDir);
550
- (0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
551
- (0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "empty.js"), "");
552
- (0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "package.json"), JSON.stringify({
553
- name: virtualModuleDir,
554
- main: "empty.js"
555
- }));
556
- }
557
- let rootDir;
558
- function findNodeModulesDir(root = process.cwd()) {
559
- let currentDir = root;
560
- while (currentDir !== (0, pathe.parse)(currentDir).root) {
561
- const nodeModulesPath = (0, pathe.join)(currentDir, "node_modules");
562
- if ((0, fs.existsSync)(nodeModulesPath)) return nodeModulesPath;
563
- currentDir = (0, pathe.dirname)(currentDir);
564
- }
565
- return "";
566
- }
567
- let cachedNodeModulesDir;
568
- function getNodeModulesDir() {
569
- if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
570
- return cachedNodeModulesDir;
571
- }
572
664
  function getSuffix(name) {
573
665
  const base = (0, pathe.basename)(name);
574
666
  const dotIndex = base.lastIndexOf(".");
@@ -577,9 +669,6 @@ function getSuffix(name) {
577
669
  }
578
670
  const patternMap = {};
579
671
  const cacheMap = {};
580
- /**
581
- * Physically generate files as virtual modules under node_modules/__mf__virtual/*
582
- */
583
672
  function assertModuleFound(tag, str = "") {
584
673
  const module = VirtualModule.findModule(tag, str);
585
674
  if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
@@ -590,33 +679,16 @@ var VirtualModule = class {
590
679
  tag;
591
680
  suffix;
592
681
  inited = false;
593
- /**
594
- * Set the root path for finding node_modules
595
- * @param root - Root path
596
- */
597
- static setRoot(root) {
598
- rootDir = root;
599
- cachedNodeModulesDir = void 0;
600
- }
601
- /**
602
- * Ensure virtual package directory exists
603
- */
604
- static ensureVirtualPackageExists() {
605
- const nodeModulesDir = getNodeModulesDir();
606
- const { virtualModuleDir } = getNormalizeModuleFederationOptions();
607
- const virtualPackagePath = (0, pathe.resolve)(nodeModulesDir, virtualModuleDir);
608
- (0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
609
- (0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "empty.js"), "");
610
- (0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "package.json"), JSON.stringify({
611
- name: virtualModuleDir,
612
- main: "empty.js"
613
- }));
614
- }
682
+ code;
615
683
  static findModule(tag, str = "") {
616
684
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
617
685
  const moduleName = (str.match(patternMap[tag]) || [])[2];
618
686
  if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
619
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
+ }
620
692
  constructor(name, tag = "__mf_v__", suffix = "") {
621
693
  this.name = name;
622
694
  this.tag = tag;
@@ -624,128 +696,23 @@ var VirtualModule = class {
624
696
  if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
625
697
  cacheMap[this.tag][this.name] = this;
626
698
  }
627
- getPath() {
628
- return (0, pathe.resolve)(getNodeModulesDir(), this.getImportId());
629
- }
630
699
  getImportId() {
631
- const { internalName: mfName, virtualModuleDir } = getNormalizeModuleFederationOptions();
632
- return `${virtualModuleDir}/${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
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()}`;
633
705
  }
634
706
  writeSync(code, force) {
635
707
  if (!force && this.inited) return;
636
708
  if (!this.inited) this.inited = true;
637
- const path = this.getPath();
638
- (0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
639
- (0, fs.writeFileSync)(path, code);
709
+ this.code = code;
640
710
  }
641
711
  write(code) {
642
- const path = this.getPath();
643
- (0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
644
- (0, fs.writeFile)(path, code, function() {});
712
+ this.writeSync(code, true);
645
713
  }
646
714
  };
647
715
  //#endregion
648
- //#region src/virtualModules/virtualRuntimeInitStatus.ts
649
- const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
650
- const MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache__";
651
- function getRuntimeInitGlobalKey() {
652
- return `__mf_init__${virtualRuntimeInitStatus.getImportId()}__`;
653
- }
654
- function getDeferredInitPromiseCode() {
655
- return `let initResolve, initReject;
656
- const initPromise = new Promise((re, rj) => {
657
- initResolve = re;
658
- initReject = rj;
659
- });`;
660
- }
661
- function getSsrNoopResolveCode() {
662
- return `if (typeof window === 'undefined') {
663
- initResolve({
664
- loadRemote: function() { return Promise.resolve(undefined); },
665
- loadShare: function() { return Promise.resolve(undefined); },
666
- });
667
- }`;
668
- }
669
- function getRuntimeInitStateBootstrapCode(options) {
670
- return `
671
- const ${options.globalKeyVar} = ${JSON.stringify(getRuntimeInitGlobalKey())};
672
- let ${options.stateVar} = globalThis[${options.globalKeyVar}];
673
- if (!${options.stateVar}) {
674
- ${getDeferredInitPromiseCode()}
675
- ${options.stateVar} = globalThis[${options.globalKeyVar}] = {
676
- initPromise,
677
- initResolve,
678
- initReject,
679
- };
680
- ${getSsrNoopResolveCode()}
681
- }
682
- const ${options.exposedConst} = ${options.stateVar}.${options.exposedProperty};
683
- `;
684
- }
685
- function getRuntimeInitBootstrapCode() {
686
- return `
687
- const globalKey = ${JSON.stringify(getRuntimeInitGlobalKey())};
688
- const moduleCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
689
- globalThis[moduleCacheGlobalKey] ||= { share: {}, remote: {} };
690
- globalThis[moduleCacheGlobalKey].share ||= {};
691
- globalThis[moduleCacheGlobalKey].remote ||= {};
692
- if (!globalThis[globalKey]) {
693
- ${getDeferredInitPromiseCode()}
694
- globalThis[globalKey] = {
695
- initPromise,
696
- initResolve,
697
- initReject,
698
- moduleCache: globalThis[moduleCacheGlobalKey],
699
- };
700
- ${getSsrNoopResolveCode()}
701
- }
702
- globalThis[globalKey].moduleCache ||= globalThis[moduleCacheGlobalKey];
703
- globalThis[globalKey].moduleCache.share ||= {};
704
- globalThis[globalKey].moduleCache.remote ||= {};
705
- `;
706
- }
707
- function getRuntimeModuleCacheBootstrapCode() {
708
- return `
709
- const __mfCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
710
- globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
711
- globalThis[__mfCacheGlobalKey].share ||= {};
712
- globalThis[__mfCacheGlobalKey].remote ||= {};
713
- const __mfModuleCache = globalThis[__mfCacheGlobalKey];
714
- `;
715
- }
716
- function getRuntimeInitResolveBootstrapCode() {
717
- return getRuntimeInitStateBootstrapCode({
718
- globalKeyVar: "__mfResolveGlobalKey",
719
- stateVar: "__mfResolveState",
720
- exposedConst: "initResolve",
721
- exposedProperty: "initResolve"
722
- });
723
- }
724
- function writeRuntimeInitStatus(command) {
725
- const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
726
- export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
727
- virtualRuntimeInitStatus.writeSync(`
728
- ${getRuntimeInitBootstrapCode()}
729
- ${exportStatement}
730
- `);
731
- }
732
- //#endregion
733
- //#region src/utils/localSharedImportMap_temp.ts
734
- /**
735
- * https://github.com/module-federation/vite/issues/68
736
- */
737
- function getLocalSharedImportMapPath_temp() {
738
- const { name } = getNormalizeModuleFederationOptions();
739
- return pathe.default.resolve(".__mf__temp", packageNameEncode(name), "localSharedImportMap");
740
- }
741
- function writeLocalSharedImportMap_temp(content) {
742
- createFile(getLocalSharedImportMapPath_temp() + ".js", "\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n" + content);
743
- }
744
- function createFile(filePath, content) {
745
- (0, fs.mkdirSync)(pathe.default.dirname(filePath), { recursive: true });
746
- (0, fs.writeFileSync)(filePath, content);
747
- }
748
- //#endregion
749
716
  //#region src/utils/serializeRuntimeOptions.ts
750
717
  /**
751
718
  * Serializes a JavaScript object into a string of source code that can be evaluated.
@@ -876,6 +843,99 @@ function generateExposes(options) {
876
843
  `;
877
844
  }
878
845
  //#endregion
846
+ //#region src/virtualModules/virtualRuntimeInitStatus.ts
847
+ const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
848
+ const MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache__";
849
+ function getRuntimeInitGlobalKey() {
850
+ return `__mf_init__${virtualRuntimeInitStatus.getImportId()}__`;
851
+ }
852
+ function getDeferredInitPromiseCode() {
853
+ return `let initResolve, initReject;
854
+ const initPromise = new Promise((re, rj) => {
855
+ initResolve = re;
856
+ initReject = rj;
857
+ });`;
858
+ }
859
+ function getSsrNoopResolveCode() {
860
+ return `if (typeof window === 'undefined') {
861
+ initResolve({
862
+ loadRemote: function() { return Promise.resolve(undefined); },
863
+ loadShare: function() { return Promise.resolve(undefined); },
864
+ });
865
+ }`;
866
+ }
867
+ function getRuntimeInitStateBootstrapCode(options) {
868
+ return `
869
+ const ${options.globalKeyVar} = ${JSON.stringify(getRuntimeInitGlobalKey())};
870
+ let ${options.stateVar} = globalThis[${options.globalKeyVar}];
871
+ if (!${options.stateVar}) {
872
+ ${getDeferredInitPromiseCode()}
873
+ ${options.stateVar} = globalThis[${options.globalKeyVar}] = {
874
+ initPromise,
875
+ initResolve,
876
+ initReject,
877
+ };
878
+ ${getSsrNoopResolveCode()}
879
+ }
880
+ const ${options.exposedConst} = ${options.stateVar}.${options.exposedProperty};
881
+ `;
882
+ }
883
+ function getRuntimeInitBootstrapCode() {
884
+ return `
885
+ const globalKey = ${JSON.stringify(getRuntimeInitGlobalKey())};
886
+ const moduleCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
887
+ globalThis[moduleCacheGlobalKey] ||= { share: {}, remote: {} };
888
+ globalThis[moduleCacheGlobalKey].share ||= {};
889
+ globalThis[moduleCacheGlobalKey].remote ||= {};
890
+ if (!globalThis[globalKey]) {
891
+ ${getDeferredInitPromiseCode()}
892
+ globalThis[globalKey] = {
893
+ initPromise,
894
+ initResolve,
895
+ initReject,
896
+ moduleCache: globalThis[moduleCacheGlobalKey],
897
+ };
898
+ ${getSsrNoopResolveCode()}
899
+ }
900
+ globalThis[globalKey].moduleCache ||= globalThis[moduleCacheGlobalKey];
901
+ globalThis[globalKey].moduleCache.share ||= {};
902
+ globalThis[globalKey].moduleCache.remote ||= {};
903
+ `;
904
+ }
905
+ function getRuntimeModuleCacheBootstrapCode() {
906
+ return `
907
+ const __mfCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
908
+ globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
909
+ globalThis[__mfCacheGlobalKey].share ||= {};
910
+ globalThis[__mfCacheGlobalKey].remote ||= {};
911
+ const __mfModuleCache = globalThis[__mfCacheGlobalKey];
912
+ `;
913
+ }
914
+ function getRuntimeInitPromiseBootstrapCode() {
915
+ return getRuntimeInitStateBootstrapCode({
916
+ globalKeyVar: "__mfPromiseGlobalKey",
917
+ stateVar: "__mfPromiseState",
918
+ exposedConst: "initPromise",
919
+ exposedProperty: "initPromise"
920
+ });
921
+ }
922
+ function getRuntimeInitResolveBootstrapCode() {
923
+ return getRuntimeInitStateBootstrapCode({
924
+ globalKeyVar: "__mfResolveGlobalKey",
925
+ stateVar: "__mfResolveState",
926
+ exposedConst: "initResolve",
927
+ exposedProperty: "initResolve"
928
+ });
929
+ }
930
+ function writeRuntimeInitStatus(command) {
931
+ const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
932
+ export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
933
+ virtualRuntimeInitStatus.writeSync(`
934
+ ${getRuntimeInitBootstrapCode()}
935
+ ${exportStatement}
936
+ `);
937
+ }
938
+ //#endregion
879
939
  //#region src/virtualModules/virtualShared_preBuild.ts
880
940
  /**
881
941
  * Even the resolveId hook cannot interfere with vite pre-build,
@@ -1018,7 +1078,16 @@ function getLocalProviderImportPath(pkg) {
1018
1078
  const resolved = (0, module$1.createRequire)(new URL(`file://${pathe.default.join(getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
1019
1079
  return isWorkspaceFilePath(resolved) ? resolved : void 0;
1020
1080
  } catch {
1021
- return;
1081
+ const resolved = getInstalledPackageEntry(pkg, {
1082
+ conditions: [
1083
+ "browser",
1084
+ "import",
1085
+ "module",
1086
+ "default"
1087
+ ],
1088
+ resolveSubpathWithRequire: false
1089
+ });
1090
+ return isWorkspaceFilePath(resolved) ? resolved : void 0;
1022
1091
  }
1023
1092
  }
1024
1093
  function getProjectResolvedImportPath(pkg) {
@@ -1033,7 +1102,12 @@ function getProjectResolvedImportPath(pkg) {
1033
1102
  }
1034
1103
  }
1035
1104
  function isWorkspaceFilePath(resolved) {
1036
- return !!resolved && !resolved.includes("/node_modules/") && !resolved.includes("\\node_modules\\");
1105
+ if (!resolved) return false;
1106
+ let realResolved = resolved;
1107
+ try {
1108
+ realResolved = fs.realpathSync.native(resolved);
1109
+ } catch {}
1110
+ return !realResolved.includes("/node_modules/") && !realResolved.includes("\\node_modules\\");
1037
1111
  }
1038
1112
  function isWorkspacePackageEntry(pkg, resolved) {
1039
1113
  if (!resolved || !pathe.default.isAbsolute(resolved) || !isWorkspaceFilePath(resolved)) return false;
@@ -1089,6 +1163,16 @@ function writePreBuildLibPath(pkg, shareItem) {
1089
1163
  export const jsx = __mfPrebuildExports.jsx;
1090
1164
  export const jsxs = __mfPrebuildExports.jsxs;
1091
1165
  export default __mfPrebuildExports;
1166
+ `, true);
1167
+ return;
1168
+ }
1169
+ const namedExports = getPackageNamedExports(pkg);
1170
+ if (namedExports.length > 0) {
1171
+ preBuildCacheMap[pkg].writeSync(`
1172
+ import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
1173
+ const __mfPrebuildExports = __mfPrebuildNamespace;
1174
+ ${namedExports.map((name) => `export const ${name} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}
1175
+ export default __mfPrebuildExports;
1092
1176
  `, true);
1093
1177
  return;
1094
1178
  }
@@ -1116,25 +1200,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
1116
1200
  }
1117
1201
  function getLoadShareModulePath(pkg, isRolldown) {
1118
1202
  if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
1119
- return loadShareCacheMap[pkg].getPath();
1203
+ return loadShareCacheMap[pkg].getImportId();
1120
1204
  }
1205
+ function generateDeferredHostProvidedExports(namedExports, pkg) {
1206
+ const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1207
+ const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
1208
+ const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
1209
+ const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1210
+ return `${declarations}
1211
+ const __mfApplyHostProvidedExports = (exportModule) => {
1212
+ ${assignments}
1213
+ };
1214
+ let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1215
+ if (exportModule === undefined) {
1216
+ initPromise.then(() => {
1217
+ exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1218
+ if (exportModule === undefined) {
1219
+ throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
1220
+ }
1221
+ __mfApplyHostProvidedExports(exportModule);
1222
+ });
1223
+ } else {
1224
+ __mfApplyHostProvidedExports(exportModule);
1225
+ }
1226
+ export { __mf_default as default };${namedExportLine}`;
1227
+ }
1228
+ function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
1229
+ return `let current = ${source};
1230
+ for (let i = 0; i < 5; i++) {
1231
+ const defaultExport = current?.default;
1232
+ ${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
1233
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1234
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
1235
+ current = defaultExport;
1236
+ }
1237
+ return current;`;
1238
+ }
1239
+ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
1240
+ ${generateShareModuleUnwrapCode({
1241
+ source: "mod",
1242
+ preserveNamedExports: true
1243
+ })}
1244
+ };`;
1121
1245
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1122
1246
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
1123
1247
  const importLine = getRuntimeModuleCacheBootstrapCode();
1124
1248
  if (shareItem.shareConfig.import === false) {
1125
1249
  const namedExports = getPackageNamedExports(pkg);
1126
1250
  let exportLine;
1127
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1251
+ if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
1128
1252
  else {
1129
1253
  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.`);
1130
- exportLine = "export default exportModule.default ?? exportModule";
1254
+ exportLine = generateDeferredHostProvidedExports([], pkg);
1131
1255
  }
1132
1256
  loadShareCacheMap[pkg].writeSync(`
1257
+ ${getRuntimeInitPromiseBootstrapCode()}
1133
1258
  ${importLine}
1134
- const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1135
- if (exportModule === undefined) {
1136
- throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
1137
- }
1138
1259
  ${exportLine}
1139
1260
  `, true);
1140
1261
  return;
@@ -1146,21 +1267,35 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1146
1267
  const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
1147
1268
  const lazyLocalFallbackSource = concreteSharedImportSource || localProviderPath || sharedImportSource;
1148
1269
  const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
1270
+ const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1149
1271
  const namedExports = getPackageNamedExports(pkg);
1150
1272
  let exportLine;
1151
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1273
+ if (namedExports.length > 0) {
1274
+ const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
1275
+ const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
1276
+ exportLine = `const __mfDefaultExport = (() => {
1277
+ ${generateShareModuleUnwrapCode({
1278
+ source: "exportModule",
1279
+ preserveNamedExports: false,
1280
+ stopWithReturn: "defaultExport ?? current"
1281
+ })}
1282
+ })();
1283
+ export default __mfDefaultExport;
1284
+ ${destructure}
1285
+ ${namedExportLine}`;
1286
+ } else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
1152
1287
  else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
1153
- const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1154
1288
  const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
1155
1289
  const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
1156
1290
  loadShareCacheMap[pkg].writeSync(`
1157
1291
  ${prebuildImportLine}
1158
1292
  ${devDynamicImportLine}
1159
1293
  ${importLine}
1294
+ ${normalizeLocalShareModuleCode}
1160
1295
  let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1161
1296
  if (exportModule === undefined) {
1162
- ${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
1163
- __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
1297
+ ${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
1298
+ __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1164
1299
  __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
1165
1300
  }
1166
1301
  ${exportLine}
@@ -1175,15 +1310,24 @@ function getUsedShares() {
1175
1310
  function addUsedShares(pkg) {
1176
1311
  usedShares.add(pkg);
1177
1312
  }
1313
+ const LOCAL_SHARED_IMPORT_MAP_ID = "virtual:mf-localSharedImportMap";
1178
1314
  function getLocalSharedImportMapPath() {
1179
- return getLocalSharedImportMapPath_temp();
1315
+ const { internalName, name } = getNormalizeModuleFederationOptions();
1316
+ return `${LOCAL_SHARED_IMPORT_MAP_ID}:${packageNameEncode(internalName || name)}`;
1317
+ }
1318
+ function getResolvedLocalSharedImportMapId() {
1319
+ return `\0${getLocalSharedImportMapPath()}`;
1320
+ }
1321
+ let invalidateLocalSharedImportMap;
1322
+ function setLocalSharedImportMapInvalidator(invalidator) {
1323
+ invalidateLocalSharedImportMap = invalidator;
1180
1324
  }
1181
1325
  let prevLocalSharedImportMapContent;
1182
1326
  function writeLocalSharedImportMap() {
1183
1327
  const nextContent = generateLocalSharedImportMap();
1184
1328
  if (prevLocalSharedImportMapContent !== nextContent) {
1185
1329
  prevLocalSharedImportMapContent = nextContent;
1186
- writeLocalSharedImportMap_temp(nextContent);
1330
+ invalidateLocalSharedImportMap?.();
1187
1331
  }
1188
1332
  }
1189
1333
  function shouldUseDirectReactImport() {
@@ -1309,9 +1453,9 @@ function getShareItemForPreload(pkg) {
1309
1453
  function generateSharedCacheSeedItem(pkg, importPath) {
1310
1454
  return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
1311
1455
  const mod = await import(${JSON.stringify(importPath)});
1312
- const exportModule = ${JSON.stringify(shouldUseDirectReactImport())} && ${JSON.stringify(pkg)} === "react"
1313
- ? (mod?.default ?? mod)
1314
- : {...mod};
1456
+ ${normalizeRuntimeShareCode}
1457
+ const normalizedModule = __mfNormalizeRuntimeShare(mod);
1458
+ const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
1315
1459
  Object.defineProperty(exportModule, "__esModule", {
1316
1460
  value: true,
1317
1461
  enumerable: false
@@ -1319,6 +1463,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
1319
1463
  __mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
1320
1464
  }`;
1321
1465
  }
1466
+ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
1467
+ let current = mod;
1468
+ for (let i = 0; i < 5; i++) {
1469
+ const defaultExport = current?.default;
1470
+ if (!defaultExport || typeof defaultExport !== "object") break;
1471
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1472
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
1473
+ current = defaultExport;
1474
+ }
1475
+ return current;
1476
+ };`;
1322
1477
  function generateDirectSharedCacheSeedCode(command = "build") {
1323
1478
  return getOrderedUsedShares().map((pkg) => {
1324
1479
  const shareItem = getShareItemForPreload(pkg);
@@ -1341,7 +1496,8 @@ function getHostAutoInitSharedSeedItems() {
1341
1496
  return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
1342
1497
  });
1343
1498
  }
1344
- function generateHostAutoInitSharedCacheSeedCode() {
1499
+ function generateHostAutoInitSharedCacheSeedCode(command = "build") {
1500
+ if (command === "build") return "";
1345
1501
  return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
1346
1502
  if (!shareItem) return null;
1347
1503
  return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
@@ -1373,43 +1529,62 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1373
1529
  if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
1374
1530
  globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
1375
1531
  }
1376
- import {createInstance, loadRemote} from "@module-federation/runtime";
1532
+ import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
1377
1533
  ${pluginImportNames.map((item) => item[1]).join("\n")}
1378
1534
  ${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
1379
1535
  ${getRuntimeModuleCacheBootstrapCode()}
1380
1536
  const initTokens = {}
1381
1537
  const shareScopeName = ${JSON.stringify(options.shareScope)}
1382
1538
  const mfName = ${JSON.stringify(options.internalName)}
1383
- let runtimeInstance
1384
1539
  let localSharedImportMapPromise
1385
1540
  let exposesMapPromise
1541
+ const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
1542
+ const message = String((error && error.message) || error || '');
1543
+ return message.includes('Importing a module script failed') ||
1544
+ message.includes('Failed to fetch') ||
1545
+ message.includes('Load failed') ||
1546
+ message.includes('Outdated Optimize Dep');
1547
+ });
1548
+ const waitSharedInitRetry = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1549
+ async function retrySharedInit(fn) {
1550
+ for (let attempt = 0; ; attempt++) {
1551
+ try {
1552
+ return await fn();
1553
+ } catch (e) {
1554
+ const canRetry = typeof shouldRetrySharedInitError === 'function' && shouldRetrySharedInitError(e);
1555
+ if (!canRetry || attempt >= 19) throw e;
1556
+ await waitSharedInitRetry(250);
1557
+ }
1558
+ }
1559
+ }
1386
1560
 
1387
1561
  async function getLocalSharedImportMap() {
1388
- localSharedImportMapPromise ??= import("${getLocalSharedImportMapPath()}")
1562
+ if (!localSharedImportMapPromise) {
1563
+ localSharedImportMapPromise = retrySharedInit(() => import("${getLocalSharedImportMapPath()}"))
1564
+ .catch((e) => { localSharedImportMapPromise = undefined; throw e; });
1565
+ }
1389
1566
  return localSharedImportMapPromise
1390
1567
  }
1391
1568
 
1392
1569
  async function getExposesMap() {
1393
- exposesMapPromise ??= import("${virtualExposesId}").then((mod) => mod.default ?? mod)
1570
+ if (!exposesMapPromise) {
1571
+ exposesMapPromise = retrySharedInit(() => import("${virtualExposesId}"))
1572
+ .then((mod) => mod.default ?? mod)
1573
+ .catch((e) => { exposesMapPromise = undefined; throw e; });
1574
+ }
1394
1575
  return exposesMapPromise
1395
1576
  }
1396
1577
 
1397
1578
  async function init(shared = {}, initScope = []) {
1398
1579
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1399
1580
  ${generateDirectSharedCacheSeedCode(command)}
1400
- const runtimeOptions = {
1581
+ const initRes = runtimeInit({
1401
1582
  name: mfName,
1402
1583
  remotes: usedRemotes,
1403
1584
  shared: usedShared,
1404
1585
  plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
1405
1586
  ${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
1406
- };
1407
- if (!runtimeInstance) {
1408
- runtimeInstance = createInstance(runtimeOptions);
1409
- } else {
1410
- runtimeInstance.initOptions(runtimeOptions);
1411
- }
1412
- const initRes = runtimeInstance;
1587
+ });
1413
1588
  // handling circular init calls
1414
1589
  var initToken = initTokens[shareScopeName];
1415
1590
  if (!initToken)
@@ -1419,14 +1594,27 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1419
1594
  initRes.initShareScopeMap('${options.shareScope}', shared);
1420
1595
  initResolve(initRes)
1421
1596
  try {
1422
- await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
1423
- strategy: '${options.shareStrategy}',
1424
- from: "build",
1425
- initScope
1426
- }));
1597
+ await retrySharedInit(async () => {
1598
+ await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
1599
+ strategy: '${options.shareStrategy}',
1600
+ from: "build",
1601
+ initScope
1602
+ }));
1603
+ });
1427
1604
  } catch (e) {
1428
1605
  console.error('[Module Federation]', e)
1429
1606
  }
1607
+ for (const [pkg, share] of Object.entries(usedShared)) {
1608
+ if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
1609
+ ${normalizeRuntimeShareCode}
1610
+ const versions = shared?.[pkg];
1611
+ const provider = versions && versions[Object.keys(versions)[0]];
1612
+ if (!provider) continue;
1613
+ const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
1614
+ const mod = typeof factory === "function" ? factory() : factory;
1615
+ const resolved = await Promise.resolve(mod);
1616
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1617
+ }
1430
1618
  return initRes
1431
1619
  }
1432
1620
 
@@ -1451,10 +1639,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1451
1639
  async function initHost() {
1452
1640
  if (!hostInitPromise) {
1453
1641
  hostInitPromise = (async () => {
1454
- ${generateHostAutoInitSharedCacheSeedCode()}
1642
+ ${generateHostAutoInitSharedCacheSeedCode(_command)}
1455
1643
  const remoteEntry = await import(${remoteEntryImport});
1456
1644
  const runtime = await remoteEntry.init();
1457
1645
  const usedShared = ${generateUsedSharedPreloadConfig()};
1646
+ ${normalizeRuntimeShareCode}
1458
1647
  for (const [pkg, share] of Object.entries(usedShared)) {
1459
1648
  if (__mfModuleCache.share[pkg] !== undefined) {
1460
1649
  continue;
@@ -1464,7 +1653,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1464
1653
  }).then((factory) => {
1465
1654
  const mod = typeof factory === "function" ? factory() : factory;
1466
1655
  return Promise.resolve(mod).then((resolved) => {
1467
- __mfModuleCache.share[pkg] = resolved;
1656
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1468
1657
  });
1469
1658
  });
1470
1659
  }
@@ -1493,7 +1682,7 @@ function getHostAutoInitImportId() {
1493
1682
  return hostAutoInitModule.getImportId();
1494
1683
  }
1495
1684
  function getHostAutoInitPath() {
1496
- return hostAutoInitModule.getPath();
1685
+ return hostAutoInitModule.getImportId();
1497
1686
  }
1498
1687
  //#endregion
1499
1688
  //#region src/virtualModules/virtualRemotes.ts
@@ -1516,7 +1705,9 @@ function getUsedRemotesMap() {
1516
1705
  }
1517
1706
  function generateRemotes(id, command) {
1518
1707
  const useReactProxy = command === "serve" && hasPackageDependency("react");
1519
- const reactImportLine = useReactProxy ? `import * as __mfReact from "react";` : "";
1708
+ const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
1709
+ import * as __mfReactNamespace from "react";
1710
+ const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
1520
1711
  const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
1521
1712
  import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
1522
1713
  const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
@@ -1526,13 +1717,13 @@ function generateRemotes(id, command) {
1526
1717
  }
1527
1718
  export const __moduleExports = exportModule;
1528
1719
  export const __mf_remote_pending = Promise.resolve(exportModule);
1529
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1720
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1530
1721
  const mod = await __mfRemotePending;
1531
1722
  if (mod !== undefined) exportModule = mod;
1532
1723
  }
1533
1724
  export const __moduleExports = exportModule;
1534
1725
  export const __mf_remote_pending = Promise.resolve(exportModule);
1535
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1726
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1536
1727
  return `
1537
1728
  ${reactImportLine}
1538
1729
  ${importLine}
@@ -1705,17 +1896,26 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1705
1896
  }
1706
1897
  return patched;
1707
1898
  }
1708
- function getBootstrapSource(initSrc, entrySrc) {
1709
- const remotePreloads = Object.values(getUsedRemotesMap()).flatMap((remotes) => Array.from(remotes)).filter((remote) => remote.includes("/")).sort().map((remote) => `runtime.loadRemote(${JSON.stringify(remote)})`).join(",");
1899
+ function getBootstrapSource(initSrc, entrySrc, useSystemImportFallback = false) {
1900
+ const remotePreloads = Object.entries(getUsedRemotesMap()).flatMap(([remoteKey, remotes]) => Array.from(remotes).filter((remote) => remote !== remoteKey)).sort().map((remote) => `runtime.loadRemote(${JSON.stringify(remote)})`).join(",");
1901
+ const importHelper = useSystemImportFallback ? `const __mfImport = (src) =>
1902
+ globalThis.System && typeof globalThis.System.import === 'function'
1903
+ ? globalThis.System.import(src)
1904
+ : import(src);
1905
+ ` : "";
1906
+ const importExpression = (src) => useSystemImportFallback ? `__mfImport(${JSON.stringify(src)})` : `import(${JSON.stringify(src)})`;
1710
1907
  return `${getRuntimeModuleCacheBootstrapCode()}
1711
- (async () => {
1712
- const { initHost } = await import(${JSON.stringify(initSrc)});
1908
+ ${importHelper}(async () => {
1909
+ const { initHost } = await ${importExpression(initSrc)};
1713
1910
  const runtime = await initHost();
1714
1911
  const __mfRemotePreloads = [${remotePreloads}];
1715
1912
  await Promise.all(__mfRemotePreloads);
1716
- })().then(() => import(${JSON.stringify(entrySrc)}));
1913
+ })().then(() => ${importExpression(entrySrc)});
1717
1914
  `;
1718
1915
  }
1916
+ function getSystemBootstrapSource(initSrc, entrySrc) {
1917
+ return getBootstrapSource(initSrc, entrySrc, true);
1918
+ }
1719
1919
  function injectHtml() {
1720
1920
  return inject === "html" && (htmlFilePath || hasPackageDependency("@sveltejs/kit"));
1721
1921
  }
@@ -1723,6 +1923,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1723
1923
  if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
1724
1924
  return inject === "entry" || !htmlFilePath;
1725
1925
  }
1926
+ function normalizeDevHtmlProxyId(id) {
1927
+ return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
1928
+ }
1726
1929
  return [{
1727
1930
  name: "add-entry",
1728
1931
  apply: "serve",
@@ -1741,7 +1944,20 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1741
1944
  }
1742
1945
  },
1743
1946
  configureServer(server) {
1744
- server.middlewares.use((req, _res, next) => {
1947
+ server.middlewares.use((req, res, next) => {
1948
+ const rawUrl = req.url?.split("#")[0] ?? "";
1949
+ if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
1950
+ const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
1951
+ const params = new URLSearchParams(query);
1952
+ const initSrc = params.get("init");
1953
+ const entrySrc = params.get("entry");
1954
+ if (initSrc && entrySrc) {
1955
+ res.statusCode = 200;
1956
+ res.setHeader("Content-Type", "application/javascript");
1957
+ res.end(getBootstrapSource(initSrc, entrySrc));
1958
+ return;
1959
+ }
1960
+ }
1745
1961
  if (!fileName) {
1746
1962
  next();
1747
1963
  return;
@@ -1758,7 +1974,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1758
1974
  const base = viteConfig.base.replace(/\/$/, "");
1759
1975
  const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
1760
1976
  const html = rewriteEntryScripts(c, (originalSrc) => {
1761
- return `/@id/${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1977
+ return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1762
1978
  init: sanitizeDevEntryPath(stripBase(devEntryPath)),
1763
1979
  entry: sanitizeDevEntryPath(stripBase(originalSrc))
1764
1980
  }).toString()}`;
@@ -1767,11 +1983,12 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1767
1983
  }
1768
1984
  },
1769
1985
  resolveId(id) {
1770
- if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1986
+ if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1771
1987
  },
1772
1988
  load(id) {
1773
- if (!id.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1774
- const params = new URLSearchParams(id.slice(28));
1989
+ const normalizedId = normalizeDevHtmlProxyId(id);
1990
+ if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1991
+ const params = new URLSearchParams(normalizedId.slice(28));
1775
1992
  const initSrc = params.get("init");
1776
1993
  const entrySrc = params.get("entry");
1777
1994
  if (!initSrc || !entrySrc) return;
@@ -1855,7 +2072,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1855
2072
  const bootstrapRef = this.emitFile({
1856
2073
  type: "asset",
1857
2074
  fileName: bootstrapFileName,
1858
- source: getBootstrapSource(initPath, entrySrc)
2075
+ source: getSystemBootstrapSource(initPath, entrySrc)
1859
2076
  });
1860
2077
  const bootstrapPath = viteConfig.base + this.getFileName(bootstrapRef);
1861
2078
  return scriptTag.replace(entrySrc, bootstrapPath);
@@ -2000,7 +2217,7 @@ function getHmrWsPath(base, hmrPath) {
2000
2217
  return `${normalizedBase.endsWith("/") ? normalizedBase.slice(0, -1) : normalizedBase}/${normalizedPath.startsWith("/") ? normalizedPath.slice(1) : normalizedPath}`;
2001
2218
  }
2002
2219
  function shouldIgnoreFile(file, options) {
2003
- return file.includes("/node_modules/") || file.includes("\\node_modules\\") || file.includes(`/${options.virtualModuleDir}/`) || file.includes(`\\${options.virtualModuleDir}\\`) || file.includes("/.vite/") || file.includes("\\.vite\\") || file.includes("/.__mf__temp/") || file.includes("\\.__mf__temp\\") || file.includes("/.mf/") || file.includes("\\.mf\\") || file.includes("/mf-manifest.json") || file.includes("\\mf-manifest.json") || file.includes("/mf-stats.json") || file.includes("\\mf-stats.json");
2220
+ return file.includes("/node_modules/") || file.includes("\\node_modules\\") || file.includes(`/${options.virtualModuleDir}/`) || file.includes(`\\${options.virtualModuleDir}\\`) || file.includes("/.vite/") || file.includes("\\.vite\\") || file.includes("/.mf/") || file.includes("\\.mf\\") || file.includes("/mf-manifest.json") || file.includes("\\mf-manifest.json") || file.includes("/mf-stats.json") || file.includes("\\mf-stats.json");
2004
2221
  }
2005
2222
  function getRemoteHmrWsUrl(server) {
2006
2223
  const hmr = server.config.server.hmr;
@@ -2041,7 +2258,22 @@ function getStringPreview(value, max = 180) {
2041
2258
  return rawValue.slice(0, max);
2042
2259
  }
2043
2260
  function isRemoteHmrEnabled(dev) {
2044
- return typeof dev === "object" && dev !== null && dev.remoteHmr === true;
2261
+ return typeof dev === "object" && dev !== null && !!dev.remoteHmr;
2262
+ }
2263
+ /**
2264
+ * Detects whether the Vite plugin pipeline includes a framework with
2265
+ * cross-federation HMR support (a shared runtime proxy that works
2266
+ * across module federation boundaries).
2267
+ *
2268
+ * Currently only React is supported via the shared /@react-refresh proxy.
2269
+ */
2270
+ function hasCrossFederationHmr(plugins) {
2271
+ const supportedPlugins = ["vite:react-refresh", "vite:react-swc:refresh"];
2272
+ return plugins.some((p) => supportedPlugins.includes(p.name));
2273
+ }
2274
+ function resolveHmrStrategy(dev, plugins) {
2275
+ if (typeof dev === "object" && dev !== null && dev.remoteHmr === "full-reload") return "full-reload";
2276
+ return hasCrossFederationHmr(plugins) ? "native" : "full-reload";
2045
2277
  }
2046
2278
  function pluginDevRemoteHmr(options) {
2047
2279
  return {
@@ -2051,6 +2283,7 @@ function pluginDevRemoteHmr(options) {
2051
2283
  if (!isRemoteHmrEnabled(options.dev)) return;
2052
2284
  const isRemote = Object.keys(options.exposes).length > 0;
2053
2285
  const isHost = Object.keys(options.remotes).length > 0;
2286
+ const strategy = resolveHmrStrategy(options.dev, server.config.plugins);
2054
2287
  if (isRemote) {
2055
2288
  const endpointPath = getRemoteHmrPath(server.config.base);
2056
2289
  const wsUrl = getRemoteHmrWsUrl(server);
@@ -2074,6 +2307,7 @@ function pluginDevRemoteHmr(options) {
2074
2307
  }));
2075
2308
  });
2076
2309
  const broadcast = (file) => {
2310
+ if (strategy === "native") return;
2077
2311
  if (shouldIgnoreFile(file, options)) return;
2078
2312
  server.ws.send({
2079
2313
  type: "custom",
@@ -2138,6 +2372,7 @@ function pluginDevRemoteHmr(options) {
2138
2372
  }
2139
2373
  const ws = new WebSocket(metadata.wsUrl, "vite-hmr");
2140
2374
  ws.onmessage = (rawEvent) => {
2375
+ if (strategy === "native") return;
2141
2376
  const message = parseRemoteHmrMessage(rawEvent.data);
2142
2377
  if (!message || message.event !== REMOTE_HMR_EVENT) return;
2143
2378
  server.ws.send({ type: "full-reload" });
@@ -2162,6 +2397,7 @@ function pluginDevRemoteHmr(options) {
2162
2397
  };
2163
2398
  for (const [remoteName, remote] of Object.entries(options.remotes)) connectRemote(remoteName, remote);
2164
2399
  const triggerHostReload = (file) => {
2400
+ if (strategy === "native") return;
2165
2401
  if (shouldIgnoreFile(file, options)) return;
2166
2402
  server.ws.send({ type: "full-reload" });
2167
2403
  };
@@ -2484,6 +2720,26 @@ function initVirtualModules(command, remoteEntryId) {
2484
2720
  }
2485
2721
  //#endregion
2486
2722
  //#region src/utils/bundleHelpers.ts
2723
+ function isOutputChunk$1(chunk) {
2724
+ return chunk.type === "chunk";
2725
+ }
2726
+ function escapeRegExp(value) {
2727
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2728
+ }
2729
+ function getProxyBaseName(fileName) {
2730
+ return fileName.replace(/^.*\//, "").replace(/\.js$/, "").replace(/-[A-Za-z0-9_-]+$/, "");
2731
+ }
2732
+ function extractFunctionDeclaration(code, functionName) {
2733
+ const funcRe = new RegExp(`function\\s+${functionName}\\s*\\([^)]*\\)\\s*\\{`);
2734
+ const funcStart = code.search(funcRe);
2735
+ if (funcStart < 0) return;
2736
+ let depth = 0;
2737
+ for (let i = code.indexOf("{", funcStart); i < code.length; i++) if (code[i] === "{") depth++;
2738
+ else if (code[i] === "}") {
2739
+ depth--;
2740
+ if (depth === 0) return code.slice(funcStart, i + 1);
2741
+ }
2742
+ }
2487
2743
  /**
2488
2744
  * Resolve the local alias for a non-inlineable proxy binding.
2489
2745
  * If Rollup's deconflict renamed the alias but didn't update references
@@ -2506,6 +2762,147 @@ function resolveProxyAlias(binding, proxyLocal, code, fullImport, claimedLocals
2506
2762
  local
2507
2763
  };
2508
2764
  }
2765
+ function collectLoadShareProxyChunks(bundle, loadShareTag) {
2766
+ const proxyChunks = /* @__PURE__ */ new Map();
2767
+ for (const [fileName, chunk] of Object.entries(bundle)) {
2768
+ if (!isOutputChunk$1(chunk)) continue;
2769
+ if (fileName.includes(loadShareTag) && fileName.includes("commonjs-proxy")) proxyChunks.set(fileName, {
2770
+ code: chunk.code,
2771
+ fileName
2772
+ });
2773
+ }
2774
+ return proxyChunks;
2775
+ }
2776
+ function collectSystemProxyInfos(proxyChunks, loadShareTag) {
2777
+ const systemProxyInfo = /* @__PURE__ */ new Map();
2778
+ for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
2779
+ const depsMatch = proxyInfo.code.match(/System\.register\(\[([\s\S]*?)\]/);
2780
+ if (!depsMatch) continue;
2781
+ const loadShareDep = Array.from(depsMatch[1].matchAll(/["']([^"']+)["']/g)).map((m) => m[1]).find((dep) => dep.includes(loadShareTag) && !dep.includes("commonjs-proxy"));
2782
+ if (!loadShareDep) continue;
2783
+ const loadShareBindings = {};
2784
+ for (const m of proxyInfo.code.matchAll(/([A-Za-z_$][\w$]*)\s*=\s*module\d+\.([A-Za-z_$][\w$]*)/g)) loadShareBindings[m[1]] = m[2];
2785
+ const exportMap = {};
2786
+ const objectExportMatch = proxyInfo.code.match(/exports\(\s*\{([\s\S]*?)\}\s*\)/);
2787
+ if (objectExportMatch) for (const m of objectExportMatch[1].matchAll(/([A-Za-z_$][\w$]*)\s*:\s*([A-Za-z_$][\w$]*)/g)) {
2788
+ const [, exported, local] = m;
2789
+ const funcBody = extractFunctionDeclaration(proxyInfo.code, local);
2790
+ if (funcBody) exportMap[exported] = {
2791
+ type: "helper",
2792
+ code: funcBody
2793
+ };
2794
+ }
2795
+ for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
2796
+ const exported = m[1];
2797
+ const expression = m[2];
2798
+ for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
2799
+ exportMap[exported] = {
2800
+ type: "reexport",
2801
+ exportName
2802
+ };
2803
+ break;
2804
+ }
2805
+ }
2806
+ if (Object.keys(exportMap).length > 0) systemProxyInfo.set(proxyFileName, {
2807
+ loadShareDep,
2808
+ exportMap
2809
+ });
2810
+ }
2811
+ return systemProxyInfo;
2812
+ }
2813
+ function rewriteEsmProxyConsumers(code, proxyChunks) {
2814
+ let nextCode = code;
2815
+ const claimedLocals = /* @__PURE__ */ new Set();
2816
+ for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
2817
+ const proxyBaseName = getProxyBaseName(proxyFileName);
2818
+ const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
2819
+ if (!importMatch) continue;
2820
+ const fullImport = importMatch[0];
2821
+ const bindings = importMatch[1].split(",").map((s) => {
2822
+ const parts = s.trim().split(/\s+as\s+/);
2823
+ return {
2824
+ imported: parts[0].trim(),
2825
+ local: (parts[1] || parts[0]).trim()
2826
+ };
2827
+ });
2828
+ const exportMapMatch = proxyInfo.code.match(/export\s*\{([^}]+)\}/);
2829
+ if (!exportMapMatch) continue;
2830
+ const exportMap = {};
2831
+ for (const entry of exportMapMatch[1].split(",")) {
2832
+ const parts = entry.trim().split(/\s+as\s+/);
2833
+ if (parts.length === 2) exportMap[parts[1].trim()] = parts[0].trim();
2834
+ }
2835
+ const inlineable = [];
2836
+ const nonInlineable = [];
2837
+ const pendingLocals = new Set(bindings.map((binding) => binding.local));
2838
+ for (const b of bindings) {
2839
+ pendingLocals.delete(b.local);
2840
+ const proxyLocal = exportMap[b.imported];
2841
+ if (!proxyLocal) {
2842
+ claimedLocals.add(b.local);
2843
+ nonInlineable.push(b);
2844
+ continue;
2845
+ }
2846
+ const funcBody = extractFunctionDeclaration(proxyInfo.code, proxyLocal);
2847
+ if (funcBody) {
2848
+ inlineable.push({
2849
+ local: b.local,
2850
+ funcBody: funcBody.replace(new RegExp(`function\\s+${proxyLocal}\\s*\\(`), `function ${b.local}(`)
2851
+ });
2852
+ claimedLocals.add(b.local);
2853
+ } else {
2854
+ const unavailableLocals = new Set(claimedLocals);
2855
+ pendingLocals.forEach((local) => unavailableLocals.add(local));
2856
+ const resolvedBinding = resolveProxyAlias(b, proxyLocal, nextCode, fullImport, unavailableLocals);
2857
+ claimedLocals.add(resolvedBinding.local);
2858
+ nonInlineable.push(resolvedBinding);
2859
+ }
2860
+ }
2861
+ const hasRenamedAlias = nonInlineable.some((b) => bindings.find((ob) => ob.imported === b.imported)?.local !== b.local);
2862
+ if (inlineable.length === 0 && !hasRenamedAlias) continue;
2863
+ let replacement = "";
2864
+ if (nonInlineable.length > 0) replacement = `import{${nonInlineable.map((b) => b.imported === b.local ? b.imported : `${b.imported} as ${b.local}`).join(",")}}from"${importMatch[2]}";`;
2865
+ replacement += inlineable.map((f) => f.funcBody).join("");
2866
+ nextCode = nextCode.replace(fullImport, () => replacement);
2867
+ }
2868
+ return nextCode;
2869
+ }
2870
+ function rewriteSystemProxyConsumers(code, systemProxyInfo) {
2871
+ if (!code.includes("System.register(")) return code;
2872
+ let nextCode = code;
2873
+ for (const [proxyFileName, proxyInfo] of Array.from(systemProxyInfo.entries())) {
2874
+ const proxyBaseName = getProxyBaseName(proxyFileName);
2875
+ const depMatch = new RegExp(`["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']`).exec(nextCode);
2876
+ if (!depMatch) continue;
2877
+ let setterIndex = 0;
2878
+ const depListMatch = nextCode.match(/System\.register\(\[([\s\S]*?)\]/);
2879
+ if (depListMatch) setterIndex = Array.from(depListMatch[1].matchAll(/["']([^"']+)["']/g)).map((m) => m[1]).findIndex((dep) => dep.includes(proxyBaseName));
2880
+ if (setterIndex < 0) continue;
2881
+ const settersStart = nextCode.indexOf("setters: [");
2882
+ if (settersStart < 0) continue;
2883
+ const setterMatch = Array.from(nextCode.slice(settersStart).matchAll(/\((module\d+)\)\s*=>\s*\{([\s\S]*?)\}/g))[setterIndex];
2884
+ if (!setterMatch) continue;
2885
+ const [fullSetter, moduleLocal, setterBody] = setterMatch;
2886
+ const helpersToInline = [];
2887
+ const nextSetterBody = setterBody.replace(new RegExp(`([A-Za-z_$][\\w$]*)\\s*=\\s*${moduleLocal}\\.([A-Za-z_$][\\w$]*);?`, "g"), (assignment, local, imported) => {
2888
+ const mapped = proxyInfo.exportMap[imported];
2889
+ if (!mapped) return assignment;
2890
+ if (mapped.type === "helper") {
2891
+ helpersToInline.push(mapped.code.replace(new RegExp(`function\\s+${imported}\\s*\\(`), `function ${local}(`));
2892
+ return "";
2893
+ }
2894
+ return `${local} = ${moduleLocal}.${mapped.exportName};`;
2895
+ });
2896
+ if (nextSetterBody === setterBody && helpersToInline.length === 0) continue;
2897
+ const nextSetter = fullSetter.replace(setterBody, () => nextSetterBody);
2898
+ nextCode = nextCode.replace(fullSetter, () => nextSetter);
2899
+ nextCode = nextCode.replace(depMatch[0], JSON.stringify(proxyInfo.loadShareDep));
2900
+ if (helpersToInline.length > 0) nextCode = nextCode.replace("execute: (function() {", () => {
2901
+ return `execute: (function() {${helpersToInline.join("")}`;
2902
+ });
2903
+ }
2904
+ return nextCode;
2905
+ }
2509
2906
  function findRemoteEntryFile(filename, bundle) {
2510
2907
  for (const [_, fileData] of Object.entries(bundle)) if (filename.replace(/[\[\]]/g, "_").replace(/\.[^/.]+$/, "") === fileData.name || fileData.name === "remoteEntry") return fileData.fileName;
2511
2908
  }
@@ -2675,6 +3072,9 @@ function normalizeNodeModulePath(source) {
2675
3072
  function isNodeModulePath(source) {
2676
3073
  return source.includes("/node_modules/") || source.includes("\\node_modules\\");
2677
3074
  }
3075
+ function filterId(id) {
3076
+ return typeof id === "string" && !id.includes("\0");
3077
+ }
2678
3078
  function getMatchingNodeModuleSubpath(source, candidates) {
2679
3079
  const normalized = normalizeNodeModulePath(source);
2680
3080
  return [...candidates].sort((a, b) => b.length - a.length).find((candidate) => normalized.includes(`/node_modules/${candidate}/`) || normalized.includes(`/node_modules/${candidate}.`));
@@ -2859,10 +3259,11 @@ const Manifest = () => {
2859
3259
  alias: remoteKey,
2860
3260
  entry: "*"
2861
3261
  })));
2862
- const shared = Array.from(getUsedShares()).map((shareKey) => {
3262
+ const shared = Array.from(getUsedShares()).flatMap((shareKey) => {
2863
3263
  const shareItem = getNormalizeShareItem(shareKey);
3264
+ if (!shareItem) return [];
2864
3265
  const assets = preloadMap[shareKey] || createEmptyAssetMap();
2865
- return {
3266
+ return [{
2866
3267
  id: `${name}:${shareKey}`,
2867
3268
  name: shareKey,
2868
3269
  version: shareItem.version,
@@ -2878,7 +3279,7 @@ const Manifest = () => {
2878
3279
  sync: assets.css.sync
2879
3280
  }
2880
3281
  }
2881
- };
3282
+ }];
2882
3283
  });
2883
3284
  const exposes = Object.entries(options.exposes).map(([key, value]) => {
2884
3285
  const formatKey = key.replace("./", "");
@@ -3030,7 +3431,6 @@ function pluginModuleParseEnd_default(excludeFn, options) {
3030
3431
  }
3031
3432
  //#endregion
3032
3433
  //#region src/plugins/pluginProxyRemoteEntry.ts
3033
- const filter$1 = (0, _rollup_pluginutils.createFilter)();
3034
3434
  function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
3035
3435
  let viteConfig, _command, root;
3036
3436
  return {
@@ -3070,14 +3470,14 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
3070
3470
  },
3071
3471
  transform(code, id) {
3072
3472
  return mapCodeToCodeWithSourcemap((() => {
3073
- if (!filter$1(id)) return;
3473
+ if (!filterId(id)) return;
3074
3474
  if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
3075
3475
  if (id === virtualExposesId) return generateExposes(options);
3076
3476
  if (id.includes(getHostAutoInitPath())) {
3077
3477
  if (_command === "serve") {
3078
3478
  const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
3079
3479
  const publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
3080
- const fallbackOrigin = `http://${host}:${viteConfig.server?.port}`;
3480
+ const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
3081
3481
  const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
3082
3482
  return `
3083
3483
  const origin = typeof window !== 'undefined' && (${!options.ignoreOrigin}) ? window.origin : ${JSON.stringify(fallbackOrigin)};
@@ -3128,10 +3528,25 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
3128
3528
  }
3129
3529
  //#endregion
3130
3530
  //#region src/plugins/pluginProxyRemotes.ts
3131
- const filter = (0, _rollup_pluginutils.createFilter)();
3132
3531
  function isNodeModulesImporter(importer) {
3133
3532
  return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
3134
3533
  }
3534
+ function appendAlias(config, alias) {
3535
+ config.resolve ??= {};
3536
+ const existingAlias = config.resolve.alias;
3537
+ if (!existingAlias) {
3538
+ config.resolve.alias = [alias];
3539
+ return;
3540
+ }
3541
+ if (Array.isArray(existingAlias)) {
3542
+ existingAlias.push(alias);
3543
+ return;
3544
+ }
3545
+ config.resolve.alias = [...Object.entries(existingAlias).map(([find, replacement]) => ({
3546
+ find,
3547
+ replacement
3548
+ })), alias];
3549
+ }
3135
3550
  function pluginProxyRemotes_default(options) {
3136
3551
  let command;
3137
3552
  let root = process.cwd();
@@ -3144,23 +3559,24 @@ function pluginProxyRemotes_default(options) {
3144
3559
  const remoteModule = getRemoteVirtualModule(source, command);
3145
3560
  addUsedRemote(remoteName, source);
3146
3561
  refreshHostAutoInit();
3147
- return remoteModule.getPath();
3562
+ return remoteModule.getImportId();
3148
3563
  }
3149
3564
  return {
3150
3565
  name: "proxyRemotes",
3566
+ enforce: "pre",
3151
3567
  config(config, { command: _command }) {
3152
3568
  command = _command;
3153
3569
  root = config.root || process.cwd();
3154
3570
  Object.keys(remotes).forEach((key) => {
3155
3571
  const remote = remotes[key];
3156
- config.resolve.alias.push({
3572
+ appendAlias(config, {
3157
3573
  find: new RegExp(`^(${remote.name}(\/.*|$))`),
3158
3574
  replacement: "$1"
3159
3575
  });
3160
3576
  });
3161
3577
  },
3162
3578
  resolveId(source, importer) {
3163
- if (!filter(source)) return;
3579
+ if (!filterId(source)) return;
3164
3580
  for (const remote of Object.values(remotes)) {
3165
3581
  if (source !== remote.name && !source.startsWith(`${remote.name}/`)) continue;
3166
3582
  return resolveRemoteId(source, importer, remote.name);
@@ -3261,7 +3677,7 @@ function excludeSharedSubDependencies(shared) {
3261
3677
  for (const dep of deps) {
3262
3678
  const depKey = sharedKeyByBase.get(dep);
3263
3679
  if (depKey && depKey !== parentKey) {
3264
- if (shared[depKey]?.shareConfig.import === false) continue;
3680
+ if (shared[depKey]?.shareConfig.singleton === true || shared[depKey]?.shareConfig.import === false) continue;
3265
3681
  mfWarn(`"${dep}" is a dependency of shared package "${parentKey}" and is also shared separately. This may cause initialization order issues in dev mode. Consider sharing only "${parentKey}".\n Auto-excluding "${dep}" from shared modules for dev mode.`);
3266
3682
  delete shared[depKey];
3267
3683
  sharedKeys.delete(depKey);
@@ -3277,15 +3693,27 @@ function proxySharedModule(options) {
3277
3693
  let useDirectReactImport = false;
3278
3694
  let useRolldown = false;
3279
3695
  const savePrebuild = new PromiseStore();
3696
+ let devServer;
3280
3697
  return [
3281
3698
  {
3282
3699
  name: "generateLocalSharedImportMap",
3283
3700
  enforce: "post",
3701
+ configureServer(server) {
3702
+ devServer = server;
3703
+ setLocalSharedImportMapInvalidator(() => {
3704
+ const module = server.moduleGraph.getModuleById(getResolvedLocalSharedImportMapId());
3705
+ if (module) server.moduleGraph.invalidateModule(module);
3706
+ });
3707
+ },
3708
+ resolveId(source) {
3709
+ if (source === getLocalSharedImportMapPath()) return getResolvedLocalSharedImportMapId();
3710
+ },
3284
3711
  load(id) {
3285
- if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
3712
+ if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) => generateLocalSharedImportMap());
3286
3713
  },
3287
- transform(_, id) {
3288
- if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
3714
+ closeBundle() {
3715
+ if (devServer) return;
3716
+ setLocalSharedImportMapInvalidator(void 0);
3289
3717
  }
3290
3718
  },
3291
3719
  {
@@ -3416,7 +3844,7 @@ function wrapDynamicImport(original) {
3416
3844
  }
3417
3845
  function applyRewrites(code, imports, id) {
3418
3846
  if (imports.length === 0) return;
3419
- const ms = new magic_string.default(code);
3847
+ const ms = new CodeRewriter(code);
3420
3848
  let changed = false;
3421
3849
  let counter = 0;
3422
3850
  for (const imp of imports) switch (imp.kind) {
@@ -3464,7 +3892,7 @@ function applyRewrites(code, imports, id) {
3464
3892
  if (!changed) return;
3465
3893
  return {
3466
3894
  code: ms.toString(),
3467
- map: ms.generateMap({ hires: true })
3895
+ map: ms.generateMap(id)
3468
3896
  };
3469
3897
  }
3470
3898
  async function collectFromAST(ast, code, isRemoteImport) {
@@ -3906,6 +4334,9 @@ function ignoreFederationGeneratedFiles(config, options) {
3906
4334
  function isSharedResolverInternalImporter(importer) {
3907
4335
  return !!importer && (importer.includes("__loadShare__") || importer.includes("__prebuild__"));
3908
4336
  }
4337
+ function isCommonJsImporter(importer) {
4338
+ return !!importer && (importer.endsWith(".cjs") || importer.includes("/cjs/"));
4339
+ }
3909
4340
  function isOutputChunk(chunk) {
3910
4341
  return chunk.type === "chunk";
3911
4342
  }
@@ -3950,12 +4381,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
3950
4381
  return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
3951
4382
  }
3952
4383
  /**
3953
- * Plugin that runs FIRST to create virtual module files in the config hook.
3954
- * This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
4384
+ * Plugin that runs FIRST to register generated virtual modules in the config hook.
4385
+ * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
3955
4386
  * before Vite's optimization phase.
3956
4387
  */
3957
4388
  function createEarlyVirtualModulesPlugin(options) {
3958
- const { shared, remotes, virtualModuleDir } = options;
4389
+ const { shared, remotes } = options;
3959
4390
  const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
3960
4391
  return {
3961
4392
  name: "vite:module-federation-early-init",
@@ -3965,9 +4396,6 @@ function createEarlyVirtualModulesPlugin(options) {
3965
4396
  const root = config.root || process.cwd();
3966
4397
  setPackageDetectionCwd(root);
3967
4398
  const isVinext = hasPackageDependency("vinext");
3968
- initVirtualModuleInfrastructure(root, virtualModuleDir);
3969
- VirtualModule.setRoot(root);
3970
- VirtualModule.ensureVirtualPackageExists();
3971
4399
  initVirtualModules(_command, getRemoteEntryId(options));
3972
4400
  const isRolldown = getIsRolldown(this);
3973
4401
  if (remotes && Object.keys(remotes).length > 0) {
@@ -3989,9 +4417,10 @@ function createEarlyVirtualModulesPlugin(options) {
3989
4417
  optimizeDeps.rolldownOptions.plugins ??= [];
3990
4418
  optimizeDeps.rolldownOptions.plugins.push({
3991
4419
  name: "module-federation:optimize-shared-resolver",
3992
- resolveId(source, importer) {
4420
+ resolveId(source, importer, options) {
4421
+ if (options?.kind?.startsWith("require")) return;
3993
4422
  if (isSharedResolverInternalImporter(importer)) return;
3994
- if (source !== "react/jsx-runtime" && source !== "react/jsx-dev-runtime") return;
4423
+ if (isCommonJsImporter(importer)) return;
3995
4424
  const key = findSharedKey(source, shared);
3996
4425
  if (!key) return;
3997
4426
  if (source.endsWith(".css")) return;
@@ -4012,6 +4441,10 @@ function createEarlyVirtualModulesPlugin(options) {
4012
4441
  optimizeDeps.esbuildOptions.plugins.push({
4013
4442
  name: "module-federation:optimize-shared-proxy",
4014
4443
  setup(build) {
4444
+ build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
4445
+ path: args.path,
4446
+ external: true
4447
+ }));
4015
4448
  build.onResolve({ filter: /.*/ }, (args) => {
4016
4449
  if (!args.importer || args.namespace === "mf-shared") return;
4017
4450
  if (isSharedResolverInternalImporter(args.importer)) return;
@@ -4043,7 +4476,6 @@ export default __mfShared.default ?? __mfShared;`
4043
4476
  }
4044
4477
  });
4045
4478
  }
4046
- config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
4047
4479
  }
4048
4480
  for (const key of Object.keys(shared)) {
4049
4481
  const shareItem = shared[key];
@@ -4054,7 +4486,6 @@ export default __mfShared.default ?? __mfShared;`
4054
4486
  for (const subpath of getCommonSharedSubpaths(key)) {
4055
4487
  writePreBuildLibPath(subpath, shareItem);
4056
4488
  optimizeDeps.include.push(subpath);
4057
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4058
4489
  }
4059
4490
  }
4060
4491
  continue;
@@ -4071,14 +4502,11 @@ export default __mfShared.default ?? __mfShared;`
4071
4502
  const optimizeDeps = config.optimizeDeps ??= {};
4072
4503
  optimizeDeps.include ??= [];
4073
4504
  optimizeDeps.exclude ??= [];
4074
- const shouldBypassOptimizeDep = isLitShare(key);
4075
- if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
4076
- if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
4077
- optimizeDeps.include.push(getPreBuildLibImportId(key));
4505
+ if (isLitShare(key)) optimizeDeps.exclude.push(key);
4506
+ else optimizeDeps.include.push(key);
4078
4507
  for (const subpath of getCommonSharedSubpaths(key)) {
4079
4508
  writePreBuildLibPath(subpath, shareItem);
4080
4509
  optimizeDeps.include.push(subpath);
4081
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4082
4510
  }
4083
4511
  }
4084
4512
  }
@@ -4098,6 +4526,21 @@ function federation(mfUserOptions) {
4098
4526
  let command;
4099
4527
  let desiredRolldownOutput;
4100
4528
  return [
4529
+ {
4530
+ name: "vite:module-federation-virtual-modules",
4531
+ enforce: "pre",
4532
+ resolveId(id) {
4533
+ const virtualModule = VirtualModule.findById(id);
4534
+ if (!virtualModule) return;
4535
+ return virtualModule.getResolvedId();
4536
+ },
4537
+ load(id) {
4538
+ const virtualModule = VirtualModule.findById(id);
4539
+ if (!virtualModule) return;
4540
+ if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
4541
+ return virtualModule.code;
4542
+ }
4543
+ },
4101
4544
  createEarlyVirtualModulesPlugin(options),
4102
4545
  ...isVinext ? [{
4103
4546
  name: "module-federation-vinext-react-server-build-alias",
@@ -4122,9 +4565,7 @@ function federation(mfUserOptions) {
4122
4565
  config(_config, env) {
4123
4566
  command = env.command;
4124
4567
  },
4125
- configResolved(config) {
4126
- VirtualModule.setRoot(config.root);
4127
- VirtualModule.ensureVirtualPackageExists();
4568
+ configResolved() {
4128
4569
  initVirtualModules(command, remoteEntryId);
4129
4570
  }
4130
4571
  },
@@ -4267,9 +4708,8 @@ function federation(mfUserOptions) {
4267
4708
  }
4268
4709
  },
4269
4710
  load(id) {
4270
- if (id.startsWith("\0")) return;
4271
4711
  if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
4272
- let code = (0, fs.readFileSync)(id, "utf-8");
4712
+ let code = VirtualModule.findById(id)?.code ?? (0, fs.readFileSync)(id, "utf-8");
4273
4713
  code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4274
4714
  code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4275
4715
  /**
@@ -4288,7 +4728,10 @@ function federation(mfUserOptions) {
4288
4728
  *
4289
4729
  * @see https://rollupjs.org/plugin-development/#synthetic-named-exports
4290
4730
  */
4291
- if (!code.includes("__moduleExports")) code = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4731
+ if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
4732
+ const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4733
+ code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
4734
+ }
4292
4735
  if (getIsRolldown(this)) return { code };
4293
4736
  return {
4294
4737
  code,
@@ -4302,87 +4745,17 @@ function federation(mfUserOptions) {
4302
4745
  if (!isFederationControlChunk(fileName, filename)) continue;
4303
4746
  chunk.code = sanitizeFederationControlChunk(chunk.code, fileName, filename);
4304
4747
  }
4305
- const proxyChunks = /* @__PURE__ */ new Map();
4306
- for (const [fileName, chunk] of Object.entries(bundle)) {
4307
- if (!isOutputChunk(chunk)) continue;
4308
- if (fileName.includes("__loadShare__") && fileName.includes("commonjs-proxy")) proxyChunks.set(fileName, {
4309
- code: chunk.code,
4310
- fileName
4311
- });
4312
- }
4313
- if (proxyChunks.size > 0) for (const [fileName, chunk] of Object.entries(bundle)) {
4314
- if (!isOutputChunk(chunk)) continue;
4315
- if (fileName.includes("__loadShare__")) continue;
4316
- let code = chunk.code;
4317
- let modified = false;
4318
- const claimedLocals = /* @__PURE__ */ new Set();
4319
- for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
4320
- const proxyBaseName = proxyFileName.replace(/^.*\//, "").replace(/\.js$/, "").replace(/-[A-Za-z0-9_-]+$/, "");
4321
- const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${proxyBaseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^"']*)["']\\s*;?`).exec(code);
4322
- if (!importMatch) continue;
4323
- const fullImport = importMatch[0];
4324
- const bindings = importMatch[1].split(",").map((s) => {
4325
- const parts = s.trim().split(/\s+as\s+/);
4326
- return {
4327
- imported: parts[0].trim(),
4328
- local: (parts[1] || parts[0]).trim()
4329
- };
4330
- });
4331
- const proxyCode = proxyInfo.code;
4332
- const exportMapMatch = proxyCode.match(/export\s*\{([^}]+)\}/);
4333
- if (!exportMapMatch) continue;
4334
- const exportMap = {};
4335
- for (const entry of exportMapMatch[1].split(",")) {
4336
- const parts = entry.trim().split(/\s+as\s+/);
4337
- if (parts.length === 2) exportMap[parts[1].trim()] = parts[0].trim();
4338
- }
4339
- const inlineable = [];
4340
- const nonInlineable = [];
4341
- const pendingLocals = new Set(bindings.map((binding) => binding.local));
4342
- for (const b of bindings) {
4343
- pendingLocals.delete(b.local);
4344
- const proxyLocal = exportMap[b.imported];
4345
- if (!proxyLocal) {
4346
- claimedLocals.add(b.local);
4347
- nonInlineable.push(b);
4348
- continue;
4349
- }
4350
- const funcRe = new RegExp(`function\\s+${proxyLocal}\\s*\\([^)]*\\)\\s*\\{`);
4351
- if (funcRe.test(proxyCode)) {
4352
- const funcStart = proxyCode.search(funcRe);
4353
- let depth = 0;
4354
- let funcEnd = funcStart;
4355
- for (let i = proxyCode.indexOf("{", funcStart); i < proxyCode.length; i++) if (proxyCode[i] === "{") depth++;
4356
- else if (proxyCode[i] === "}") {
4357
- depth--;
4358
- if (depth === 0) {
4359
- funcEnd = i + 1;
4360
- break;
4361
- }
4362
- }
4363
- const renamedFunc = proxyCode.slice(funcStart, funcEnd).replace(new RegExp(`function\\s+${proxyLocal}\\s*\\(`), `function ${b.local}(`);
4364
- inlineable.push({
4365
- local: b.local,
4366
- funcBody: renamedFunc
4367
- });
4368
- claimedLocals.add(b.local);
4369
- } else {
4370
- const unavailableLocals = new Set(claimedLocals);
4371
- pendingLocals.forEach((local) => unavailableLocals.add(local));
4372
- const resolvedBinding = resolveProxyAlias(b, proxyLocal, code, fullImport, unavailableLocals);
4373
- claimedLocals.add(resolvedBinding.local);
4374
- nonInlineable.push(resolvedBinding);
4375
- }
4376
- }
4377
- const hasRenamedAlias = nonInlineable.some((b) => bindings.find((ob) => ob.imported === b.imported)?.local !== b.local);
4378
- if (inlineable.length === 0 && !hasRenamedAlias) continue;
4379
- let replacement = "";
4380
- if (nonInlineable.length > 0) replacement = `import{${nonInlineable.map((b) => b.imported === b.local ? b.imported : `${b.imported} as ${b.local}`).join(",")}}from"${importMatch[2]}";`;
4381
- replacement += inlineable.map((f) => f.funcBody).join("");
4382
- code = code.replace(fullImport, () => replacement);
4383
- modified = true;
4748
+ const proxyChunks = collectLoadShareProxyChunks(bundle, LOAD_SHARE_TAG);
4749
+ if (proxyChunks.size > 0) {
4750
+ const systemProxyInfo = collectSystemProxyInfos(proxyChunks, LOAD_SHARE_TAG);
4751
+ for (const [fileName, chunk] of Object.entries(bundle)) {
4752
+ if (!isOutputChunk(chunk)) continue;
4753
+ if (proxyChunks.has(fileName)) continue;
4754
+ let code = chunk.code;
4755
+ if (!fileName.includes("__loadShare__")) code = rewriteEsmProxyConsumers(code, proxyChunks);
4756
+ code = rewriteSystemProxyConsumers(code, systemProxyInfo);
4757
+ if (code !== chunk.code) chunk.code = code;
4384
4758
  }
4385
- if (modified) chunk.code = code;
4386
4759
  }
4387
4760
  }
4388
4761
  },
@@ -4420,24 +4793,19 @@ function federation(mfUserOptions) {
4420
4793
  find: "@module-federation/runtime",
4421
4794
  replacement: implementation
4422
4795
  });
4423
- config.build = (0, defu.default)(config.build || {}, { commonjsOptions: { strictRequires: "auto" } });
4424
- const virtualDir = options.virtualModuleDir;
4796
+ config.build ||= {};
4797
+ config.build.commonjsOptions ||= {};
4798
+ config.build.commonjsOptions.strictRequires ??= "auto";
4425
4799
  config.optimizeDeps ||= {};
4426
4800
  config.optimizeDeps.include ||= [];
4427
4801
  config.optimizeDeps.include.push("@module-federation/runtime");
4428
- config.optimizeDeps.include.push(virtualDir);
4429
- config.ssr ||= {};
4430
- config.ssr.noExternal ||= [];
4431
- if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
4432
4802
  options.runtimePlugins.forEach((p) => {
4433
4803
  const pluginPath = typeof p === "string" ? p : p[0];
4434
4804
  if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
4435
4805
  });
4436
- if (isRolldown) config.build = (0, defu.default)(config.build || {}, { target: "esnext" });
4437
- else {
4438
- config.optimizeDeps.needsInterop ||= [];
4439
- config.optimizeDeps.needsInterop.push(virtualDir);
4440
- config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
4806
+ if (isRolldown) {
4807
+ config.build ??= {};
4808
+ config.build.target ??= "esnext";
4441
4809
  }
4442
4810
  const isAstro = hasPackageDependency("astro");
4443
4811
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");