@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.mjs
CHANGED
|
@@ -1,28 +1,151 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import defu from "defu";
|
|
3
2
|
import * as fs$1 from "fs";
|
|
4
|
-
import fs, { existsSync,
|
|
3
|
+
import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
5
4
|
import { createRequire as createRequire$1 } from "module";
|
|
6
5
|
import * as path$1 from "pathe";
|
|
7
|
-
import path, { basename
|
|
8
|
-
import MagicString from "magic-string";
|
|
6
|
+
import path, { basename } from "pathe";
|
|
9
7
|
import { normalizeOptions } from "@module-federation/sdk";
|
|
10
8
|
import { consumeTypesAPI, generateTypesAPI, isTSProject, normalizeConsumeTypesOptions, normalizeDtsOptions, normalizeGenerateTypesOptions } from "@module-federation/dts-plugin";
|
|
11
9
|
import { rpc } from "@module-federation/dts-plugin/core";
|
|
12
|
-
import { createFilter } from "@rollup/pluginutils";
|
|
13
10
|
import { fileURLToPath } from "url";
|
|
14
|
-
import { init, parse
|
|
11
|
+
import { init, parse } from "es-module-lexer";
|
|
15
12
|
//#region \0rolldown/runtime.js
|
|
16
13
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
17
14
|
//#endregion
|
|
15
|
+
//#region src/utils/codeRewriter.ts
|
|
16
|
+
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
17
|
+
var CodeRewriter = class {
|
|
18
|
+
replacements = [];
|
|
19
|
+
constructor(original) {
|
|
20
|
+
this.original = original;
|
|
21
|
+
}
|
|
22
|
+
overwrite(start, end, content) {
|
|
23
|
+
if (start < 0 || end < start || end > this.original.length) throw new Error(`Invalid overwrite range: ${start}-${end}`);
|
|
24
|
+
this.replacements.push({
|
|
25
|
+
start,
|
|
26
|
+
end,
|
|
27
|
+
content
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
toString() {
|
|
31
|
+
return applyReplacements(this.original, this.getSortedReplacements()).code;
|
|
32
|
+
}
|
|
33
|
+
generateMap(source = "") {
|
|
34
|
+
const { code, replacements } = applyReplacements(this.original, this.getSortedReplacements());
|
|
35
|
+
return {
|
|
36
|
+
version: 3,
|
|
37
|
+
sources: [source],
|
|
38
|
+
sourcesContent: [this.original],
|
|
39
|
+
names: [],
|
|
40
|
+
mappings: generateLineMappings(code, this.original, replacements)
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
getSortedReplacements() {
|
|
44
|
+
return [...this.replacements].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
function createSourceMap(code, source = "") {
|
|
48
|
+
return {
|
|
49
|
+
version: 3,
|
|
50
|
+
sources: [source],
|
|
51
|
+
sourcesContent: [code],
|
|
52
|
+
names: [],
|
|
53
|
+
mappings: generateLineMappings(code, code, [])
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function applyReplacements(original, replacements) {
|
|
57
|
+
let code = "";
|
|
58
|
+
let cursor = 0;
|
|
59
|
+
let delta = 0;
|
|
60
|
+
const applied = [];
|
|
61
|
+
for (const replacement of replacements) {
|
|
62
|
+
if (replacement.start < cursor) throw new Error("Overlapping overwrite ranges are not supported");
|
|
63
|
+
code += original.slice(cursor, replacement.start);
|
|
64
|
+
const generatedStart = replacement.start + delta;
|
|
65
|
+
code += replacement.content;
|
|
66
|
+
const generatedEnd = generatedStart + replacement.content.length;
|
|
67
|
+
applied.push({
|
|
68
|
+
...replacement,
|
|
69
|
+
generatedStart,
|
|
70
|
+
generatedEnd
|
|
71
|
+
});
|
|
72
|
+
cursor = replacement.end;
|
|
73
|
+
delta += replacement.content.length - (replacement.end - replacement.start);
|
|
74
|
+
}
|
|
75
|
+
code += original.slice(cursor);
|
|
76
|
+
return {
|
|
77
|
+
code,
|
|
78
|
+
replacements: applied
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function generateLineMappings(generated, original, replacements) {
|
|
82
|
+
const generatedLineStarts = getLineStarts(generated);
|
|
83
|
+
const originalLineStarts = getLineStarts(original);
|
|
84
|
+
let previousOriginalLine = 0;
|
|
85
|
+
let previousOriginalColumn = 0;
|
|
86
|
+
let mappings = "";
|
|
87
|
+
generatedLineStarts.forEach((generatedOffset, lineIndex) => {
|
|
88
|
+
if (lineIndex > 0) mappings += ";";
|
|
89
|
+
const originalOffset = generatedOffsetToOriginalOffset(generatedOffset, replacements);
|
|
90
|
+
const originalLine = findLine(originalLineStarts, originalOffset);
|
|
91
|
+
const originalColumn = originalOffset - originalLineStarts[originalLine];
|
|
92
|
+
mappings += encodeSegment([
|
|
93
|
+
0,
|
|
94
|
+
0,
|
|
95
|
+
originalLine - previousOriginalLine,
|
|
96
|
+
originalColumn - previousOriginalColumn
|
|
97
|
+
]);
|
|
98
|
+
previousOriginalLine = originalLine;
|
|
99
|
+
previousOriginalColumn = originalColumn;
|
|
100
|
+
});
|
|
101
|
+
return mappings;
|
|
102
|
+
}
|
|
103
|
+
function generatedOffsetToOriginalOffset(offset, replacements) {
|
|
104
|
+
let delta = 0;
|
|
105
|
+
for (const replacement of replacements) {
|
|
106
|
+
if (offset < replacement.generatedStart) break;
|
|
107
|
+
if (offset < replacement.generatedEnd) return replacement.start;
|
|
108
|
+
delta += replacement.content.length - (replacement.end - replacement.start);
|
|
109
|
+
}
|
|
110
|
+
return offset - delta;
|
|
111
|
+
}
|
|
112
|
+
function getLineStarts(code) {
|
|
113
|
+
const starts = [0];
|
|
114
|
+
for (let i = 0; i < code.length; i++) if (code.charCodeAt(i) === 10) starts.push(i + 1);
|
|
115
|
+
return starts;
|
|
116
|
+
}
|
|
117
|
+
function findLine(lineStarts, offset) {
|
|
118
|
+
let low = 0;
|
|
119
|
+
let high = lineStarts.length - 1;
|
|
120
|
+
while (low <= high) {
|
|
121
|
+
const mid = low + high >> 1;
|
|
122
|
+
if (lineStarts[mid] <= offset) low = mid + 1;
|
|
123
|
+
else high = mid - 1;
|
|
124
|
+
}
|
|
125
|
+
return Math.max(0, high);
|
|
126
|
+
}
|
|
127
|
+
function encodeSegment(values) {
|
|
128
|
+
return values.map(encodeVlq).join("");
|
|
129
|
+
}
|
|
130
|
+
function encodeVlq(value) {
|
|
131
|
+
let vlq = value < 0 ? (-value << 1) + 1 : value << 1;
|
|
132
|
+
let encoded = "";
|
|
133
|
+
do {
|
|
134
|
+
let digit = vlq & 31;
|
|
135
|
+
vlq >>>= 5;
|
|
136
|
+
if (vlq > 0) digit |= 32;
|
|
137
|
+
encoded += BASE64_CHARS[digit];
|
|
138
|
+
} while (vlq > 0);
|
|
139
|
+
return encoded;
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
18
142
|
//#region src/utils/mapCodeToCodeWithSourcemap.ts
|
|
19
143
|
async function mapCodeToCodeWithSourcemap(code) {
|
|
20
144
|
const resolvedCode = await code;
|
|
21
145
|
if (resolvedCode === void 0) return;
|
|
22
|
-
const s = new MagicString(resolvedCode);
|
|
23
146
|
return {
|
|
24
|
-
code:
|
|
25
|
-
map:
|
|
147
|
+
code: resolvedCode,
|
|
148
|
+
map: createSourceMap(resolvedCode)
|
|
26
149
|
};
|
|
27
150
|
}
|
|
28
151
|
//#endregion
|
|
@@ -401,7 +524,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
401
524
|
shareConfig: {
|
|
402
525
|
import: shareItem.import,
|
|
403
526
|
singleton: shareItem.singleton || false,
|
|
404
|
-
requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
|
|
527
|
+
requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
|
|
405
528
|
strictVersion: !!shareItem.strictVersion
|
|
406
529
|
}
|
|
407
530
|
};
|
|
@@ -518,35 +641,6 @@ function normalizeModuleFederationOptions(options) {
|
|
|
518
641
|
}
|
|
519
642
|
//#endregion
|
|
520
643
|
//#region src/utils/VirtualModule.ts
|
|
521
|
-
/**
|
|
522
|
-
* Initialize virtual module infrastructure BEFORE VirtualModule class is used.
|
|
523
|
-
* This must be called in the config hook to ensure the directory exists
|
|
524
|
-
* before Vite's optimization phase.
|
|
525
|
-
*/
|
|
526
|
-
function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
|
|
527
|
-
const virtualPackagePath = join(join(root, "node_modules"), virtualModuleDir);
|
|
528
|
-
mkdirSync(virtualPackagePath, { recursive: true });
|
|
529
|
-
writeFileSync(join(virtualPackagePath, "empty.js"), "");
|
|
530
|
-
writeFileSync(join(virtualPackagePath, "package.json"), JSON.stringify({
|
|
531
|
-
name: virtualModuleDir,
|
|
532
|
-
main: "empty.js"
|
|
533
|
-
}));
|
|
534
|
-
}
|
|
535
|
-
let rootDir;
|
|
536
|
-
function findNodeModulesDir(root = process.cwd()) {
|
|
537
|
-
let currentDir = root;
|
|
538
|
-
while (currentDir !== parse(currentDir).root) {
|
|
539
|
-
const nodeModulesPath = join(currentDir, "node_modules");
|
|
540
|
-
if (existsSync(nodeModulesPath)) return nodeModulesPath;
|
|
541
|
-
currentDir = dirname(currentDir);
|
|
542
|
-
}
|
|
543
|
-
return "";
|
|
544
|
-
}
|
|
545
|
-
let cachedNodeModulesDir;
|
|
546
|
-
function getNodeModulesDir() {
|
|
547
|
-
if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
|
|
548
|
-
return cachedNodeModulesDir;
|
|
549
|
-
}
|
|
550
644
|
function getSuffix(name) {
|
|
551
645
|
const base = basename(name);
|
|
552
646
|
const dotIndex = base.lastIndexOf(".");
|
|
@@ -555,9 +649,6 @@ function getSuffix(name) {
|
|
|
555
649
|
}
|
|
556
650
|
const patternMap = {};
|
|
557
651
|
const cacheMap = {};
|
|
558
|
-
/**
|
|
559
|
-
* Physically generate files as virtual modules under node_modules/__mf__virtual/*
|
|
560
|
-
*/
|
|
561
652
|
function assertModuleFound(tag, str = "") {
|
|
562
653
|
const module = VirtualModule.findModule(tag, str);
|
|
563
654
|
if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
|
|
@@ -568,33 +659,16 @@ var VirtualModule = class {
|
|
|
568
659
|
tag;
|
|
569
660
|
suffix;
|
|
570
661
|
inited = false;
|
|
571
|
-
|
|
572
|
-
* Set the root path for finding node_modules
|
|
573
|
-
* @param root - Root path
|
|
574
|
-
*/
|
|
575
|
-
static setRoot(root) {
|
|
576
|
-
rootDir = root;
|
|
577
|
-
cachedNodeModulesDir = void 0;
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Ensure virtual package directory exists
|
|
581
|
-
*/
|
|
582
|
-
static ensureVirtualPackageExists() {
|
|
583
|
-
const nodeModulesDir = getNodeModulesDir();
|
|
584
|
-
const { virtualModuleDir } = getNormalizeModuleFederationOptions();
|
|
585
|
-
const virtualPackagePath = resolve(nodeModulesDir, virtualModuleDir);
|
|
586
|
-
mkdirSync(virtualPackagePath, { recursive: true });
|
|
587
|
-
writeFileSync(resolve(virtualPackagePath, "empty.js"), "");
|
|
588
|
-
writeFileSync(resolve(virtualPackagePath, "package.json"), JSON.stringify({
|
|
589
|
-
name: virtualModuleDir,
|
|
590
|
-
main: "empty.js"
|
|
591
|
-
}));
|
|
592
|
-
}
|
|
662
|
+
code;
|
|
593
663
|
static findModule(tag, str = "") {
|
|
594
664
|
if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
|
|
595
665
|
const moduleName = (str.match(patternMap[tag]) || [])[2];
|
|
596
666
|
if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
|
|
597
667
|
}
|
|
668
|
+
static findById(id) {
|
|
669
|
+
const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
|
|
670
|
+
for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
|
|
671
|
+
}
|
|
598
672
|
constructor(name, tag = "__mf_v__", suffix = "") {
|
|
599
673
|
this.name = name;
|
|
600
674
|
this.tag = tag;
|
|
@@ -602,128 +676,23 @@ var VirtualModule = class {
|
|
|
602
676
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
603
677
|
cacheMap[this.tag][this.name] = this;
|
|
604
678
|
}
|
|
605
|
-
getPath() {
|
|
606
|
-
return resolve(getNodeModulesDir(), this.getImportId());
|
|
607
|
-
}
|
|
608
679
|
getImportId() {
|
|
609
|
-
const { internalName: mfName
|
|
610
|
-
return
|
|
680
|
+
const { internalName: mfName } = getNormalizeModuleFederationOptions();
|
|
681
|
+
return `virtual:mf:${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
|
|
682
|
+
}
|
|
683
|
+
getResolvedId() {
|
|
684
|
+
return `\0${this.getImportId()}`;
|
|
611
685
|
}
|
|
612
686
|
writeSync(code, force) {
|
|
613
687
|
if (!force && this.inited) return;
|
|
614
688
|
if (!this.inited) this.inited = true;
|
|
615
|
-
|
|
616
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
617
|
-
writeFileSync(path, code);
|
|
689
|
+
this.code = code;
|
|
618
690
|
}
|
|
619
691
|
write(code) {
|
|
620
|
-
|
|
621
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
622
|
-
writeFile(path, code, function() {});
|
|
692
|
+
this.writeSync(code, true);
|
|
623
693
|
}
|
|
624
694
|
};
|
|
625
695
|
//#endregion
|
|
626
|
-
//#region src/virtualModules/virtualRuntimeInitStatus.ts
|
|
627
|
-
const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
|
|
628
|
-
const MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache__";
|
|
629
|
-
function getRuntimeInitGlobalKey() {
|
|
630
|
-
return `__mf_init__${virtualRuntimeInitStatus.getImportId()}__`;
|
|
631
|
-
}
|
|
632
|
-
function getDeferredInitPromiseCode() {
|
|
633
|
-
return `let initResolve, initReject;
|
|
634
|
-
const initPromise = new Promise((re, rj) => {
|
|
635
|
-
initResolve = re;
|
|
636
|
-
initReject = rj;
|
|
637
|
-
});`;
|
|
638
|
-
}
|
|
639
|
-
function getSsrNoopResolveCode() {
|
|
640
|
-
return `if (typeof window === 'undefined') {
|
|
641
|
-
initResolve({
|
|
642
|
-
loadRemote: function() { return Promise.resolve(undefined); },
|
|
643
|
-
loadShare: function() { return Promise.resolve(undefined); },
|
|
644
|
-
});
|
|
645
|
-
}`;
|
|
646
|
-
}
|
|
647
|
-
function getRuntimeInitStateBootstrapCode(options) {
|
|
648
|
-
return `
|
|
649
|
-
const ${options.globalKeyVar} = ${JSON.stringify(getRuntimeInitGlobalKey())};
|
|
650
|
-
let ${options.stateVar} = globalThis[${options.globalKeyVar}];
|
|
651
|
-
if (!${options.stateVar}) {
|
|
652
|
-
${getDeferredInitPromiseCode()}
|
|
653
|
-
${options.stateVar} = globalThis[${options.globalKeyVar}] = {
|
|
654
|
-
initPromise,
|
|
655
|
-
initResolve,
|
|
656
|
-
initReject,
|
|
657
|
-
};
|
|
658
|
-
${getSsrNoopResolveCode()}
|
|
659
|
-
}
|
|
660
|
-
const ${options.exposedConst} = ${options.stateVar}.${options.exposedProperty};
|
|
661
|
-
`;
|
|
662
|
-
}
|
|
663
|
-
function getRuntimeInitBootstrapCode() {
|
|
664
|
-
return `
|
|
665
|
-
const globalKey = ${JSON.stringify(getRuntimeInitGlobalKey())};
|
|
666
|
-
const moduleCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
|
|
667
|
-
globalThis[moduleCacheGlobalKey] ||= { share: {}, remote: {} };
|
|
668
|
-
globalThis[moduleCacheGlobalKey].share ||= {};
|
|
669
|
-
globalThis[moduleCacheGlobalKey].remote ||= {};
|
|
670
|
-
if (!globalThis[globalKey]) {
|
|
671
|
-
${getDeferredInitPromiseCode()}
|
|
672
|
-
globalThis[globalKey] = {
|
|
673
|
-
initPromise,
|
|
674
|
-
initResolve,
|
|
675
|
-
initReject,
|
|
676
|
-
moduleCache: globalThis[moduleCacheGlobalKey],
|
|
677
|
-
};
|
|
678
|
-
${getSsrNoopResolveCode()}
|
|
679
|
-
}
|
|
680
|
-
globalThis[globalKey].moduleCache ||= globalThis[moduleCacheGlobalKey];
|
|
681
|
-
globalThis[globalKey].moduleCache.share ||= {};
|
|
682
|
-
globalThis[globalKey].moduleCache.remote ||= {};
|
|
683
|
-
`;
|
|
684
|
-
}
|
|
685
|
-
function getRuntimeModuleCacheBootstrapCode() {
|
|
686
|
-
return `
|
|
687
|
-
const __mfCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
|
|
688
|
-
globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
|
|
689
|
-
globalThis[__mfCacheGlobalKey].share ||= {};
|
|
690
|
-
globalThis[__mfCacheGlobalKey].remote ||= {};
|
|
691
|
-
const __mfModuleCache = globalThis[__mfCacheGlobalKey];
|
|
692
|
-
`;
|
|
693
|
-
}
|
|
694
|
-
function getRuntimeInitResolveBootstrapCode() {
|
|
695
|
-
return getRuntimeInitStateBootstrapCode({
|
|
696
|
-
globalKeyVar: "__mfResolveGlobalKey",
|
|
697
|
-
stateVar: "__mfResolveState",
|
|
698
|
-
exposedConst: "initResolve",
|
|
699
|
-
exposedProperty: "initResolve"
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
function writeRuntimeInitStatus(command) {
|
|
703
|
-
const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
|
|
704
|
-
export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
|
|
705
|
-
virtualRuntimeInitStatus.writeSync(`
|
|
706
|
-
${getRuntimeInitBootstrapCode()}
|
|
707
|
-
${exportStatement}
|
|
708
|
-
`);
|
|
709
|
-
}
|
|
710
|
-
//#endregion
|
|
711
|
-
//#region src/utils/localSharedImportMap_temp.ts
|
|
712
|
-
/**
|
|
713
|
-
* https://github.com/module-federation/vite/issues/68
|
|
714
|
-
*/
|
|
715
|
-
function getLocalSharedImportMapPath_temp() {
|
|
716
|
-
const { name } = getNormalizeModuleFederationOptions();
|
|
717
|
-
return path.resolve(".__mf__temp", packageNameEncode(name), "localSharedImportMap");
|
|
718
|
-
}
|
|
719
|
-
function writeLocalSharedImportMap_temp(content) {
|
|
720
|
-
createFile(getLocalSharedImportMapPath_temp() + ".js", "\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n" + content);
|
|
721
|
-
}
|
|
722
|
-
function createFile(filePath, content) {
|
|
723
|
-
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
724
|
-
writeFileSync(filePath, content);
|
|
725
|
-
}
|
|
726
|
-
//#endregion
|
|
727
696
|
//#region src/utils/serializeRuntimeOptions.ts
|
|
728
697
|
/**
|
|
729
698
|
* Serializes a JavaScript object into a string of source code that can be evaluated.
|
|
@@ -854,6 +823,99 @@ function generateExposes(options) {
|
|
|
854
823
|
`;
|
|
855
824
|
}
|
|
856
825
|
//#endregion
|
|
826
|
+
//#region src/virtualModules/virtualRuntimeInitStatus.ts
|
|
827
|
+
const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
|
|
828
|
+
const MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache__";
|
|
829
|
+
function getRuntimeInitGlobalKey() {
|
|
830
|
+
return `__mf_init__${virtualRuntimeInitStatus.getImportId()}__`;
|
|
831
|
+
}
|
|
832
|
+
function getDeferredInitPromiseCode() {
|
|
833
|
+
return `let initResolve, initReject;
|
|
834
|
+
const initPromise = new Promise((re, rj) => {
|
|
835
|
+
initResolve = re;
|
|
836
|
+
initReject = rj;
|
|
837
|
+
});`;
|
|
838
|
+
}
|
|
839
|
+
function getSsrNoopResolveCode() {
|
|
840
|
+
return `if (typeof window === 'undefined') {
|
|
841
|
+
initResolve({
|
|
842
|
+
loadRemote: function() { return Promise.resolve(undefined); },
|
|
843
|
+
loadShare: function() { return Promise.resolve(undefined); },
|
|
844
|
+
});
|
|
845
|
+
}`;
|
|
846
|
+
}
|
|
847
|
+
function getRuntimeInitStateBootstrapCode(options) {
|
|
848
|
+
return `
|
|
849
|
+
const ${options.globalKeyVar} = ${JSON.stringify(getRuntimeInitGlobalKey())};
|
|
850
|
+
let ${options.stateVar} = globalThis[${options.globalKeyVar}];
|
|
851
|
+
if (!${options.stateVar}) {
|
|
852
|
+
${getDeferredInitPromiseCode()}
|
|
853
|
+
${options.stateVar} = globalThis[${options.globalKeyVar}] = {
|
|
854
|
+
initPromise,
|
|
855
|
+
initResolve,
|
|
856
|
+
initReject,
|
|
857
|
+
};
|
|
858
|
+
${getSsrNoopResolveCode()}
|
|
859
|
+
}
|
|
860
|
+
const ${options.exposedConst} = ${options.stateVar}.${options.exposedProperty};
|
|
861
|
+
`;
|
|
862
|
+
}
|
|
863
|
+
function getRuntimeInitBootstrapCode() {
|
|
864
|
+
return `
|
|
865
|
+
const globalKey = ${JSON.stringify(getRuntimeInitGlobalKey())};
|
|
866
|
+
const moduleCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
|
|
867
|
+
globalThis[moduleCacheGlobalKey] ||= { share: {}, remote: {} };
|
|
868
|
+
globalThis[moduleCacheGlobalKey].share ||= {};
|
|
869
|
+
globalThis[moduleCacheGlobalKey].remote ||= {};
|
|
870
|
+
if (!globalThis[globalKey]) {
|
|
871
|
+
${getDeferredInitPromiseCode()}
|
|
872
|
+
globalThis[globalKey] = {
|
|
873
|
+
initPromise,
|
|
874
|
+
initResolve,
|
|
875
|
+
initReject,
|
|
876
|
+
moduleCache: globalThis[moduleCacheGlobalKey],
|
|
877
|
+
};
|
|
878
|
+
${getSsrNoopResolveCode()}
|
|
879
|
+
}
|
|
880
|
+
globalThis[globalKey].moduleCache ||= globalThis[moduleCacheGlobalKey];
|
|
881
|
+
globalThis[globalKey].moduleCache.share ||= {};
|
|
882
|
+
globalThis[globalKey].moduleCache.remote ||= {};
|
|
883
|
+
`;
|
|
884
|
+
}
|
|
885
|
+
function getRuntimeModuleCacheBootstrapCode() {
|
|
886
|
+
return `
|
|
887
|
+
const __mfCacheGlobalKey = ${JSON.stringify(MODULE_CACHE_GLOBAL_KEY)};
|
|
888
|
+
globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
|
|
889
|
+
globalThis[__mfCacheGlobalKey].share ||= {};
|
|
890
|
+
globalThis[__mfCacheGlobalKey].remote ||= {};
|
|
891
|
+
const __mfModuleCache = globalThis[__mfCacheGlobalKey];
|
|
892
|
+
`;
|
|
893
|
+
}
|
|
894
|
+
function getRuntimeInitPromiseBootstrapCode() {
|
|
895
|
+
return getRuntimeInitStateBootstrapCode({
|
|
896
|
+
globalKeyVar: "__mfPromiseGlobalKey",
|
|
897
|
+
stateVar: "__mfPromiseState",
|
|
898
|
+
exposedConst: "initPromise",
|
|
899
|
+
exposedProperty: "initPromise"
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
function getRuntimeInitResolveBootstrapCode() {
|
|
903
|
+
return getRuntimeInitStateBootstrapCode({
|
|
904
|
+
globalKeyVar: "__mfResolveGlobalKey",
|
|
905
|
+
stateVar: "__mfResolveState",
|
|
906
|
+
exposedConst: "initResolve",
|
|
907
|
+
exposedProperty: "initResolve"
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
function writeRuntimeInitStatus(command) {
|
|
911
|
+
const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
|
|
912
|
+
export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
|
|
913
|
+
virtualRuntimeInitStatus.writeSync(`
|
|
914
|
+
${getRuntimeInitBootstrapCode()}
|
|
915
|
+
${exportStatement}
|
|
916
|
+
`);
|
|
917
|
+
}
|
|
918
|
+
//#endregion
|
|
857
919
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
858
920
|
/**
|
|
859
921
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -996,7 +1058,16 @@ function getLocalProviderImportPath(pkg) {
|
|
|
996
1058
|
const resolved = createRequire$1(new URL(`file://${path.join(getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
|
|
997
1059
|
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
998
1060
|
} catch {
|
|
999
|
-
|
|
1061
|
+
const resolved = getInstalledPackageEntry(pkg, {
|
|
1062
|
+
conditions: [
|
|
1063
|
+
"browser",
|
|
1064
|
+
"import",
|
|
1065
|
+
"module",
|
|
1066
|
+
"default"
|
|
1067
|
+
],
|
|
1068
|
+
resolveSubpathWithRequire: false
|
|
1069
|
+
});
|
|
1070
|
+
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
1000
1071
|
}
|
|
1001
1072
|
}
|
|
1002
1073
|
function getProjectResolvedImportPath(pkg) {
|
|
@@ -1011,7 +1082,12 @@ function getProjectResolvedImportPath(pkg) {
|
|
|
1011
1082
|
}
|
|
1012
1083
|
}
|
|
1013
1084
|
function isWorkspaceFilePath(resolved) {
|
|
1014
|
-
|
|
1085
|
+
if (!resolved) return false;
|
|
1086
|
+
let realResolved = resolved;
|
|
1087
|
+
try {
|
|
1088
|
+
realResolved = realpathSync.native(resolved);
|
|
1089
|
+
} catch {}
|
|
1090
|
+
return !realResolved.includes("/node_modules/") && !realResolved.includes("\\node_modules\\");
|
|
1015
1091
|
}
|
|
1016
1092
|
function isWorkspacePackageEntry(pkg, resolved) {
|
|
1017
1093
|
if (!resolved || !path.isAbsolute(resolved) || !isWorkspaceFilePath(resolved)) return false;
|
|
@@ -1067,6 +1143,16 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1067
1143
|
export const jsx = __mfPrebuildExports.jsx;
|
|
1068
1144
|
export const jsxs = __mfPrebuildExports.jsxs;
|
|
1069
1145
|
export default __mfPrebuildExports;
|
|
1146
|
+
`, true);
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
const namedExports = getPackageNamedExports(pkg);
|
|
1150
|
+
if (namedExports.length > 0) {
|
|
1151
|
+
preBuildCacheMap[pkg].writeSync(`
|
|
1152
|
+
import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
|
|
1153
|
+
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1154
|
+
${namedExports.map((name) => `export const ${name} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}
|
|
1155
|
+
export default __mfPrebuildExports;
|
|
1070
1156
|
`, true);
|
|
1071
1157
|
return;
|
|
1072
1158
|
}
|
|
@@ -1094,25 +1180,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
|
|
|
1094
1180
|
}
|
|
1095
1181
|
function getLoadShareModulePath(pkg, isRolldown) {
|
|
1096
1182
|
if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
|
|
1097
|
-
return loadShareCacheMap[pkg].
|
|
1183
|
+
return loadShareCacheMap[pkg].getImportId();
|
|
1098
1184
|
}
|
|
1185
|
+
function generateDeferredHostProvidedExports(namedExports, pkg) {
|
|
1186
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1187
|
+
const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
|
|
1188
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
1189
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1190
|
+
return `${declarations}
|
|
1191
|
+
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1192
|
+
${assignments}
|
|
1193
|
+
};
|
|
1194
|
+
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1195
|
+
if (exportModule === undefined) {
|
|
1196
|
+
initPromise.then(() => {
|
|
1197
|
+
exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
|
|
1198
|
+
if (exportModule === undefined) {
|
|
1199
|
+
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1200
|
+
}
|
|
1201
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1202
|
+
});
|
|
1203
|
+
} else {
|
|
1204
|
+
__mfApplyHostProvidedExports(exportModule);
|
|
1205
|
+
}
|
|
1206
|
+
export { __mf_default as default };${namedExportLine}`;
|
|
1207
|
+
}
|
|
1208
|
+
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1209
|
+
return `let current = ${source};
|
|
1210
|
+
for (let i = 0; i < 5; i++) {
|
|
1211
|
+
const defaultExport = current?.default;
|
|
1212
|
+
${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
|
|
1213
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1214
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
|
|
1215
|
+
current = defaultExport;
|
|
1216
|
+
}
|
|
1217
|
+
return current;`;
|
|
1218
|
+
}
|
|
1219
|
+
const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
|
|
1220
|
+
${generateShareModuleUnwrapCode({
|
|
1221
|
+
source: "mod",
|
|
1222
|
+
preserveNamedExports: true
|
|
1223
|
+
})}
|
|
1224
|
+
};`;
|
|
1099
1225
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
1100
1226
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
|
|
1101
1227
|
const importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1102
1228
|
if (shareItem.shareConfig.import === false) {
|
|
1103
1229
|
const namedExports = getPackageNamedExports(pkg);
|
|
1104
1230
|
let exportLine;
|
|
1105
|
-
if (namedExports.length > 0) exportLine =
|
|
1231
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
|
|
1106
1232
|
else {
|
|
1107
1233
|
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.`);
|
|
1108
|
-
exportLine =
|
|
1234
|
+
exportLine = generateDeferredHostProvidedExports([], pkg);
|
|
1109
1235
|
}
|
|
1110
1236
|
loadShareCacheMap[pkg].writeSync(`
|
|
1237
|
+
${getRuntimeInitPromiseBootstrapCode()}
|
|
1111
1238
|
${importLine}
|
|
1112
|
-
const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1113
|
-
if (exportModule === undefined) {
|
|
1114
|
-
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
|
|
1115
|
-
}
|
|
1116
1239
|
${exportLine}
|
|
1117
1240
|
`, true);
|
|
1118
1241
|
return;
|
|
@@ -1124,21 +1247,35 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1124
1247
|
const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
|
|
1125
1248
|
const lazyLocalFallbackSource = concreteSharedImportSource || localProviderPath || sharedImportSource;
|
|
1126
1249
|
const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
|
|
1250
|
+
const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
1127
1251
|
const namedExports = getPackageNamedExports(pkg);
|
|
1128
1252
|
let exportLine;
|
|
1129
|
-
if (namedExports.length > 0)
|
|
1253
|
+
if (namedExports.length > 0) {
|
|
1254
|
+
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1255
|
+
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
1256
|
+
exportLine = `const __mfDefaultExport = (() => {
|
|
1257
|
+
${generateShareModuleUnwrapCode({
|
|
1258
|
+
source: "exportModule",
|
|
1259
|
+
preserveNamedExports: false,
|
|
1260
|
+
stopWithReturn: "defaultExport ?? current"
|
|
1261
|
+
})}
|
|
1262
|
+
})();
|
|
1263
|
+
export default __mfDefaultExport;
|
|
1264
|
+
${destructure}
|
|
1265
|
+
${namedExportLine}`;
|
|
1266
|
+
} else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
|
|
1130
1267
|
else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
1131
|
-
const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
1132
1268
|
const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1133
1269
|
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1134
1270
|
loadShareCacheMap[pkg].writeSync(`
|
|
1135
1271
|
${prebuildImportLine}
|
|
1136
1272
|
${devDynamicImportLine}
|
|
1137
1273
|
${importLine}
|
|
1274
|
+
${normalizeLocalShareModuleCode}
|
|
1138
1275
|
let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
|
|
1139
1276
|
if (exportModule === undefined) {
|
|
1140
|
-
${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
|
|
1141
|
-
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
|
|
1277
|
+
${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
|
|
1278
|
+
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1142
1279
|
__mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
|
|
1143
1280
|
}
|
|
1144
1281
|
${exportLine}
|
|
@@ -1153,15 +1290,24 @@ function getUsedShares() {
|
|
|
1153
1290
|
function addUsedShares(pkg) {
|
|
1154
1291
|
usedShares.add(pkg);
|
|
1155
1292
|
}
|
|
1293
|
+
const LOCAL_SHARED_IMPORT_MAP_ID = "virtual:mf-localSharedImportMap";
|
|
1156
1294
|
function getLocalSharedImportMapPath() {
|
|
1157
|
-
|
|
1295
|
+
const { internalName, name } = getNormalizeModuleFederationOptions();
|
|
1296
|
+
return `${LOCAL_SHARED_IMPORT_MAP_ID}:${packageNameEncode(internalName || name)}`;
|
|
1297
|
+
}
|
|
1298
|
+
function getResolvedLocalSharedImportMapId() {
|
|
1299
|
+
return `\0${getLocalSharedImportMapPath()}`;
|
|
1300
|
+
}
|
|
1301
|
+
let invalidateLocalSharedImportMap;
|
|
1302
|
+
function setLocalSharedImportMapInvalidator(invalidator) {
|
|
1303
|
+
invalidateLocalSharedImportMap = invalidator;
|
|
1158
1304
|
}
|
|
1159
1305
|
let prevLocalSharedImportMapContent;
|
|
1160
1306
|
function writeLocalSharedImportMap() {
|
|
1161
1307
|
const nextContent = generateLocalSharedImportMap();
|
|
1162
1308
|
if (prevLocalSharedImportMapContent !== nextContent) {
|
|
1163
1309
|
prevLocalSharedImportMapContent = nextContent;
|
|
1164
|
-
|
|
1310
|
+
invalidateLocalSharedImportMap?.();
|
|
1165
1311
|
}
|
|
1166
1312
|
}
|
|
1167
1313
|
function shouldUseDirectReactImport() {
|
|
@@ -1287,9 +1433,9 @@ function getShareItemForPreload(pkg) {
|
|
|
1287
1433
|
function generateSharedCacheSeedItem(pkg, importPath) {
|
|
1288
1434
|
return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
|
|
1289
1435
|
const mod = await import(${JSON.stringify(importPath)});
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1436
|
+
${normalizeRuntimeShareCode}
|
|
1437
|
+
const normalizedModule = __mfNormalizeRuntimeShare(mod);
|
|
1438
|
+
const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
|
|
1293
1439
|
Object.defineProperty(exportModule, "__esModule", {
|
|
1294
1440
|
value: true,
|
|
1295
1441
|
enumerable: false
|
|
@@ -1297,6 +1443,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
|
|
|
1297
1443
|
__mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
|
|
1298
1444
|
}`;
|
|
1299
1445
|
}
|
|
1446
|
+
const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
1447
|
+
let current = mod;
|
|
1448
|
+
for (let i = 0; i < 5; i++) {
|
|
1449
|
+
const defaultExport = current?.default;
|
|
1450
|
+
if (!defaultExport || typeof defaultExport !== "object") break;
|
|
1451
|
+
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
1452
|
+
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
|
|
1453
|
+
current = defaultExport;
|
|
1454
|
+
}
|
|
1455
|
+
return current;
|
|
1456
|
+
};`;
|
|
1300
1457
|
function generateDirectSharedCacheSeedCode(command = "build") {
|
|
1301
1458
|
return getOrderedUsedShares().map((pkg) => {
|
|
1302
1459
|
const shareItem = getShareItemForPreload(pkg);
|
|
@@ -1319,7 +1476,8 @@ function getHostAutoInitSharedSeedItems() {
|
|
|
1319
1476
|
return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
|
|
1320
1477
|
});
|
|
1321
1478
|
}
|
|
1322
|
-
function generateHostAutoInitSharedCacheSeedCode() {
|
|
1479
|
+
function generateHostAutoInitSharedCacheSeedCode(command = "build") {
|
|
1480
|
+
if (command === "build") return "";
|
|
1323
1481
|
return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
|
|
1324
1482
|
if (!shareItem) return null;
|
|
1325
1483
|
return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
|
|
@@ -1351,43 +1509,62 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1351
1509
|
if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
|
|
1352
1510
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
1353
1511
|
}
|
|
1354
|
-
import {
|
|
1512
|
+
import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
|
|
1355
1513
|
${pluginImportNames.map((item) => item[1]).join("\n")}
|
|
1356
1514
|
${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
|
|
1357
1515
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
1358
1516
|
const initTokens = {}
|
|
1359
1517
|
const shareScopeName = ${JSON.stringify(options.shareScope)}
|
|
1360
1518
|
const mfName = ${JSON.stringify(options.internalName)}
|
|
1361
|
-
let runtimeInstance
|
|
1362
1519
|
let localSharedImportMapPromise
|
|
1363
1520
|
let exposesMapPromise
|
|
1521
|
+
const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
|
|
1522
|
+
const message = String((error && error.message) || error || '');
|
|
1523
|
+
return message.includes('Importing a module script failed') ||
|
|
1524
|
+
message.includes('Failed to fetch') ||
|
|
1525
|
+
message.includes('Load failed') ||
|
|
1526
|
+
message.includes('Outdated Optimize Dep');
|
|
1527
|
+
});
|
|
1528
|
+
const waitSharedInitRetry = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1529
|
+
async function retrySharedInit(fn) {
|
|
1530
|
+
for (let attempt = 0; ; attempt++) {
|
|
1531
|
+
try {
|
|
1532
|
+
return await fn();
|
|
1533
|
+
} catch (e) {
|
|
1534
|
+
const canRetry = typeof shouldRetrySharedInitError === 'function' && shouldRetrySharedInitError(e);
|
|
1535
|
+
if (!canRetry || attempt >= 19) throw e;
|
|
1536
|
+
await waitSharedInitRetry(250);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1364
1540
|
|
|
1365
1541
|
async function getLocalSharedImportMap() {
|
|
1366
|
-
localSharedImportMapPromise
|
|
1542
|
+
if (!localSharedImportMapPromise) {
|
|
1543
|
+
localSharedImportMapPromise = retrySharedInit(() => import("${getLocalSharedImportMapPath()}"))
|
|
1544
|
+
.catch((e) => { localSharedImportMapPromise = undefined; throw e; });
|
|
1545
|
+
}
|
|
1367
1546
|
return localSharedImportMapPromise
|
|
1368
1547
|
}
|
|
1369
1548
|
|
|
1370
1549
|
async function getExposesMap() {
|
|
1371
|
-
|
|
1550
|
+
if (!exposesMapPromise) {
|
|
1551
|
+
exposesMapPromise = retrySharedInit(() => import("${virtualExposesId}"))
|
|
1552
|
+
.then((mod) => mod.default ?? mod)
|
|
1553
|
+
.catch((e) => { exposesMapPromise = undefined; throw e; });
|
|
1554
|
+
}
|
|
1372
1555
|
return exposesMapPromise
|
|
1373
1556
|
}
|
|
1374
1557
|
|
|
1375
1558
|
async function init(shared = {}, initScope = []) {
|
|
1376
1559
|
const {usedShared, usedRemotes} = await getLocalSharedImportMap()
|
|
1377
1560
|
${generateDirectSharedCacheSeedCode(command)}
|
|
1378
|
-
const
|
|
1561
|
+
const initRes = runtimeInit({
|
|
1379
1562
|
name: mfName,
|
|
1380
1563
|
remotes: usedRemotes,
|
|
1381
1564
|
shared: usedShared,
|
|
1382
1565
|
plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
|
|
1383
1566
|
${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
|
|
1384
|
-
};
|
|
1385
|
-
if (!runtimeInstance) {
|
|
1386
|
-
runtimeInstance = createInstance(runtimeOptions);
|
|
1387
|
-
} else {
|
|
1388
|
-
runtimeInstance.initOptions(runtimeOptions);
|
|
1389
|
-
}
|
|
1390
|
-
const initRes = runtimeInstance;
|
|
1567
|
+
});
|
|
1391
1568
|
// handling circular init calls
|
|
1392
1569
|
var initToken = initTokens[shareScopeName];
|
|
1393
1570
|
if (!initToken)
|
|
@@ -1397,14 +1574,27 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1397
1574
|
initRes.initShareScopeMap('${options.shareScope}', shared);
|
|
1398
1575
|
initResolve(initRes)
|
|
1399
1576
|
try {
|
|
1400
|
-
await
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1577
|
+
await retrySharedInit(async () => {
|
|
1578
|
+
await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
|
|
1579
|
+
strategy: '${options.shareStrategy}',
|
|
1580
|
+
from: "build",
|
|
1581
|
+
initScope
|
|
1582
|
+
}));
|
|
1583
|
+
});
|
|
1405
1584
|
} catch (e) {
|
|
1406
1585
|
console.error('[Module Federation]', e)
|
|
1407
1586
|
}
|
|
1587
|
+
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1588
|
+
if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
|
|
1589
|
+
${normalizeRuntimeShareCode}
|
|
1590
|
+
const versions = shared?.[pkg];
|
|
1591
|
+
const provider = versions && versions[Object.keys(versions)[0]];
|
|
1592
|
+
if (!provider) continue;
|
|
1593
|
+
const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
|
|
1594
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
1595
|
+
const resolved = await Promise.resolve(mod);
|
|
1596
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1597
|
+
}
|
|
1408
1598
|
return initRes
|
|
1409
1599
|
}
|
|
1410
1600
|
|
|
@@ -1429,10 +1619,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1429
1619
|
async function initHost() {
|
|
1430
1620
|
if (!hostInitPromise) {
|
|
1431
1621
|
hostInitPromise = (async () => {
|
|
1432
|
-
${generateHostAutoInitSharedCacheSeedCode()}
|
|
1622
|
+
${generateHostAutoInitSharedCacheSeedCode(_command)}
|
|
1433
1623
|
const remoteEntry = await import(${remoteEntryImport});
|
|
1434
1624
|
const runtime = await remoteEntry.init();
|
|
1435
1625
|
const usedShared = ${generateUsedSharedPreloadConfig()};
|
|
1626
|
+
${normalizeRuntimeShareCode}
|
|
1436
1627
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
1437
1628
|
if (__mfModuleCache.share[pkg] !== undefined) {
|
|
1438
1629
|
continue;
|
|
@@ -1442,7 +1633,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
1442
1633
|
}).then((factory) => {
|
|
1443
1634
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
1444
1635
|
return Promise.resolve(mod).then((resolved) => {
|
|
1445
|
-
__mfModuleCache.share[pkg] = resolved;
|
|
1636
|
+
__mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
|
|
1446
1637
|
});
|
|
1447
1638
|
});
|
|
1448
1639
|
}
|
|
@@ -1471,7 +1662,7 @@ function getHostAutoInitImportId() {
|
|
|
1471
1662
|
return hostAutoInitModule.getImportId();
|
|
1472
1663
|
}
|
|
1473
1664
|
function getHostAutoInitPath() {
|
|
1474
|
-
return hostAutoInitModule.
|
|
1665
|
+
return hostAutoInitModule.getImportId();
|
|
1475
1666
|
}
|
|
1476
1667
|
//#endregion
|
|
1477
1668
|
//#region src/virtualModules/virtualRemotes.ts
|
|
@@ -1494,7 +1685,9 @@ function getUsedRemotesMap() {
|
|
|
1494
1685
|
}
|
|
1495
1686
|
function generateRemotes(id, command) {
|
|
1496
1687
|
const useReactProxy = command === "serve" && hasPackageDependency("react");
|
|
1497
|
-
const reactImportLine = useReactProxy ? `import
|
|
1688
|
+
const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
|
|
1689
|
+
import * as __mfReactNamespace from "react";
|
|
1690
|
+
const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
|
|
1498
1691
|
const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
|
|
1499
1692
|
import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
|
|
1500
1693
|
const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
|
|
@@ -1504,13 +1697,13 @@ function generateRemotes(id, command) {
|
|
|
1504
1697
|
}
|
|
1505
1698
|
export const __moduleExports = exportModule;
|
|
1506
1699
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1507
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1700
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
|
|
1508
1701
|
const mod = await __mfRemotePending;
|
|
1509
1702
|
if (mod !== undefined) exportModule = mod;
|
|
1510
1703
|
}
|
|
1511
1704
|
export const __moduleExports = exportModule;
|
|
1512
1705
|
export const __mf_remote_pending = Promise.resolve(exportModule);
|
|
1513
|
-
export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1706
|
+
export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
|
|
1514
1707
|
return `
|
|
1515
1708
|
${reactImportLine}
|
|
1516
1709
|
${importLine}
|
|
@@ -1683,17 +1876,26 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1683
1876
|
}
|
|
1684
1877
|
return patched;
|
|
1685
1878
|
}
|
|
1686
|
-
function getBootstrapSource(initSrc, entrySrc) {
|
|
1687
|
-
const remotePreloads = Object.
|
|
1879
|
+
function getBootstrapSource(initSrc, entrySrc, useSystemImportFallback = false) {
|
|
1880
|
+
const remotePreloads = Object.entries(getUsedRemotesMap()).flatMap(([remoteKey, remotes]) => Array.from(remotes).filter((remote) => remote !== remoteKey)).sort().map((remote) => `runtime.loadRemote(${JSON.stringify(remote)})`).join(",");
|
|
1881
|
+
const importHelper = useSystemImportFallback ? `const __mfImport = (src) =>
|
|
1882
|
+
globalThis.System && typeof globalThis.System.import === 'function'
|
|
1883
|
+
? globalThis.System.import(src)
|
|
1884
|
+
: import(src);
|
|
1885
|
+
` : "";
|
|
1886
|
+
const importExpression = (src) => useSystemImportFallback ? `__mfImport(${JSON.stringify(src)})` : `import(${JSON.stringify(src)})`;
|
|
1688
1887
|
return `${getRuntimeModuleCacheBootstrapCode()}
|
|
1689
|
-
(async () => {
|
|
1690
|
-
const { initHost } = await
|
|
1888
|
+
${importHelper}(async () => {
|
|
1889
|
+
const { initHost } = await ${importExpression(initSrc)};
|
|
1691
1890
|
const runtime = await initHost();
|
|
1692
1891
|
const __mfRemotePreloads = [${remotePreloads}];
|
|
1693
1892
|
await Promise.all(__mfRemotePreloads);
|
|
1694
|
-
})().then(() =>
|
|
1893
|
+
})().then(() => ${importExpression(entrySrc)});
|
|
1695
1894
|
`;
|
|
1696
1895
|
}
|
|
1896
|
+
function getSystemBootstrapSource(initSrc, entrySrc) {
|
|
1897
|
+
return getBootstrapSource(initSrc, entrySrc, true);
|
|
1898
|
+
}
|
|
1697
1899
|
function injectHtml() {
|
|
1698
1900
|
return inject === "html" && (htmlFilePath || hasPackageDependency("@sveltejs/kit"));
|
|
1699
1901
|
}
|
|
@@ -1701,6 +1903,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1701
1903
|
if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
|
|
1702
1904
|
return inject === "entry" || !htmlFilePath;
|
|
1703
1905
|
}
|
|
1906
|
+
function normalizeDevHtmlProxyId(id) {
|
|
1907
|
+
return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
|
|
1908
|
+
}
|
|
1704
1909
|
return [{
|
|
1705
1910
|
name: "add-entry",
|
|
1706
1911
|
apply: "serve",
|
|
@@ -1719,7 +1924,20 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1719
1924
|
}
|
|
1720
1925
|
},
|
|
1721
1926
|
configureServer(server) {
|
|
1722
|
-
server.middlewares.use((req,
|
|
1927
|
+
server.middlewares.use((req, res, next) => {
|
|
1928
|
+
const rawUrl = req.url?.split("#")[0] ?? "";
|
|
1929
|
+
if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
|
|
1930
|
+
const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
|
|
1931
|
+
const params = new URLSearchParams(query);
|
|
1932
|
+
const initSrc = params.get("init");
|
|
1933
|
+
const entrySrc = params.get("entry");
|
|
1934
|
+
if (initSrc && entrySrc) {
|
|
1935
|
+
res.statusCode = 200;
|
|
1936
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
1937
|
+
res.end(getBootstrapSource(initSrc, entrySrc));
|
|
1938
|
+
return;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1723
1941
|
if (!fileName) {
|
|
1724
1942
|
next();
|
|
1725
1943
|
return;
|
|
@@ -1736,7 +1954,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1736
1954
|
const base = viteConfig.base.replace(/\/$/, "");
|
|
1737
1955
|
const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
|
|
1738
1956
|
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
1739
|
-
return `/@id
|
|
1957
|
+
return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
1740
1958
|
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
1741
1959
|
entry: sanitizeDevEntryPath(stripBase(originalSrc))
|
|
1742
1960
|
}).toString()}`;
|
|
@@ -1745,11 +1963,12 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1745
1963
|
}
|
|
1746
1964
|
},
|
|
1747
1965
|
resolveId(id) {
|
|
1748
|
-
if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1966
|
+
if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
1749
1967
|
},
|
|
1750
1968
|
load(id) {
|
|
1751
|
-
|
|
1752
|
-
|
|
1969
|
+
const normalizedId = normalizeDevHtmlProxyId(id);
|
|
1970
|
+
if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
|
|
1971
|
+
const params = new URLSearchParams(normalizedId.slice(28));
|
|
1753
1972
|
const initSrc = params.get("init");
|
|
1754
1973
|
const entrySrc = params.get("entry");
|
|
1755
1974
|
if (!initSrc || !entrySrc) return;
|
|
@@ -1833,7 +2052,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
1833
2052
|
const bootstrapRef = this.emitFile({
|
|
1834
2053
|
type: "asset",
|
|
1835
2054
|
fileName: bootstrapFileName,
|
|
1836
|
-
source:
|
|
2055
|
+
source: getSystemBootstrapSource(initPath, entrySrc)
|
|
1837
2056
|
});
|
|
1838
2057
|
const bootstrapPath = viteConfig.base + this.getFileName(bootstrapRef);
|
|
1839
2058
|
return scriptTag.replace(entrySrc, bootstrapPath);
|
|
@@ -1978,7 +2197,7 @@ function getHmrWsPath(base, hmrPath) {
|
|
|
1978
2197
|
return `${normalizedBase.endsWith("/") ? normalizedBase.slice(0, -1) : normalizedBase}/${normalizedPath.startsWith("/") ? normalizedPath.slice(1) : normalizedPath}`;
|
|
1979
2198
|
}
|
|
1980
2199
|
function shouldIgnoreFile(file, options) {
|
|
1981
|
-
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("/.
|
|
2200
|
+
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");
|
|
1982
2201
|
}
|
|
1983
2202
|
function getRemoteHmrWsUrl(server) {
|
|
1984
2203
|
const hmr = server.config.server.hmr;
|
|
@@ -2019,7 +2238,22 @@ function getStringPreview(value, max = 180) {
|
|
|
2019
2238
|
return rawValue.slice(0, max);
|
|
2020
2239
|
}
|
|
2021
2240
|
function isRemoteHmrEnabled(dev) {
|
|
2022
|
-
return typeof dev === "object" && dev !== null && dev.remoteHmr
|
|
2241
|
+
return typeof dev === "object" && dev !== null && !!dev.remoteHmr;
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Detects whether the Vite plugin pipeline includes a framework with
|
|
2245
|
+
* cross-federation HMR support (a shared runtime proxy that works
|
|
2246
|
+
* across module federation boundaries).
|
|
2247
|
+
*
|
|
2248
|
+
* Currently only React is supported via the shared /@react-refresh proxy.
|
|
2249
|
+
*/
|
|
2250
|
+
function hasCrossFederationHmr(plugins) {
|
|
2251
|
+
const supportedPlugins = ["vite:react-refresh", "vite:react-swc:refresh"];
|
|
2252
|
+
return plugins.some((p) => supportedPlugins.includes(p.name));
|
|
2253
|
+
}
|
|
2254
|
+
function resolveHmrStrategy(dev, plugins) {
|
|
2255
|
+
if (typeof dev === "object" && dev !== null && dev.remoteHmr === "full-reload") return "full-reload";
|
|
2256
|
+
return hasCrossFederationHmr(plugins) ? "native" : "full-reload";
|
|
2023
2257
|
}
|
|
2024
2258
|
function pluginDevRemoteHmr(options) {
|
|
2025
2259
|
return {
|
|
@@ -2029,6 +2263,7 @@ function pluginDevRemoteHmr(options) {
|
|
|
2029
2263
|
if (!isRemoteHmrEnabled(options.dev)) return;
|
|
2030
2264
|
const isRemote = Object.keys(options.exposes).length > 0;
|
|
2031
2265
|
const isHost = Object.keys(options.remotes).length > 0;
|
|
2266
|
+
const strategy = resolveHmrStrategy(options.dev, server.config.plugins);
|
|
2032
2267
|
if (isRemote) {
|
|
2033
2268
|
const endpointPath = getRemoteHmrPath(server.config.base);
|
|
2034
2269
|
const wsUrl = getRemoteHmrWsUrl(server);
|
|
@@ -2052,6 +2287,7 @@ function pluginDevRemoteHmr(options) {
|
|
|
2052
2287
|
}));
|
|
2053
2288
|
});
|
|
2054
2289
|
const broadcast = (file) => {
|
|
2290
|
+
if (strategy === "native") return;
|
|
2055
2291
|
if (shouldIgnoreFile(file, options)) return;
|
|
2056
2292
|
server.ws.send({
|
|
2057
2293
|
type: "custom",
|
|
@@ -2116,6 +2352,7 @@ function pluginDevRemoteHmr(options) {
|
|
|
2116
2352
|
}
|
|
2117
2353
|
const ws = new WebSocket(metadata.wsUrl, "vite-hmr");
|
|
2118
2354
|
ws.onmessage = (rawEvent) => {
|
|
2355
|
+
if (strategy === "native") return;
|
|
2119
2356
|
const message = parseRemoteHmrMessage(rawEvent.data);
|
|
2120
2357
|
if (!message || message.event !== REMOTE_HMR_EVENT) return;
|
|
2121
2358
|
server.ws.send({ type: "full-reload" });
|
|
@@ -2140,6 +2377,7 @@ function pluginDevRemoteHmr(options) {
|
|
|
2140
2377
|
};
|
|
2141
2378
|
for (const [remoteName, remote] of Object.entries(options.remotes)) connectRemote(remoteName, remote);
|
|
2142
2379
|
const triggerHostReload = (file) => {
|
|
2380
|
+
if (strategy === "native") return;
|
|
2143
2381
|
if (shouldIgnoreFile(file, options)) return;
|
|
2144
2382
|
server.ws.send({ type: "full-reload" });
|
|
2145
2383
|
};
|
|
@@ -2462,6 +2700,26 @@ function initVirtualModules(command, remoteEntryId) {
|
|
|
2462
2700
|
}
|
|
2463
2701
|
//#endregion
|
|
2464
2702
|
//#region src/utils/bundleHelpers.ts
|
|
2703
|
+
function isOutputChunk$1(chunk) {
|
|
2704
|
+
return chunk.type === "chunk";
|
|
2705
|
+
}
|
|
2706
|
+
function escapeRegExp(value) {
|
|
2707
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2708
|
+
}
|
|
2709
|
+
function getProxyBaseName(fileName) {
|
|
2710
|
+
return fileName.replace(/^.*\//, "").replace(/\.js$/, "").replace(/-[A-Za-z0-9_-]+$/, "");
|
|
2711
|
+
}
|
|
2712
|
+
function extractFunctionDeclaration(code, functionName) {
|
|
2713
|
+
const funcRe = new RegExp(`function\\s+${functionName}\\s*\\([^)]*\\)\\s*\\{`);
|
|
2714
|
+
const funcStart = code.search(funcRe);
|
|
2715
|
+
if (funcStart < 0) return;
|
|
2716
|
+
let depth = 0;
|
|
2717
|
+
for (let i = code.indexOf("{", funcStart); i < code.length; i++) if (code[i] === "{") depth++;
|
|
2718
|
+
else if (code[i] === "}") {
|
|
2719
|
+
depth--;
|
|
2720
|
+
if (depth === 0) return code.slice(funcStart, i + 1);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2465
2723
|
/**
|
|
2466
2724
|
* Resolve the local alias for a non-inlineable proxy binding.
|
|
2467
2725
|
* If Rollup's deconflict renamed the alias but didn't update references
|
|
@@ -2484,6 +2742,147 @@ function resolveProxyAlias(binding, proxyLocal, code, fullImport, claimedLocals
|
|
|
2484
2742
|
local
|
|
2485
2743
|
};
|
|
2486
2744
|
}
|
|
2745
|
+
function collectLoadShareProxyChunks(bundle, loadShareTag) {
|
|
2746
|
+
const proxyChunks = /* @__PURE__ */ new Map();
|
|
2747
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2748
|
+
if (!isOutputChunk$1(chunk)) continue;
|
|
2749
|
+
if (fileName.includes(loadShareTag) && fileName.includes("commonjs-proxy")) proxyChunks.set(fileName, {
|
|
2750
|
+
code: chunk.code,
|
|
2751
|
+
fileName
|
|
2752
|
+
});
|
|
2753
|
+
}
|
|
2754
|
+
return proxyChunks;
|
|
2755
|
+
}
|
|
2756
|
+
function collectSystemProxyInfos(proxyChunks, loadShareTag) {
|
|
2757
|
+
const systemProxyInfo = /* @__PURE__ */ new Map();
|
|
2758
|
+
for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
|
|
2759
|
+
const depsMatch = proxyInfo.code.match(/System\.register\(\[([\s\S]*?)\]/);
|
|
2760
|
+
if (!depsMatch) continue;
|
|
2761
|
+
const loadShareDep = Array.from(depsMatch[1].matchAll(/["']([^"']+)["']/g)).map((m) => m[1]).find((dep) => dep.includes(loadShareTag) && !dep.includes("commonjs-proxy"));
|
|
2762
|
+
if (!loadShareDep) continue;
|
|
2763
|
+
const loadShareBindings = {};
|
|
2764
|
+
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];
|
|
2765
|
+
const exportMap = {};
|
|
2766
|
+
const objectExportMatch = proxyInfo.code.match(/exports\(\s*\{([\s\S]*?)\}\s*\)/);
|
|
2767
|
+
if (objectExportMatch) for (const m of objectExportMatch[1].matchAll(/([A-Za-z_$][\w$]*)\s*:\s*([A-Za-z_$][\w$]*)/g)) {
|
|
2768
|
+
const [, exported, local] = m;
|
|
2769
|
+
const funcBody = extractFunctionDeclaration(proxyInfo.code, local);
|
|
2770
|
+
if (funcBody) exportMap[exported] = {
|
|
2771
|
+
type: "helper",
|
|
2772
|
+
code: funcBody
|
|
2773
|
+
};
|
|
2774
|
+
}
|
|
2775
|
+
for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
|
|
2776
|
+
const exported = m[1];
|
|
2777
|
+
const expression = m[2];
|
|
2778
|
+
for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
|
|
2779
|
+
exportMap[exported] = {
|
|
2780
|
+
type: "reexport",
|
|
2781
|
+
exportName
|
|
2782
|
+
};
|
|
2783
|
+
break;
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
if (Object.keys(exportMap).length > 0) systemProxyInfo.set(proxyFileName, {
|
|
2787
|
+
loadShareDep,
|
|
2788
|
+
exportMap
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2791
|
+
return systemProxyInfo;
|
|
2792
|
+
}
|
|
2793
|
+
function rewriteEsmProxyConsumers(code, proxyChunks) {
|
|
2794
|
+
let nextCode = code;
|
|
2795
|
+
const claimedLocals = /* @__PURE__ */ new Set();
|
|
2796
|
+
for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
|
|
2797
|
+
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
2798
|
+
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
|
|
2799
|
+
if (!importMatch) continue;
|
|
2800
|
+
const fullImport = importMatch[0];
|
|
2801
|
+
const bindings = importMatch[1].split(",").map((s) => {
|
|
2802
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
2803
|
+
return {
|
|
2804
|
+
imported: parts[0].trim(),
|
|
2805
|
+
local: (parts[1] || parts[0]).trim()
|
|
2806
|
+
};
|
|
2807
|
+
});
|
|
2808
|
+
const exportMapMatch = proxyInfo.code.match(/export\s*\{([^}]+)\}/);
|
|
2809
|
+
if (!exportMapMatch) continue;
|
|
2810
|
+
const exportMap = {};
|
|
2811
|
+
for (const entry of exportMapMatch[1].split(",")) {
|
|
2812
|
+
const parts = entry.trim().split(/\s+as\s+/);
|
|
2813
|
+
if (parts.length === 2) exportMap[parts[1].trim()] = parts[0].trim();
|
|
2814
|
+
}
|
|
2815
|
+
const inlineable = [];
|
|
2816
|
+
const nonInlineable = [];
|
|
2817
|
+
const pendingLocals = new Set(bindings.map((binding) => binding.local));
|
|
2818
|
+
for (const b of bindings) {
|
|
2819
|
+
pendingLocals.delete(b.local);
|
|
2820
|
+
const proxyLocal = exportMap[b.imported];
|
|
2821
|
+
if (!proxyLocal) {
|
|
2822
|
+
claimedLocals.add(b.local);
|
|
2823
|
+
nonInlineable.push(b);
|
|
2824
|
+
continue;
|
|
2825
|
+
}
|
|
2826
|
+
const funcBody = extractFunctionDeclaration(proxyInfo.code, proxyLocal);
|
|
2827
|
+
if (funcBody) {
|
|
2828
|
+
inlineable.push({
|
|
2829
|
+
local: b.local,
|
|
2830
|
+
funcBody: funcBody.replace(new RegExp(`function\\s+${proxyLocal}\\s*\\(`), `function ${b.local}(`)
|
|
2831
|
+
});
|
|
2832
|
+
claimedLocals.add(b.local);
|
|
2833
|
+
} else {
|
|
2834
|
+
const unavailableLocals = new Set(claimedLocals);
|
|
2835
|
+
pendingLocals.forEach((local) => unavailableLocals.add(local));
|
|
2836
|
+
const resolvedBinding = resolveProxyAlias(b, proxyLocal, nextCode, fullImport, unavailableLocals);
|
|
2837
|
+
claimedLocals.add(resolvedBinding.local);
|
|
2838
|
+
nonInlineable.push(resolvedBinding);
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
const hasRenamedAlias = nonInlineable.some((b) => bindings.find((ob) => ob.imported === b.imported)?.local !== b.local);
|
|
2842
|
+
if (inlineable.length === 0 && !hasRenamedAlias) continue;
|
|
2843
|
+
let replacement = "";
|
|
2844
|
+
if (nonInlineable.length > 0) replacement = `import{${nonInlineable.map((b) => b.imported === b.local ? b.imported : `${b.imported} as ${b.local}`).join(",")}}from"${importMatch[2]}";`;
|
|
2845
|
+
replacement += inlineable.map((f) => f.funcBody).join("");
|
|
2846
|
+
nextCode = nextCode.replace(fullImport, () => replacement);
|
|
2847
|
+
}
|
|
2848
|
+
return nextCode;
|
|
2849
|
+
}
|
|
2850
|
+
function rewriteSystemProxyConsumers(code, systemProxyInfo) {
|
|
2851
|
+
if (!code.includes("System.register(")) return code;
|
|
2852
|
+
let nextCode = code;
|
|
2853
|
+
for (const [proxyFileName, proxyInfo] of Array.from(systemProxyInfo.entries())) {
|
|
2854
|
+
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
2855
|
+
const depMatch = new RegExp(`["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']`).exec(nextCode);
|
|
2856
|
+
if (!depMatch) continue;
|
|
2857
|
+
let setterIndex = 0;
|
|
2858
|
+
const depListMatch = nextCode.match(/System\.register\(\[([\s\S]*?)\]/);
|
|
2859
|
+
if (depListMatch) setterIndex = Array.from(depListMatch[1].matchAll(/["']([^"']+)["']/g)).map((m) => m[1]).findIndex((dep) => dep.includes(proxyBaseName));
|
|
2860
|
+
if (setterIndex < 0) continue;
|
|
2861
|
+
const settersStart = nextCode.indexOf("setters: [");
|
|
2862
|
+
if (settersStart < 0) continue;
|
|
2863
|
+
const setterMatch = Array.from(nextCode.slice(settersStart).matchAll(/\((module\d+)\)\s*=>\s*\{([\s\S]*?)\}/g))[setterIndex];
|
|
2864
|
+
if (!setterMatch) continue;
|
|
2865
|
+
const [fullSetter, moduleLocal, setterBody] = setterMatch;
|
|
2866
|
+
const helpersToInline = [];
|
|
2867
|
+
const nextSetterBody = setterBody.replace(new RegExp(`([A-Za-z_$][\\w$]*)\\s*=\\s*${moduleLocal}\\.([A-Za-z_$][\\w$]*);?`, "g"), (assignment, local, imported) => {
|
|
2868
|
+
const mapped = proxyInfo.exportMap[imported];
|
|
2869
|
+
if (!mapped) return assignment;
|
|
2870
|
+
if (mapped.type === "helper") {
|
|
2871
|
+
helpersToInline.push(mapped.code.replace(new RegExp(`function\\s+${imported}\\s*\\(`), `function ${local}(`));
|
|
2872
|
+
return "";
|
|
2873
|
+
}
|
|
2874
|
+
return `${local} = ${moduleLocal}.${mapped.exportName};`;
|
|
2875
|
+
});
|
|
2876
|
+
if (nextSetterBody === setterBody && helpersToInline.length === 0) continue;
|
|
2877
|
+
const nextSetter = fullSetter.replace(setterBody, () => nextSetterBody);
|
|
2878
|
+
nextCode = nextCode.replace(fullSetter, () => nextSetter);
|
|
2879
|
+
nextCode = nextCode.replace(depMatch[0], JSON.stringify(proxyInfo.loadShareDep));
|
|
2880
|
+
if (helpersToInline.length > 0) nextCode = nextCode.replace("execute: (function() {", () => {
|
|
2881
|
+
return `execute: (function() {${helpersToInline.join("")}`;
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
return nextCode;
|
|
2885
|
+
}
|
|
2487
2886
|
function findRemoteEntryFile(filename, bundle) {
|
|
2488
2887
|
for (const [_, fileData] of Object.entries(bundle)) if (filename.replace(/[\[\]]/g, "_").replace(/\.[^/.]+$/, "") === fileData.name || fileData.name === "remoteEntry") return fileData.fileName;
|
|
2489
2888
|
}
|
|
@@ -2653,6 +3052,9 @@ function normalizeNodeModulePath(source) {
|
|
|
2653
3052
|
function isNodeModulePath(source) {
|
|
2654
3053
|
return source.includes("/node_modules/") || source.includes("\\node_modules\\");
|
|
2655
3054
|
}
|
|
3055
|
+
function filterId(id) {
|
|
3056
|
+
return typeof id === "string" && !id.includes("\0");
|
|
3057
|
+
}
|
|
2656
3058
|
function getMatchingNodeModuleSubpath(source, candidates) {
|
|
2657
3059
|
const normalized = normalizeNodeModulePath(source);
|
|
2658
3060
|
return [...candidates].sort((a, b) => b.length - a.length).find((candidate) => normalized.includes(`/node_modules/${candidate}/`) || normalized.includes(`/node_modules/${candidate}.`));
|
|
@@ -2837,10 +3239,11 @@ const Manifest = () => {
|
|
|
2837
3239
|
alias: remoteKey,
|
|
2838
3240
|
entry: "*"
|
|
2839
3241
|
})));
|
|
2840
|
-
const shared = Array.from(getUsedShares()).
|
|
3242
|
+
const shared = Array.from(getUsedShares()).flatMap((shareKey) => {
|
|
2841
3243
|
const shareItem = getNormalizeShareItem(shareKey);
|
|
3244
|
+
if (!shareItem) return [];
|
|
2842
3245
|
const assets = preloadMap[shareKey] || createEmptyAssetMap();
|
|
2843
|
-
return {
|
|
3246
|
+
return [{
|
|
2844
3247
|
id: `${name}:${shareKey}`,
|
|
2845
3248
|
name: shareKey,
|
|
2846
3249
|
version: shareItem.version,
|
|
@@ -2856,7 +3259,7 @@ const Manifest = () => {
|
|
|
2856
3259
|
sync: assets.css.sync
|
|
2857
3260
|
}
|
|
2858
3261
|
}
|
|
2859
|
-
};
|
|
3262
|
+
}];
|
|
2860
3263
|
});
|
|
2861
3264
|
const exposes = Object.entries(options.exposes).map(([key, value]) => {
|
|
2862
3265
|
const formatKey = key.replace("./", "");
|
|
@@ -3008,7 +3411,6 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
3008
3411
|
}
|
|
3009
3412
|
//#endregion
|
|
3010
3413
|
//#region src/plugins/pluginProxyRemoteEntry.ts
|
|
3011
|
-
const filter$1 = createFilter();
|
|
3012
3414
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
3013
3415
|
let viteConfig, _command, root;
|
|
3014
3416
|
return {
|
|
@@ -3048,14 +3450,14 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
3048
3450
|
},
|
|
3049
3451
|
transform(code, id) {
|
|
3050
3452
|
return mapCodeToCodeWithSourcemap((() => {
|
|
3051
|
-
if (!
|
|
3453
|
+
if (!filterId(id)) return;
|
|
3052
3454
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
3053
3455
|
if (id === virtualExposesId) return generateExposes(options);
|
|
3054
3456
|
if (id.includes(getHostAutoInitPath())) {
|
|
3055
3457
|
if (_command === "serve") {
|
|
3056
3458
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
3057
3459
|
const publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
3058
|
-
const fallbackOrigin =
|
|
3460
|
+
const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
|
|
3059
3461
|
const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
|
|
3060
3462
|
return `
|
|
3061
3463
|
const origin = typeof window !== 'undefined' && (${!options.ignoreOrigin}) ? window.origin : ${JSON.stringify(fallbackOrigin)};
|
|
@@ -3106,10 +3508,25 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
3106
3508
|
}
|
|
3107
3509
|
//#endregion
|
|
3108
3510
|
//#region src/plugins/pluginProxyRemotes.ts
|
|
3109
|
-
const filter = createFilter();
|
|
3110
3511
|
function isNodeModulesImporter(importer) {
|
|
3111
3512
|
return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
|
|
3112
3513
|
}
|
|
3514
|
+
function appendAlias(config, alias) {
|
|
3515
|
+
config.resolve ??= {};
|
|
3516
|
+
const existingAlias = config.resolve.alias;
|
|
3517
|
+
if (!existingAlias) {
|
|
3518
|
+
config.resolve.alias = [alias];
|
|
3519
|
+
return;
|
|
3520
|
+
}
|
|
3521
|
+
if (Array.isArray(existingAlias)) {
|
|
3522
|
+
existingAlias.push(alias);
|
|
3523
|
+
return;
|
|
3524
|
+
}
|
|
3525
|
+
config.resolve.alias = [...Object.entries(existingAlias).map(([find, replacement]) => ({
|
|
3526
|
+
find,
|
|
3527
|
+
replacement
|
|
3528
|
+
})), alias];
|
|
3529
|
+
}
|
|
3113
3530
|
function pluginProxyRemotes_default(options) {
|
|
3114
3531
|
let command;
|
|
3115
3532
|
let root = process.cwd();
|
|
@@ -3122,23 +3539,24 @@ function pluginProxyRemotes_default(options) {
|
|
|
3122
3539
|
const remoteModule = getRemoteVirtualModule(source, command);
|
|
3123
3540
|
addUsedRemote(remoteName, source);
|
|
3124
3541
|
refreshHostAutoInit();
|
|
3125
|
-
return remoteModule.
|
|
3542
|
+
return remoteModule.getImportId();
|
|
3126
3543
|
}
|
|
3127
3544
|
return {
|
|
3128
3545
|
name: "proxyRemotes",
|
|
3546
|
+
enforce: "pre",
|
|
3129
3547
|
config(config, { command: _command }) {
|
|
3130
3548
|
command = _command;
|
|
3131
3549
|
root = config.root || process.cwd();
|
|
3132
3550
|
Object.keys(remotes).forEach((key) => {
|
|
3133
3551
|
const remote = remotes[key];
|
|
3134
|
-
config
|
|
3552
|
+
appendAlias(config, {
|
|
3135
3553
|
find: new RegExp(`^(${remote.name}(\/.*|$))`),
|
|
3136
3554
|
replacement: "$1"
|
|
3137
3555
|
});
|
|
3138
3556
|
});
|
|
3139
3557
|
},
|
|
3140
3558
|
resolveId(source, importer) {
|
|
3141
|
-
if (!
|
|
3559
|
+
if (!filterId(source)) return;
|
|
3142
3560
|
for (const remote of Object.values(remotes)) {
|
|
3143
3561
|
if (source !== remote.name && !source.startsWith(`${remote.name}/`)) continue;
|
|
3144
3562
|
return resolveRemoteId(source, importer, remote.name);
|
|
@@ -3239,7 +3657,7 @@ function excludeSharedSubDependencies(shared) {
|
|
|
3239
3657
|
for (const dep of deps) {
|
|
3240
3658
|
const depKey = sharedKeyByBase.get(dep);
|
|
3241
3659
|
if (depKey && depKey !== parentKey) {
|
|
3242
|
-
if (shared[depKey]?.shareConfig.import === false) continue;
|
|
3660
|
+
if (shared[depKey]?.shareConfig.singleton === true || shared[depKey]?.shareConfig.import === false) continue;
|
|
3243
3661
|
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.`);
|
|
3244
3662
|
delete shared[depKey];
|
|
3245
3663
|
sharedKeys.delete(depKey);
|
|
@@ -3255,15 +3673,27 @@ function proxySharedModule(options) {
|
|
|
3255
3673
|
let useDirectReactImport = false;
|
|
3256
3674
|
let useRolldown = false;
|
|
3257
3675
|
const savePrebuild = new PromiseStore();
|
|
3676
|
+
let devServer;
|
|
3258
3677
|
return [
|
|
3259
3678
|
{
|
|
3260
3679
|
name: "generateLocalSharedImportMap",
|
|
3261
3680
|
enforce: "post",
|
|
3681
|
+
configureServer(server) {
|
|
3682
|
+
devServer = server;
|
|
3683
|
+
setLocalSharedImportMapInvalidator(() => {
|
|
3684
|
+
const module = server.moduleGraph.getModuleById(getResolvedLocalSharedImportMapId());
|
|
3685
|
+
if (module) server.moduleGraph.invalidateModule(module);
|
|
3686
|
+
});
|
|
3687
|
+
},
|
|
3688
|
+
resolveId(source) {
|
|
3689
|
+
if (source === getLocalSharedImportMapPath()) return getResolvedLocalSharedImportMapId();
|
|
3690
|
+
},
|
|
3262
3691
|
load(id) {
|
|
3263
|
-
if (id
|
|
3692
|
+
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
3264
3693
|
},
|
|
3265
|
-
|
|
3266
|
-
if (
|
|
3694
|
+
closeBundle() {
|
|
3695
|
+
if (devServer) return;
|
|
3696
|
+
setLocalSharedImportMapInvalidator(void 0);
|
|
3267
3697
|
}
|
|
3268
3698
|
},
|
|
3269
3699
|
{
|
|
@@ -3394,7 +3824,7 @@ function wrapDynamicImport(original) {
|
|
|
3394
3824
|
}
|
|
3395
3825
|
function applyRewrites(code, imports, id) {
|
|
3396
3826
|
if (imports.length === 0) return;
|
|
3397
|
-
const ms = new
|
|
3827
|
+
const ms = new CodeRewriter(code);
|
|
3398
3828
|
let changed = false;
|
|
3399
3829
|
let counter = 0;
|
|
3400
3830
|
for (const imp of imports) switch (imp.kind) {
|
|
@@ -3442,7 +3872,7 @@ function applyRewrites(code, imports, id) {
|
|
|
3442
3872
|
if (!changed) return;
|
|
3443
3873
|
return {
|
|
3444
3874
|
code: ms.toString(),
|
|
3445
|
-
map: ms.generateMap(
|
|
3875
|
+
map: ms.generateMap(id)
|
|
3446
3876
|
};
|
|
3447
3877
|
}
|
|
3448
3878
|
async function collectFromAST(ast, code, isRemoteImport) {
|
|
@@ -3511,7 +3941,7 @@ async function collectFromEsLexer(code, isRemoteImport) {
|
|
|
3511
3941
|
await init;
|
|
3512
3942
|
let imports;
|
|
3513
3943
|
try {
|
|
3514
|
-
[imports] = parse
|
|
3944
|
+
[imports] = parse(code);
|
|
3515
3945
|
} catch {
|
|
3516
3946
|
return;
|
|
3517
3947
|
}
|
|
@@ -3884,6 +4314,9 @@ function ignoreFederationGeneratedFiles(config, options) {
|
|
|
3884
4314
|
function isSharedResolverInternalImporter(importer) {
|
|
3885
4315
|
return !!importer && (importer.includes("__loadShare__") || importer.includes("__prebuild__"));
|
|
3886
4316
|
}
|
|
4317
|
+
function isCommonJsImporter(importer) {
|
|
4318
|
+
return !!importer && (importer.endsWith(".cjs") || importer.includes("/cjs/"));
|
|
4319
|
+
}
|
|
3887
4320
|
function isOutputChunk(chunk) {
|
|
3888
4321
|
return chunk.type === "chunk";
|
|
3889
4322
|
}
|
|
@@ -3928,12 +4361,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
3928
4361
|
return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
|
|
3929
4362
|
}
|
|
3930
4363
|
/**
|
|
3931
|
-
* Plugin that runs FIRST to
|
|
3932
|
-
* This prevents 504 "Outdated Optimize Dep" errors by ensuring
|
|
4364
|
+
* Plugin that runs FIRST to register generated virtual modules in the config hook.
|
|
4365
|
+
* This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
|
|
3933
4366
|
* before Vite's optimization phase.
|
|
3934
4367
|
*/
|
|
3935
4368
|
function createEarlyVirtualModulesPlugin(options) {
|
|
3936
|
-
const { shared, remotes
|
|
4369
|
+
const { shared, remotes } = options;
|
|
3937
4370
|
const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
|
|
3938
4371
|
return {
|
|
3939
4372
|
name: "vite:module-federation-early-init",
|
|
@@ -3943,9 +4376,6 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
3943
4376
|
const root = config.root || process.cwd();
|
|
3944
4377
|
setPackageDetectionCwd(root);
|
|
3945
4378
|
const isVinext = hasPackageDependency("vinext");
|
|
3946
|
-
initVirtualModuleInfrastructure(root, virtualModuleDir);
|
|
3947
|
-
VirtualModule.setRoot(root);
|
|
3948
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
3949
4379
|
initVirtualModules(_command, getRemoteEntryId(options));
|
|
3950
4380
|
const isRolldown = getIsRolldown(this);
|
|
3951
4381
|
if (remotes && Object.keys(remotes).length > 0) {
|
|
@@ -3967,9 +4397,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
3967
4397
|
optimizeDeps.rolldownOptions.plugins ??= [];
|
|
3968
4398
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
3969
4399
|
name: "module-federation:optimize-shared-resolver",
|
|
3970
|
-
resolveId(source, importer) {
|
|
4400
|
+
resolveId(source, importer, options) {
|
|
4401
|
+
if (options?.kind?.startsWith("require")) return;
|
|
3971
4402
|
if (isSharedResolverInternalImporter(importer)) return;
|
|
3972
|
-
if (
|
|
4403
|
+
if (isCommonJsImporter(importer)) return;
|
|
3973
4404
|
const key = findSharedKey(source, shared);
|
|
3974
4405
|
if (!key) return;
|
|
3975
4406
|
if (source.endsWith(".css")) return;
|
|
@@ -3990,6 +4421,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
3990
4421
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
3991
4422
|
name: "module-federation:optimize-shared-proxy",
|
|
3992
4423
|
setup(build) {
|
|
4424
|
+
build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
|
|
4425
|
+
path: args.path,
|
|
4426
|
+
external: true
|
|
4427
|
+
}));
|
|
3993
4428
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
3994
4429
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
3995
4430
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
@@ -4021,7 +4456,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4021
4456
|
}
|
|
4022
4457
|
});
|
|
4023
4458
|
}
|
|
4024
|
-
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
4025
4459
|
}
|
|
4026
4460
|
for (const key of Object.keys(shared)) {
|
|
4027
4461
|
const shareItem = shared[key];
|
|
@@ -4032,7 +4466,6 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4032
4466
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4033
4467
|
writePreBuildLibPath(subpath, shareItem);
|
|
4034
4468
|
optimizeDeps.include.push(subpath);
|
|
4035
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4036
4469
|
}
|
|
4037
4470
|
}
|
|
4038
4471
|
continue;
|
|
@@ -4049,14 +4482,11 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
4049
4482
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
4050
4483
|
optimizeDeps.include ??= [];
|
|
4051
4484
|
optimizeDeps.exclude ??= [];
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
|
|
4055
|
-
optimizeDeps.include.push(getPreBuildLibImportId(key));
|
|
4485
|
+
if (isLitShare(key)) optimizeDeps.exclude.push(key);
|
|
4486
|
+
else optimizeDeps.include.push(key);
|
|
4056
4487
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
4057
4488
|
writePreBuildLibPath(subpath, shareItem);
|
|
4058
4489
|
optimizeDeps.include.push(subpath);
|
|
4059
|
-
optimizeDeps.include.push(getPreBuildLibImportId(subpath));
|
|
4060
4490
|
}
|
|
4061
4491
|
}
|
|
4062
4492
|
}
|
|
@@ -4076,6 +4506,21 @@ function federation(mfUserOptions) {
|
|
|
4076
4506
|
let command;
|
|
4077
4507
|
let desiredRolldownOutput;
|
|
4078
4508
|
return [
|
|
4509
|
+
{
|
|
4510
|
+
name: "vite:module-federation-virtual-modules",
|
|
4511
|
+
enforce: "pre",
|
|
4512
|
+
resolveId(id) {
|
|
4513
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4514
|
+
if (!virtualModule) return;
|
|
4515
|
+
return virtualModule.getResolvedId();
|
|
4516
|
+
},
|
|
4517
|
+
load(id) {
|
|
4518
|
+
const virtualModule = VirtualModule.findById(id);
|
|
4519
|
+
if (!virtualModule) return;
|
|
4520
|
+
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
4521
|
+
return virtualModule.code;
|
|
4522
|
+
}
|
|
4523
|
+
},
|
|
4079
4524
|
createEarlyVirtualModulesPlugin(options),
|
|
4080
4525
|
...isVinext ? [{
|
|
4081
4526
|
name: "module-federation-vinext-react-server-build-alias",
|
|
@@ -4100,9 +4545,7 @@ function federation(mfUserOptions) {
|
|
|
4100
4545
|
config(_config, env) {
|
|
4101
4546
|
command = env.command;
|
|
4102
4547
|
},
|
|
4103
|
-
configResolved(
|
|
4104
|
-
VirtualModule.setRoot(config.root);
|
|
4105
|
-
VirtualModule.ensureVirtualPackageExists();
|
|
4548
|
+
configResolved() {
|
|
4106
4549
|
initVirtualModules(command, remoteEntryId);
|
|
4107
4550
|
}
|
|
4108
4551
|
},
|
|
@@ -4245,9 +4688,8 @@ function federation(mfUserOptions) {
|
|
|
4245
4688
|
}
|
|
4246
4689
|
},
|
|
4247
4690
|
load(id) {
|
|
4248
|
-
if (id.startsWith("\0")) return;
|
|
4249
4691
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
4250
|
-
let code = readFileSync(id, "utf-8");
|
|
4692
|
+
let code = VirtualModule.findById(id)?.code ?? readFileSync(id, "utf-8");
|
|
4251
4693
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4252
4694
|
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
4253
4695
|
/**
|
|
@@ -4266,7 +4708,10 @@ function federation(mfUserOptions) {
|
|
|
4266
4708
|
*
|
|
4267
4709
|
* @see https://rollupjs.org/plugin-development/#synthetic-named-exports
|
|
4268
4710
|
*/
|
|
4269
|
-
if (
|
|
4711
|
+
if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
|
|
4712
|
+
const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
|
|
4713
|
+
code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
|
|
4714
|
+
}
|
|
4270
4715
|
if (getIsRolldown(this)) return { code };
|
|
4271
4716
|
return {
|
|
4272
4717
|
code,
|
|
@@ -4280,87 +4725,17 @@ function federation(mfUserOptions) {
|
|
|
4280
4725
|
if (!isFederationControlChunk(fileName, filename)) continue;
|
|
4281
4726
|
chunk.code = sanitizeFederationControlChunk(chunk.code, fileName, filename);
|
|
4282
4727
|
}
|
|
4283
|
-
const proxyChunks =
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
fileName
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
if (fileName.includes("__loadShare__")) continue;
|
|
4294
|
-
let code = chunk.code;
|
|
4295
|
-
let modified = false;
|
|
4296
|
-
const claimedLocals = /* @__PURE__ */ new Set();
|
|
4297
|
-
for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
|
|
4298
|
-
const proxyBaseName = proxyFileName.replace(/^.*\//, "").replace(/\.js$/, "").replace(/-[A-Za-z0-9_-]+$/, "");
|
|
4299
|
-
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${proxyBaseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^"']*)["']\\s*;?`).exec(code);
|
|
4300
|
-
if (!importMatch) continue;
|
|
4301
|
-
const fullImport = importMatch[0];
|
|
4302
|
-
const bindings = importMatch[1].split(",").map((s) => {
|
|
4303
|
-
const parts = s.trim().split(/\s+as\s+/);
|
|
4304
|
-
return {
|
|
4305
|
-
imported: parts[0].trim(),
|
|
4306
|
-
local: (parts[1] || parts[0]).trim()
|
|
4307
|
-
};
|
|
4308
|
-
});
|
|
4309
|
-
const proxyCode = proxyInfo.code;
|
|
4310
|
-
const exportMapMatch = proxyCode.match(/export\s*\{([^}]+)\}/);
|
|
4311
|
-
if (!exportMapMatch) continue;
|
|
4312
|
-
const exportMap = {};
|
|
4313
|
-
for (const entry of exportMapMatch[1].split(",")) {
|
|
4314
|
-
const parts = entry.trim().split(/\s+as\s+/);
|
|
4315
|
-
if (parts.length === 2) exportMap[parts[1].trim()] = parts[0].trim();
|
|
4316
|
-
}
|
|
4317
|
-
const inlineable = [];
|
|
4318
|
-
const nonInlineable = [];
|
|
4319
|
-
const pendingLocals = new Set(bindings.map((binding) => binding.local));
|
|
4320
|
-
for (const b of bindings) {
|
|
4321
|
-
pendingLocals.delete(b.local);
|
|
4322
|
-
const proxyLocal = exportMap[b.imported];
|
|
4323
|
-
if (!proxyLocal) {
|
|
4324
|
-
claimedLocals.add(b.local);
|
|
4325
|
-
nonInlineable.push(b);
|
|
4326
|
-
continue;
|
|
4327
|
-
}
|
|
4328
|
-
const funcRe = new RegExp(`function\\s+${proxyLocal}\\s*\\([^)]*\\)\\s*\\{`);
|
|
4329
|
-
if (funcRe.test(proxyCode)) {
|
|
4330
|
-
const funcStart = proxyCode.search(funcRe);
|
|
4331
|
-
let depth = 0;
|
|
4332
|
-
let funcEnd = funcStart;
|
|
4333
|
-
for (let i = proxyCode.indexOf("{", funcStart); i < proxyCode.length; i++) if (proxyCode[i] === "{") depth++;
|
|
4334
|
-
else if (proxyCode[i] === "}") {
|
|
4335
|
-
depth--;
|
|
4336
|
-
if (depth === 0) {
|
|
4337
|
-
funcEnd = i + 1;
|
|
4338
|
-
break;
|
|
4339
|
-
}
|
|
4340
|
-
}
|
|
4341
|
-
const renamedFunc = proxyCode.slice(funcStart, funcEnd).replace(new RegExp(`function\\s+${proxyLocal}\\s*\\(`), `function ${b.local}(`);
|
|
4342
|
-
inlineable.push({
|
|
4343
|
-
local: b.local,
|
|
4344
|
-
funcBody: renamedFunc
|
|
4345
|
-
});
|
|
4346
|
-
claimedLocals.add(b.local);
|
|
4347
|
-
} else {
|
|
4348
|
-
const unavailableLocals = new Set(claimedLocals);
|
|
4349
|
-
pendingLocals.forEach((local) => unavailableLocals.add(local));
|
|
4350
|
-
const resolvedBinding = resolveProxyAlias(b, proxyLocal, code, fullImport, unavailableLocals);
|
|
4351
|
-
claimedLocals.add(resolvedBinding.local);
|
|
4352
|
-
nonInlineable.push(resolvedBinding);
|
|
4353
|
-
}
|
|
4354
|
-
}
|
|
4355
|
-
const hasRenamedAlias = nonInlineable.some((b) => bindings.find((ob) => ob.imported === b.imported)?.local !== b.local);
|
|
4356
|
-
if (inlineable.length === 0 && !hasRenamedAlias) continue;
|
|
4357
|
-
let replacement = "";
|
|
4358
|
-
if (nonInlineable.length > 0) replacement = `import{${nonInlineable.map((b) => b.imported === b.local ? b.imported : `${b.imported} as ${b.local}`).join(",")}}from"${importMatch[2]}";`;
|
|
4359
|
-
replacement += inlineable.map((f) => f.funcBody).join("");
|
|
4360
|
-
code = code.replace(fullImport, () => replacement);
|
|
4361
|
-
modified = true;
|
|
4728
|
+
const proxyChunks = collectLoadShareProxyChunks(bundle, LOAD_SHARE_TAG);
|
|
4729
|
+
if (proxyChunks.size > 0) {
|
|
4730
|
+
const systemProxyInfo = collectSystemProxyInfos(proxyChunks, LOAD_SHARE_TAG);
|
|
4731
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
4732
|
+
if (!isOutputChunk(chunk)) continue;
|
|
4733
|
+
if (proxyChunks.has(fileName)) continue;
|
|
4734
|
+
let code = chunk.code;
|
|
4735
|
+
if (!fileName.includes("__loadShare__")) code = rewriteEsmProxyConsumers(code, proxyChunks);
|
|
4736
|
+
code = rewriteSystemProxyConsumers(code, systemProxyInfo);
|
|
4737
|
+
if (code !== chunk.code) chunk.code = code;
|
|
4362
4738
|
}
|
|
4363
|
-
if (modified) chunk.code = code;
|
|
4364
4739
|
}
|
|
4365
4740
|
}
|
|
4366
4741
|
},
|
|
@@ -4398,24 +4773,19 @@ function federation(mfUserOptions) {
|
|
|
4398
4773
|
find: "@module-federation/runtime",
|
|
4399
4774
|
replacement: implementation
|
|
4400
4775
|
});
|
|
4401
|
-
config.build
|
|
4402
|
-
|
|
4776
|
+
config.build ||= {};
|
|
4777
|
+
config.build.commonjsOptions ||= {};
|
|
4778
|
+
config.build.commonjsOptions.strictRequires ??= "auto";
|
|
4403
4779
|
config.optimizeDeps ||= {};
|
|
4404
4780
|
config.optimizeDeps.include ||= [];
|
|
4405
4781
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
4406
|
-
config.optimizeDeps.include.push(virtualDir);
|
|
4407
|
-
config.ssr ||= {};
|
|
4408
|
-
config.ssr.noExternal ||= [];
|
|
4409
|
-
if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
|
|
4410
4782
|
options.runtimePlugins.forEach((p) => {
|
|
4411
4783
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
4412
4784
|
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
|
|
4413
4785
|
});
|
|
4414
|
-
if (isRolldown)
|
|
4415
|
-
|
|
4416
|
-
config.
|
|
4417
|
-
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
4418
|
-
config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
|
|
4786
|
+
if (isRolldown) {
|
|
4787
|
+
config.build ??= {};
|
|
4788
|
+
config.build.target ??= "esnext";
|
|
4419
4789
|
}
|
|
4420
4790
|
const isAstro = hasPackageDependency("astro");
|
|
4421
4791
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|