@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 +726 -358
- package/lib/index.d.cts +13 -1
- package/lib/index.d.mts +13 -1
- package/lib/index.mjs +730 -360
- package/package.json +7 -8
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:
|
|
46
|
-
map:
|
|
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
|
|
632
|
-
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()}`;
|
|
633
705
|
}
|
|
634
706
|
writeSync(code, force) {
|
|
635
707
|
if (!force && this.inited) return;
|
|
636
708
|
if (!this.inited) this.inited = true;
|
|
637
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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].
|
|
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 =
|
|
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 =
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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(() =>
|
|
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,
|
|
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
|
|
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
|
-
|
|
1774
|
-
|
|
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:
|
|
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("/.
|
|
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
|
|
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()).
|
|
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 (!
|
|
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 =
|
|
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.
|
|
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
|
|
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 (!
|
|
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
|
|
3712
|
+
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
3286
3713
|
},
|
|
3287
|
-
|
|
3288
|
-
if (
|
|
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
|
|
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(
|
|
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
|
|
3954
|
-
* This prevents 504 "Outdated Optimize Dep" errors by ensuring
|
|
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
|
|
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 (
|
|
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
|
-
|
|
4075
|
-
|
|
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(
|
|
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 (
|
|
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 =
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
fileName
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
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
|
|
4424
|
-
|
|
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)
|
|
4437
|
-
|
|
4438
|
-
config.
|
|
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");
|