@module-federation/vite 1.11.1 → 1.12.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/lib/index.cjs +404 -127
- package/lib/index.d.cts +7 -0
- package/lib/index.d.mts +7 -0
- package/lib/index.mjs +398 -118
- package/package.json +29 -25
package/lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -7,16 +7,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
9
|
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
20
16
|
}
|
|
21
17
|
return to;
|
|
22
18
|
};
|
|
@@ -24,7 +20,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
20
|
value: mod,
|
|
25
21
|
enumerable: true
|
|
26
22
|
}) : target, mod));
|
|
27
|
-
|
|
28
23
|
//#endregion
|
|
29
24
|
let defu = require("defu");
|
|
30
25
|
defu = __toESM(defu);
|
|
@@ -35,12 +30,11 @@ pathe = __toESM(pathe);
|
|
|
35
30
|
let magic_string = require("magic-string");
|
|
36
31
|
magic_string = __toESM(magic_string);
|
|
37
32
|
let _rollup_pluginutils = require("@rollup/pluginutils");
|
|
38
|
-
let estree_walker = require("estree-walker");
|
|
39
33
|
let _module_federation_sdk = require("@module-federation/sdk");
|
|
40
34
|
let _module_federation_dts_plugin = require("@module-federation/dts-plugin");
|
|
41
35
|
let _module_federation_dts_plugin_core = require("@module-federation/dts-plugin/core");
|
|
36
|
+
let module$1 = require("module");
|
|
42
37
|
let url = require("url");
|
|
43
|
-
|
|
44
38
|
//#region src/utils/mapCodeToCodeWithSourcemap.ts
|
|
45
39
|
async function mapCodeToCodeWithSourcemap(code) {
|
|
46
40
|
const resolvedCode = await code;
|
|
@@ -51,14 +45,14 @@ async function mapCodeToCodeWithSourcemap(code) {
|
|
|
51
45
|
map: s.generateMap({ hires: true })
|
|
52
46
|
};
|
|
53
47
|
}
|
|
54
|
-
|
|
55
48
|
//#endregion
|
|
56
49
|
//#region src/plugins/pluginAddEntry.ts
|
|
57
50
|
function getFirstHtmlEntryFile(entryFiles) {
|
|
58
51
|
return entryFiles.find((file) => file.endsWith(".html"));
|
|
59
52
|
}
|
|
60
53
|
const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
61
|
-
|
|
54
|
+
const getEntryPath = () => typeof entryPath === "function" ? entryPath() : entryPath;
|
|
55
|
+
let devEntryPath = "";
|
|
62
56
|
let entryFiles = [];
|
|
63
57
|
let htmlFilePath;
|
|
64
58
|
let _command;
|
|
@@ -78,6 +72,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
|
78
72
|
},
|
|
79
73
|
configResolved(config) {
|
|
80
74
|
viteConfig = config;
|
|
75
|
+
const resolvedEntryPath = getEntryPath();
|
|
76
|
+
devEntryPath = resolvedEntryPath.startsWith("virtual:mf") ? "@id/" + resolvedEntryPath : resolvedEntryPath;
|
|
81
77
|
devEntryPath = config.base + devEntryPath.replace(/\\\\?/g, "/").replace(/.+?\:([/\\])[/\\]?/, "$1").replace(/^\//, "");
|
|
82
78
|
},
|
|
83
79
|
configureServer(server) {
|
|
@@ -119,7 +115,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
|
119
115
|
const emitFileOptions = {
|
|
120
116
|
name: entryName,
|
|
121
117
|
type: "chunk",
|
|
122
|
-
id:
|
|
118
|
+
id: getEntryPath(),
|
|
123
119
|
preserveSignature: "strict"
|
|
124
120
|
};
|
|
125
121
|
if (!hasHash) emitFileOptions.fileName = fileName;
|
|
@@ -165,12 +161,11 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
|
165
161
|
},
|
|
166
162
|
transform(code, id) {
|
|
167
163
|
if (injectEntry() && entryFiles.some((file) => id.endsWith(file))) return mapCodeToCodeWithSourcemap(`
|
|
168
|
-
import ${JSON.stringify(
|
|
164
|
+
import ${JSON.stringify(getEntryPath())};
|
|
169
165
|
` + code);
|
|
170
166
|
}
|
|
171
167
|
}];
|
|
172
168
|
};
|
|
173
|
-
|
|
174
169
|
//#endregion
|
|
175
170
|
//#region src/plugins/pluginCheckAliasConflicts.ts
|
|
176
171
|
/**
|
|
@@ -210,19 +205,23 @@ function checkAliasConflicts(options) {
|
|
|
210
205
|
}
|
|
211
206
|
};
|
|
212
207
|
}
|
|
213
|
-
|
|
214
208
|
//#endregion
|
|
215
209
|
//#region src/plugins/pluginDevProxyModuleTopLevelAwait.ts
|
|
216
210
|
/**
|
|
217
211
|
* Solve the problem that dev mode dependency prebunding does not support top-level await syntax
|
|
218
212
|
*/
|
|
213
|
+
let walkPromise = null;
|
|
214
|
+
function loadWalk() {
|
|
215
|
+
walkPromise ||= import("estree-walker").then(({ walk }) => walk);
|
|
216
|
+
return walkPromise;
|
|
217
|
+
}
|
|
219
218
|
function PluginDevProxyModuleTopLevelAwait() {
|
|
220
219
|
const filterFunction = (0, _rollup_pluginutils.createFilter)();
|
|
221
220
|
const processedFlag = "/* already-processed-by-dev-proxy-module-top-level-await */";
|
|
222
221
|
return {
|
|
223
222
|
name: "dev-proxy-module-top-level-await",
|
|
224
223
|
apply: "serve",
|
|
225
|
-
transform(code, id) {
|
|
224
|
+
async transform(code, id) {
|
|
226
225
|
if (code.includes(processedFlag)) return null;
|
|
227
226
|
if (!code.includes("/*mf top-level-await placeholder replacement mf*/")) return null;
|
|
228
227
|
if (!filterFunction(id)) return null;
|
|
@@ -233,7 +232,7 @@ function PluginDevProxyModuleTopLevelAwait() {
|
|
|
233
232
|
throw new Error(`${id}: ${e}`);
|
|
234
233
|
}
|
|
235
234
|
const magicString = new magic_string.default(code);
|
|
236
|
-
(
|
|
235
|
+
(await loadWalk())(ast, { enter(node) {
|
|
237
236
|
if (node.type === "ExportNamedDeclaration" && node.specifiers) {
|
|
238
237
|
const exportSpecifiers = node.specifiers.map((specifier) => specifier.exported.name);
|
|
239
238
|
const proxyStatements = exportSpecifiers.map((name) => `
|
|
@@ -275,7 +274,6 @@ function PluginDevProxyModuleTopLevelAwait() {
|
|
|
275
274
|
}
|
|
276
275
|
};
|
|
277
276
|
}
|
|
278
|
-
|
|
279
277
|
//#endregion
|
|
280
278
|
//#region src/plugins/pluginDts.ts
|
|
281
279
|
const DEFAULT_DEV_OPTIONS = {
|
|
@@ -503,7 +501,6 @@ function pluginDts(options) {
|
|
|
503
501
|
}
|
|
504
502
|
}];
|
|
505
503
|
}
|
|
506
|
-
|
|
507
504
|
//#endregion
|
|
508
505
|
//#region src/utils/normalizeModuleFederationOptions.ts
|
|
509
506
|
function normalizeExposesItem(key, item) {
|
|
@@ -670,11 +667,11 @@ function normalizeModuleFederationOptions(options) {
|
|
|
670
667
|
hostInitInjectLocation: options.hostInitInjectLocation || "html",
|
|
671
668
|
bundleAllCSS: options.bundleAllCSS || false,
|
|
672
669
|
moduleParseTimeout: options.moduleParseTimeout || 10,
|
|
670
|
+
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
673
671
|
varFilename: options.varFilename,
|
|
674
672
|
target: options.target
|
|
675
673
|
};
|
|
676
674
|
}
|
|
677
|
-
|
|
678
675
|
//#endregion
|
|
679
676
|
//#region src/utils/packageNameUtils.ts
|
|
680
677
|
/**
|
|
@@ -703,7 +700,6 @@ function packageNameDecode(encoded) {
|
|
|
703
700
|
if (typeof encoded !== "string") throw new Error("A string encoded file name is required");
|
|
704
701
|
return encoded.replace(/_mf_0_/g, "@").replace(/_mf_1_/g, "/").replace(/_mf_2_/g, "-").replace(/_mf_3_/g, ".");
|
|
705
702
|
}
|
|
706
|
-
|
|
707
703
|
//#endregion
|
|
708
704
|
//#region src/utils/localSharedImportMap_temp.ts
|
|
709
705
|
/**
|
|
@@ -720,7 +716,6 @@ function createFile(filePath, content) {
|
|
|
720
716
|
(0, fs.mkdirSync)(pathe.default.dirname(filePath), { recursive: true });
|
|
721
717
|
(0, fs.writeFileSync)(filePath, content);
|
|
722
718
|
}
|
|
723
|
-
|
|
724
719
|
//#endregion
|
|
725
720
|
//#region src/utils/serializeRuntimeOptions.ts
|
|
726
721
|
/**
|
|
@@ -768,9 +763,22 @@ function serializeRuntimeOptions(options) {
|
|
|
768
763
|
for (const key in options) if (Object.prototype.hasOwnProperty.call(options, key)) topLevelProps.push(`${JSON.stringify(key)}: ${valueToCode(options[key])}`);
|
|
769
764
|
return `{${topLevelProps.join(", ")}}`;
|
|
770
765
|
}
|
|
771
|
-
|
|
772
766
|
//#endregion
|
|
773
767
|
//#region src/utils/VirtualModule.ts
|
|
768
|
+
/**
|
|
769
|
+
* Initialize virtual module infrastructure BEFORE VirtualModule class is used.
|
|
770
|
+
* This must be called in the config hook to ensure the directory exists
|
|
771
|
+
* before Vite's optimization phase.
|
|
772
|
+
*/
|
|
773
|
+
function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
|
|
774
|
+
const virtualPackagePath = (0, pathe.join)((0, pathe.join)(root, "node_modules"), virtualModuleDir);
|
|
775
|
+
(0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
|
|
776
|
+
(0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "empty.js"), "");
|
|
777
|
+
(0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "package.json"), JSON.stringify({
|
|
778
|
+
name: virtualModuleDir,
|
|
779
|
+
main: "empty.js"
|
|
780
|
+
}));
|
|
781
|
+
}
|
|
774
782
|
let rootDir;
|
|
775
783
|
function findNodeModulesDir(root = process.cwd()) {
|
|
776
784
|
let currentDir = root;
|
|
@@ -818,14 +826,12 @@ var VirtualModule = class {
|
|
|
818
826
|
const nodeModulesDir = getNodeModulesDir();
|
|
819
827
|
const { virtualModuleDir } = getNormalizeModuleFederationOptions();
|
|
820
828
|
const virtualPackagePath = (0, pathe.resolve)(nodeModulesDir, virtualModuleDir);
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}));
|
|
828
|
-
}
|
|
829
|
+
(0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
|
|
830
|
+
(0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "empty.js"), "");
|
|
831
|
+
(0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "package.json"), JSON.stringify({
|
|
832
|
+
name: virtualModuleDir,
|
|
833
|
+
main: "empty.js"
|
|
834
|
+
}));
|
|
829
835
|
}
|
|
830
836
|
static findModule(tag, str = "") {
|
|
831
837
|
if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
|
|
@@ -856,12 +862,12 @@ var VirtualModule = class {
|
|
|
856
862
|
(0, fs.writeFile)(this.getPath(), code, function() {});
|
|
857
863
|
}
|
|
858
864
|
};
|
|
859
|
-
|
|
860
865
|
//#endregion
|
|
861
866
|
//#region src/virtualModules/virtualExposes.ts
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
867
|
+
function getVirtualExposesId(options) {
|
|
868
|
+
return `virtual:mf-exposes:${`${options.name}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
869
|
+
}
|
|
870
|
+
function generateExposes(options) {
|
|
865
871
|
return `
|
|
866
872
|
export default {
|
|
867
873
|
${Object.keys(options.exposes).map((key) => {
|
|
@@ -881,7 +887,6 @@ function generateExposes() {
|
|
|
881
887
|
}
|
|
882
888
|
`;
|
|
883
889
|
}
|
|
884
|
-
|
|
885
890
|
//#endregion
|
|
886
891
|
//#region src/virtualModules/virtualRuntimeInitStatus.ts
|
|
887
892
|
const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
|
|
@@ -906,15 +911,14 @@ if (!globalThis[globalKey]) {
|
|
|
906
911
|
${exportStatement}
|
|
907
912
|
`);
|
|
908
913
|
}
|
|
909
|
-
|
|
910
914
|
//#endregion
|
|
911
915
|
//#region src/virtualModules/virtualRemotes.ts
|
|
912
916
|
const cacheRemoteMap = {};
|
|
913
917
|
const LOAD_REMOTE_TAG = "__loadRemote__";
|
|
914
|
-
function getRemoteVirtualModule(remote, command) {
|
|
918
|
+
function getRemoteVirtualModule(remote, command, isRolldown) {
|
|
915
919
|
if (!cacheRemoteMap[remote]) {
|
|
916
|
-
cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".js");
|
|
917
|
-
cacheRemoteMap[remote].writeSync(generateRemotes(remote, command));
|
|
920
|
+
cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, isRolldown ? ".mjs" : ".js");
|
|
921
|
+
cacheRemoteMap[remote].writeSync(generateRemotes(remote, command, isRolldown));
|
|
918
922
|
}
|
|
919
923
|
return cacheRemoteMap[remote];
|
|
920
924
|
}
|
|
@@ -926,11 +930,11 @@ function addUsedRemote(remoteKey, remoteModule) {
|
|
|
926
930
|
function getUsedRemotesMap() {
|
|
927
931
|
return usedRemotesMap;
|
|
928
932
|
}
|
|
929
|
-
function generateRemotes(id, command) {
|
|
930
|
-
const
|
|
931
|
-
const importLine =
|
|
932
|
-
const awaitOrPlaceholder =
|
|
933
|
-
const exportLine =
|
|
933
|
+
function generateRemotes(id, command, isRolldown) {
|
|
934
|
+
const useESM = command === "build" || isRolldown;
|
|
935
|
+
const importLine = useESM ? `import { initPromise } from "${virtualRuntimeInitStatus.getImportId()}"` : `const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")`;
|
|
936
|
+
const awaitOrPlaceholder = useESM ? "await " : "/*mf top-level-await placeholder replacement mf*/";
|
|
937
|
+
const exportLine = command === "serve" && useESM ? "export default exportModule.default ?? exportModule" : useESM ? "export default exportModule" : "module.exports = exportModule";
|
|
934
938
|
return `
|
|
935
939
|
${importLine}
|
|
936
940
|
const res = initPromise.then(runtime => runtime.loadRemote(${JSON.stringify(id)}))
|
|
@@ -938,9 +942,26 @@ function generateRemotes(id, command) {
|
|
|
938
942
|
${exportLine}
|
|
939
943
|
`;
|
|
940
944
|
}
|
|
941
|
-
|
|
942
945
|
//#endregion
|
|
943
946
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
947
|
+
/**
|
|
948
|
+
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
949
|
+
* and adding query parameter virtual modules will also fail.
|
|
950
|
+
* You can only proxy to the real file through alias
|
|
951
|
+
*/
|
|
952
|
+
/**
|
|
953
|
+
* shared will be proxied:
|
|
954
|
+
* 1. __prebuild__: export shareModule (pre-built source code of modules such as vue, react, etc.)
|
|
955
|
+
* 2. __loadShare__: load shareModule (mfRuntime.loadShare('vue'))
|
|
956
|
+
*/
|
|
957
|
+
function getPackageNamedExports(pkg) {
|
|
958
|
+
try {
|
|
959
|
+
const mod = (0, module$1.createRequire)(new URL("file://" + process.cwd() + "/package.json"))(pkg);
|
|
960
|
+
return Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule");
|
|
961
|
+
} catch {
|
|
962
|
+
return [];
|
|
963
|
+
}
|
|
964
|
+
}
|
|
944
965
|
const preBuildCacheMap = {};
|
|
945
966
|
const PREBUILD_TAG = "__prebuild__";
|
|
946
967
|
function writePreBuildLibPath(pkg) {
|
|
@@ -953,17 +974,24 @@ function getPreBuildLibImportId(pkg) {
|
|
|
953
974
|
}
|
|
954
975
|
const LOAD_SHARE_TAG = "__loadShare__";
|
|
955
976
|
const loadShareCacheMap = {};
|
|
956
|
-
function getLoadShareModulePath(pkg) {
|
|
957
|
-
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
|
|
977
|
+
function getLoadShareModulePath(pkg, isRolldown, command) {
|
|
978
|
+
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, isRolldown || command === "build" ? ".mjs" : ".js");
|
|
958
979
|
return loadShareCacheMap[pkg].getPath();
|
|
959
980
|
}
|
|
960
|
-
function writeLoadShareModule(pkg, shareItem, command) {
|
|
961
|
-
|
|
962
|
-
const
|
|
963
|
-
const
|
|
964
|
-
const
|
|
981
|
+
function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
|
|
982
|
+
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, isRolldown || command === "build" ? ".mjs" : ".js");
|
|
983
|
+
const useESM = command === "build" || isRolldown;
|
|
984
|
+
const importLine = useESM ? `import { initPromise } from "${virtualRuntimeInitStatus.getImportId()}"` : `const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")`;
|
|
985
|
+
const awaitOrPlaceholder = useESM ? "await " : "/*mf top-level-await placeholder replacement mf*/";
|
|
986
|
+
const namedExports = getPackageNamedExports(pkg);
|
|
987
|
+
let exportLine;
|
|
988
|
+
if (namedExports.length > 0) {
|
|
989
|
+
const destructure = `const { ${namedExports.join(", ")} } = exportModule;`;
|
|
990
|
+
const namedExportLine = `export { ${namedExports.join(", ")} };`;
|
|
991
|
+
exportLine = useESM ? `export default exportModule;\n ${destructure}\n ${namedExportLine}` : `module.exports = exportModule;\n ${destructure}\n Object.assign(module.exports, { ${namedExports.join(", ")} });`;
|
|
992
|
+
} else exportLine = useESM ? `export default exportModule\n export * from ${JSON.stringify(getPreBuildLibImportId(pkg))}` : "module.exports = exportModule";
|
|
965
993
|
loadShareCacheMap[pkg].writeSync(`
|
|
966
|
-
|
|
994
|
+
import ${JSON.stringify(getPreBuildLibImportId(pkg))};
|
|
967
995
|
${command !== "build" ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ""}
|
|
968
996
|
${importLine}
|
|
969
997
|
const res = initPromise.then(runtime => runtime.loadShare(${JSON.stringify(pkg)}, {
|
|
@@ -973,11 +1001,10 @@ function writeLoadShareModule(pkg, shareItem, command) {
|
|
|
973
1001
|
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
|
|
974
1002
|
}}
|
|
975
1003
|
}))
|
|
976
|
-
const exportModule = ${awaitOrPlaceholder}res.then(factory => factory())
|
|
1004
|
+
const exportModule = ${awaitOrPlaceholder}res.then((factory) => (typeof factory === "function" ? factory() : factory))
|
|
977
1005
|
${exportLine}
|
|
978
1006
|
`);
|
|
979
1007
|
}
|
|
980
|
-
|
|
981
1008
|
//#endregion
|
|
982
1009
|
//#region src/virtualModules/virtualRemoteEntry.ts
|
|
983
1010
|
let usedShares = /* @__PURE__ */ new Set();
|
|
@@ -1072,7 +1099,10 @@ function generateLocalSharedImportMap() {
|
|
|
1072
1099
|
`;
|
|
1073
1100
|
}
|
|
1074
1101
|
const REMOTE_ENTRY_ID = "virtual:mf-REMOTE_ENTRY_ID";
|
|
1075
|
-
function
|
|
1102
|
+
function getRemoteEntryId(options) {
|
|
1103
|
+
return `${REMOTE_ENTRY_ID}:${`${options.name}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
1104
|
+
}
|
|
1105
|
+
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options)) {
|
|
1076
1106
|
const pluginImportNames = options.runtimePlugins.map((p, i) => {
|
|
1077
1107
|
if (typeof p === "string") return [
|
|
1078
1108
|
`$runtimePlugin_${i}`,
|
|
@@ -1088,7 +1118,7 @@ function generateRemoteEntry(options) {
|
|
|
1088
1118
|
return `
|
|
1089
1119
|
import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
|
|
1090
1120
|
${pluginImportNames.map((item) => item[1]).join("\n")}
|
|
1091
|
-
import exposesMap from "${
|
|
1121
|
+
import exposesMap from "${virtualExposesId}"
|
|
1092
1122
|
import {usedShared, usedRemotes} from "${getLocalSharedImportMapPath()}"
|
|
1093
1123
|
import {
|
|
1094
1124
|
initResolve
|
|
@@ -1134,15 +1164,10 @@ function generateRemoteEntry(options) {
|
|
|
1134
1164
|
}
|
|
1135
1165
|
`;
|
|
1136
1166
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
* and will not inject remoteEntry
|
|
1140
|
-
*/
|
|
1141
|
-
const HOST_AUTO_INIT_TAG = "__H_A_I__";
|
|
1142
|
-
const hostAutoInitModule = new VirtualModule("hostAutoInit", HOST_AUTO_INIT_TAG);
|
|
1143
|
-
function writeHostAutoInit() {
|
|
1167
|
+
const hostAutoInitModule = new VirtualModule("hostAutoInit", "__H_A_I__");
|
|
1168
|
+
function writeHostAutoInit(remoteEntryId = REMOTE_ENTRY_ID) {
|
|
1144
1169
|
hostAutoInitModule.writeSync(`
|
|
1145
|
-
const remoteEntryPromise = import("${
|
|
1170
|
+
const remoteEntryPromise = import("${remoteEntryId}")
|
|
1146
1171
|
// __tla only serves as a hack for vite-plugin-top-level-await.
|
|
1147
1172
|
Promise.resolve(remoteEntryPromise)
|
|
1148
1173
|
.then(remoteEntry => {
|
|
@@ -1157,21 +1182,18 @@ function getHostAutoInitImportId() {
|
|
|
1157
1182
|
function getHostAutoInitPath() {
|
|
1158
1183
|
return hostAutoInitModule.getPath();
|
|
1159
1184
|
}
|
|
1160
|
-
|
|
1161
1185
|
//#endregion
|
|
1162
1186
|
//#region src/virtualModules/index.ts
|
|
1163
|
-
function initVirtualModules(command) {
|
|
1187
|
+
function initVirtualModules(command, remoteEntryId) {
|
|
1164
1188
|
writeLocalSharedImportMap();
|
|
1165
|
-
writeHostAutoInit();
|
|
1189
|
+
writeHostAutoInit(remoteEntryId);
|
|
1166
1190
|
writeRuntimeInitStatus(command);
|
|
1167
1191
|
}
|
|
1168
|
-
|
|
1169
1192
|
//#endregion
|
|
1170
1193
|
//#region src/utils/bundleHelpers.ts
|
|
1171
1194
|
function findRemoteEntryFile(filename, bundle) {
|
|
1172
1195
|
for (const [_, fileData] of Object.entries(bundle)) if (filename.replace(/[\[\]]/g, "_").replace(/\.[^/.]+$/, "") === fileData.name || fileData.name === "remoteEntry") return fileData.fileName;
|
|
1173
1196
|
}
|
|
1174
|
-
|
|
1175
1197
|
//#endregion
|
|
1176
1198
|
//#region src/utils/cssModuleHelpers.ts
|
|
1177
1199
|
const ASSET_TYPES = ["js", "css"];
|
|
@@ -1292,7 +1314,6 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
|
|
|
1292
1314
|
for (const resolution of resolutions) if (resolution?.file) fileToShareKey.set(resolution.file, resolution.shareKey);
|
|
1293
1315
|
return fileToShareKey;
|
|
1294
1316
|
};
|
|
1295
|
-
|
|
1296
1317
|
//#endregion
|
|
1297
1318
|
//#region src/utils/publicPath.ts
|
|
1298
1319
|
/**
|
|
@@ -1308,7 +1329,6 @@ function resolvePublicPath(options, viteBase, originalBase) {
|
|
|
1308
1329
|
if (viteBase) return viteBase.replace(/\/?$/, "/");
|
|
1309
1330
|
return "auto";
|
|
1310
1331
|
}
|
|
1311
|
-
|
|
1312
1332
|
//#endregion
|
|
1313
1333
|
//#region src/plugins/pluginMFManifest.ts
|
|
1314
1334
|
const Manifest = () => {
|
|
@@ -1523,7 +1543,6 @@ const Manifest = () => {
|
|
|
1523
1543
|
};
|
|
1524
1544
|
}
|
|
1525
1545
|
};
|
|
1526
|
-
|
|
1527
1546
|
//#endregion
|
|
1528
1547
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
1529
1548
|
let _resolve, _parseTimeout;
|
|
@@ -1540,12 +1559,19 @@ function setParseTimeout(timeout) {
|
|
|
1540
1559
|
_resolve(1);
|
|
1541
1560
|
}, timeout * 1e3);
|
|
1542
1561
|
}
|
|
1562
|
+
function resetIdleTimeout(timeout) {
|
|
1563
|
+
clearTimeout(_parseTimeout);
|
|
1564
|
+
_parseTimeout = setTimeout(() => {
|
|
1565
|
+
console.warn(`moduleParseIdleTimeout: no module activity for ${timeout}s, forcing resolve. Some shared/remote dependencies may be missing. Consider increasing moduleParseIdleTimeout.`);
|
|
1566
|
+
_resolve(1);
|
|
1567
|
+
}, timeout * 1e3);
|
|
1568
|
+
}
|
|
1543
1569
|
let parsePromise = promise;
|
|
1544
1570
|
let exposesParseEnd = false;
|
|
1545
1571
|
const parseStartSet = /* @__PURE__ */ new Set();
|
|
1546
1572
|
const parseEndSet = /* @__PURE__ */ new Set();
|
|
1547
1573
|
function pluginModuleParseEnd_default(excludeFn, options) {
|
|
1548
|
-
|
|
1574
|
+
const idleTimeout = options.moduleParseIdleTimeout;
|
|
1549
1575
|
return [
|
|
1550
1576
|
{
|
|
1551
1577
|
name: "_",
|
|
@@ -1558,6 +1584,10 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
1558
1584
|
enforce: "pre",
|
|
1559
1585
|
name: "parseStart",
|
|
1560
1586
|
apply: "build",
|
|
1587
|
+
buildStart() {
|
|
1588
|
+
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
1589
|
+
else setParseTimeout(options.moduleParseTimeout);
|
|
1590
|
+
},
|
|
1561
1591
|
load(id) {
|
|
1562
1592
|
if (excludeFn(id)) return;
|
|
1563
1593
|
parseStartSet.add(id);
|
|
@@ -1569,7 +1599,8 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
1569
1599
|
apply: "build",
|
|
1570
1600
|
moduleParsed(module) {
|
|
1571
1601
|
const id = module.id;
|
|
1572
|
-
if (id ===
|
|
1602
|
+
if (id === options.virtualExposesId) exposesParseEnd = true;
|
|
1603
|
+
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
1573
1604
|
if (excludeFn(id)) return;
|
|
1574
1605
|
parseEndSet.add(id);
|
|
1575
1606
|
if (exposesParseEnd && parseStartSet.size === parseEndSet.size) _resolve(1);
|
|
@@ -1577,11 +1608,10 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
1577
1608
|
}
|
|
1578
1609
|
];
|
|
1579
1610
|
}
|
|
1580
|
-
|
|
1581
1611
|
//#endregion
|
|
1582
1612
|
//#region src/plugins/pluginProxyRemoteEntry.ts
|
|
1583
1613
|
const filter = (0, _rollup_pluginutils.createFilter)();
|
|
1584
|
-
function pluginProxyRemoteEntry_default() {
|
|
1614
|
+
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
1585
1615
|
let viteConfig, _command;
|
|
1586
1616
|
return {
|
|
1587
1617
|
name: "proxyRemoteEntry",
|
|
@@ -1592,28 +1622,37 @@ function pluginProxyRemoteEntry_default() {
|
|
|
1592
1622
|
config(config, { command }) {
|
|
1593
1623
|
_command = command;
|
|
1594
1624
|
},
|
|
1625
|
+
async buildStart() {
|
|
1626
|
+
if (_command !== "build") return;
|
|
1627
|
+
for (const expose of Object.values(options.exposes)) {
|
|
1628
|
+
const resolved = await this.resolve(expose.import);
|
|
1629
|
+
if (resolved) this.emitFile({
|
|
1630
|
+
type: "chunk",
|
|
1631
|
+
id: resolved.id
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
},
|
|
1595
1635
|
async resolveId(id, importer) {
|
|
1596
|
-
if (id ===
|
|
1597
|
-
if (id ===
|
|
1636
|
+
if (id === remoteEntryId) return remoteEntryId;
|
|
1637
|
+
if (id === virtualExposesId) return virtualExposesId;
|
|
1598
1638
|
if (_command === "serve" && id.includes(getHostAutoInitPath())) return id;
|
|
1599
|
-
if (importer ===
|
|
1600
|
-
typeof __filename === "string" ? __filename : (0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
1601
|
-
const resolved = await this.resolve(id,
|
|
1639
|
+
if (importer === remoteEntryId && !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\0") && !id.startsWith("virtual:")) {
|
|
1640
|
+
const importPath = typeof __filename === "string" ? __filename : (0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
1641
|
+
const resolved = await this.resolve(id, importPath, { skipSelf: true });
|
|
1602
1642
|
if (resolved) return resolved;
|
|
1603
1643
|
}
|
|
1604
1644
|
},
|
|
1605
1645
|
load(id) {
|
|
1606
|
-
if (id ===
|
|
1607
|
-
if (id ===
|
|
1646
|
+
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId));
|
|
1647
|
+
if (id === virtualExposesId) return generateExposes(options);
|
|
1608
1648
|
if (_command === "serve" && id.includes(getHostAutoInitPath())) return id;
|
|
1609
1649
|
},
|
|
1610
1650
|
transform(code, id) {
|
|
1611
1651
|
return mapCodeToCodeWithSourcemap((() => {
|
|
1612
1652
|
if (!filter(id)) return;
|
|
1613
|
-
if (id.includes(
|
|
1614
|
-
if (id ===
|
|
1653
|
+
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId));
|
|
1654
|
+
if (id === virtualExposesId) return generateExposes(options);
|
|
1615
1655
|
if (id.includes(getHostAutoInitPath())) {
|
|
1616
|
-
const options = getNormalizeModuleFederationOptions();
|
|
1617
1656
|
if (_command === "serve") {
|
|
1618
1657
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
1619
1658
|
const publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
|
|
@@ -1634,7 +1673,6 @@ function pluginProxyRemoteEntry_default() {
|
|
|
1634
1673
|
}
|
|
1635
1674
|
};
|
|
1636
1675
|
}
|
|
1637
|
-
|
|
1638
1676
|
//#endregion
|
|
1639
1677
|
//#region src/plugins/pluginProxyRemotes.ts
|
|
1640
1678
|
(0, _rollup_pluginutils.createFilter)();
|
|
@@ -1643,13 +1681,14 @@ function pluginProxyRemotes_default(options) {
|
|
|
1643
1681
|
return {
|
|
1644
1682
|
name: "proxyRemotes",
|
|
1645
1683
|
config(config, { command: _command }) {
|
|
1684
|
+
const isRolldown = !!this?.meta?.rolldownVersion;
|
|
1646
1685
|
Object.keys(remotes).forEach((key) => {
|
|
1647
1686
|
const remote = remotes[key];
|
|
1648
1687
|
config.resolve.alias.push({
|
|
1649
1688
|
find: new RegExp(`^(${remote.name}(\/.*|$))`),
|
|
1650
1689
|
replacement: "$1",
|
|
1651
1690
|
customResolver(source) {
|
|
1652
|
-
const remoteModule = getRemoteVirtualModule(source, _command);
|
|
1691
|
+
const remoteModule = getRemoteVirtualModule(source, _command, isRolldown);
|
|
1653
1692
|
addUsedRemote(remote.name, source);
|
|
1654
1693
|
return remoteModule.getPath();
|
|
1655
1694
|
}
|
|
@@ -1658,7 +1697,6 @@ function pluginProxyRemotes_default(options) {
|
|
|
1658
1697
|
}
|
|
1659
1698
|
};
|
|
1660
1699
|
}
|
|
1661
|
-
|
|
1662
1700
|
//#endregion
|
|
1663
1701
|
//#region src/utils/PromiseStore.ts
|
|
1664
1702
|
/**
|
|
@@ -1692,12 +1730,13 @@ var PromiseStore = class {
|
|
|
1692
1730
|
return pendingPromise;
|
|
1693
1731
|
}
|
|
1694
1732
|
};
|
|
1695
|
-
|
|
1696
1733
|
//#endregion
|
|
1697
1734
|
//#region src/plugins/pluginProxySharedModule_preBuild.ts
|
|
1698
1735
|
function proxySharedModule(options) {
|
|
1699
|
-
|
|
1736
|
+
const { shared = {} } = options;
|
|
1700
1737
|
let _config;
|
|
1738
|
+
let _command = "serve";
|
|
1739
|
+
const savePrebuild = new PromiseStore();
|
|
1701
1740
|
return [{
|
|
1702
1741
|
name: "generateLocalSharedImportMap",
|
|
1703
1742
|
enforce: "post",
|
|
@@ -1710,19 +1749,23 @@ function proxySharedModule(options) {
|
|
|
1710
1749
|
}, {
|
|
1711
1750
|
name: "proxyPreBuildShared",
|
|
1712
1751
|
enforce: "post",
|
|
1713
|
-
configResolved(config) {
|
|
1714
|
-
_config = config;
|
|
1715
|
-
},
|
|
1716
1752
|
config(config, { command }) {
|
|
1753
|
+
const isRolldown = !!this?.meta?.rolldownVersion;
|
|
1754
|
+
_command = command;
|
|
1717
1755
|
config.resolve.alias.push(...Object.keys(shared).map((key) => {
|
|
1718
|
-
const
|
|
1756
|
+
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
1757
|
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1758
|
+
const escapedKeyBase = escapeRegex(keyBase);
|
|
1759
|
+
const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
|
|
1719
1760
|
return {
|
|
1720
1761
|
find: new RegExp(pattern),
|
|
1721
1762
|
replacement: "$1",
|
|
1722
1763
|
customResolver(source, importer) {
|
|
1723
1764
|
if (/\.css$/.test(source)) return;
|
|
1724
|
-
|
|
1725
|
-
|
|
1765
|
+
if (importer && importer.includes("localSharedImportMap")) return;
|
|
1766
|
+
if (key.endsWith("/") && source !== key.slice(0, -1)) return;
|
|
1767
|
+
const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
|
|
1768
|
+
writeLoadShareModule(source, shared[key], command, isRolldown);
|
|
1726
1769
|
writePreBuildLibPath(source);
|
|
1727
1770
|
addUsedShares(source);
|
|
1728
1771
|
writeLocalSharedImportMap();
|
|
@@ -1730,7 +1773,6 @@ function proxySharedModule(options) {
|
|
|
1730
1773
|
}
|
|
1731
1774
|
};
|
|
1732
1775
|
}));
|
|
1733
|
-
const savePrebuild = new PromiseStore();
|
|
1734
1776
|
config.resolve.alias.push(...Object.keys(shared).map((key) => {
|
|
1735
1777
|
return command === "build" ? {
|
|
1736
1778
|
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
@@ -1743,15 +1785,25 @@ function proxySharedModule(options) {
|
|
|
1743
1785
|
async customResolver(source, importer) {
|
|
1744
1786
|
const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
|
|
1745
1787
|
const result = await this.resolve(pkgName, importer).then((item) => item.id);
|
|
1746
|
-
if (!result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
1788
|
+
if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
1747
1789
|
return await this.resolve(await savePrebuild.get(pkgName), importer);
|
|
1748
1790
|
}
|
|
1749
1791
|
};
|
|
1750
1792
|
}));
|
|
1793
|
+
},
|
|
1794
|
+
configResolved(config) {
|
|
1795
|
+
_config = config;
|
|
1796
|
+
const isRolldown = !!config.experimental?.rolldownDev;
|
|
1797
|
+
Object.keys(shared).forEach((key) => {
|
|
1798
|
+
if (key.endsWith("/")) return;
|
|
1799
|
+
writeLoadShareModule(key, shared[key], _command, isRolldown);
|
|
1800
|
+
writePreBuildLibPath(key);
|
|
1801
|
+
addUsedShares(key);
|
|
1802
|
+
});
|
|
1803
|
+
writeLocalSharedImportMap();
|
|
1751
1804
|
}
|
|
1752
1805
|
}];
|
|
1753
1806
|
}
|
|
1754
|
-
|
|
1755
1807
|
//#endregion
|
|
1756
1808
|
//#region src/plugins/pluginVarRemoteEntry.ts
|
|
1757
1809
|
const VarRemoteEntry = () => {
|
|
@@ -1832,7 +1884,6 @@ const VarRemoteEntry = () => {
|
|
|
1832
1884
|
`;
|
|
1833
1885
|
}
|
|
1834
1886
|
};
|
|
1835
|
-
|
|
1836
1887
|
//#endregion
|
|
1837
1888
|
//#region src/utils/aliasToArrayPlugin.ts
|
|
1838
1889
|
var aliasToArrayPlugin_default = {
|
|
@@ -1847,7 +1898,6 @@ var aliasToArrayPlugin_default = {
|
|
|
1847
1898
|
}));
|
|
1848
1899
|
}
|
|
1849
1900
|
};
|
|
1850
|
-
|
|
1851
1901
|
//#endregion
|
|
1852
1902
|
//#region src/utils/normalizeOptimizeDeps.ts
|
|
1853
1903
|
var normalizeOptimizeDeps_default = {
|
|
@@ -1858,20 +1908,59 @@ var normalizeOptimizeDeps_default = {
|
|
|
1858
1908
|
config.optimizeDeps = {};
|
|
1859
1909
|
optimizeDeps = config.optimizeDeps;
|
|
1860
1910
|
}
|
|
1861
|
-
optimizeDeps.force = true;
|
|
1862
1911
|
if (!optimizeDeps.include) optimizeDeps.include = [];
|
|
1912
|
+
if (!optimizeDeps.exclude) optimizeDeps.exclude = [];
|
|
1863
1913
|
if (!optimizeDeps.needsInterop) optimizeDeps.needsInterop = [];
|
|
1864
1914
|
}
|
|
1865
1915
|
};
|
|
1866
|
-
|
|
1867
1916
|
//#endregion
|
|
1868
1917
|
//#region src/index.ts
|
|
1918
|
+
/**
|
|
1919
|
+
* Plugin that runs FIRST to create virtual module files in the config hook.
|
|
1920
|
+
* This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
|
|
1921
|
+
* before Vite's optimization phase.
|
|
1922
|
+
*/
|
|
1923
|
+
function createEarlyVirtualModulesPlugin(options) {
|
|
1924
|
+
const { shared, remotes, virtualModuleDir } = options;
|
|
1925
|
+
return {
|
|
1926
|
+
name: "vite:module-federation-early-init",
|
|
1927
|
+
enforce: "pre",
|
|
1928
|
+
config(config, { command: _command }) {
|
|
1929
|
+
if (_command !== "serve") return;
|
|
1930
|
+
const isRolldown = !!this?.meta?.rolldownVersion;
|
|
1931
|
+
const root = config.root || process.cwd();
|
|
1932
|
+
initVirtualModuleInfrastructure(root, virtualModuleDir);
|
|
1933
|
+
VirtualModule.setRoot(root);
|
|
1934
|
+
VirtualModule.ensureVirtualPackageExists();
|
|
1935
|
+
initVirtualModules(_command, getRemoteEntryId(options));
|
|
1936
|
+
if (remotes && Object.keys(remotes).length > 0) for (const key of Object.keys(remotes)) addUsedRemote(key, key);
|
|
1937
|
+
if (shared && Object.keys(shared).length > 0) {
|
|
1938
|
+
config.optimizeDeps = config.optimizeDeps || {};
|
|
1939
|
+
config.optimizeDeps.include = config.optimizeDeps.include || [];
|
|
1940
|
+
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
1941
|
+
for (const key of Object.keys(shared)) {
|
|
1942
|
+
if (key.endsWith("/")) continue;
|
|
1943
|
+
const shareItem = shared[key];
|
|
1944
|
+
getLoadShareModulePath(key, isRolldown);
|
|
1945
|
+
writeLoadShareModule(key, shareItem, _command, isRolldown);
|
|
1946
|
+
writePreBuildLibPath(key);
|
|
1947
|
+
addUsedShares(key);
|
|
1948
|
+
config.optimizeDeps.include.push(getPreBuildLibImportId(key));
|
|
1949
|
+
}
|
|
1950
|
+
writeLocalSharedImportMap();
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1869
1955
|
function federation(mfUserOptions) {
|
|
1870
1956
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
1871
1957
|
const { name, remotes, shared, filename, hostInitInjectLocation } = options;
|
|
1872
1958
|
if (!name) throw new Error("name is required");
|
|
1959
|
+
const remoteEntryId = getRemoteEntryId(options);
|
|
1960
|
+
const virtualExposesId = getVirtualExposesId(options);
|
|
1873
1961
|
let command;
|
|
1874
1962
|
return [
|
|
1963
|
+
createEarlyVirtualModulesPlugin(options),
|
|
1875
1964
|
{
|
|
1876
1965
|
name: "vite:module-federation-config",
|
|
1877
1966
|
enforce: "pre",
|
|
@@ -1881,7 +1970,7 @@ function federation(mfUserOptions) {
|
|
|
1881
1970
|
configResolved(config) {
|
|
1882
1971
|
VirtualModule.setRoot(config.root);
|
|
1883
1972
|
VirtualModule.ensureVirtualPackageExists();
|
|
1884
|
-
initVirtualModules(command);
|
|
1973
|
+
initVirtualModules(command, remoteEntryId);
|
|
1885
1974
|
}
|
|
1886
1975
|
},
|
|
1887
1976
|
aliasToArrayPlugin_default,
|
|
@@ -1890,32 +1979,62 @@ function federation(mfUserOptions) {
|
|
|
1890
1979
|
...pluginDts(options),
|
|
1891
1980
|
...addEntry({
|
|
1892
1981
|
entryName: "remoteEntry",
|
|
1893
|
-
entryPath:
|
|
1982
|
+
entryPath: remoteEntryId,
|
|
1894
1983
|
fileName: filename
|
|
1895
1984
|
}),
|
|
1896
1985
|
...addEntry({
|
|
1897
1986
|
entryName: "hostInit",
|
|
1898
|
-
entryPath: getHostAutoInitPath(),
|
|
1987
|
+
entryPath: () => getHostAutoInitPath(),
|
|
1899
1988
|
inject: hostInitInjectLocation
|
|
1900
1989
|
}),
|
|
1901
1990
|
...addEntry({
|
|
1902
1991
|
entryName: "virtualExposes",
|
|
1903
|
-
entryPath:
|
|
1992
|
+
entryPath: virtualExposesId
|
|
1993
|
+
}),
|
|
1994
|
+
pluginProxyRemoteEntry_default({
|
|
1995
|
+
options,
|
|
1996
|
+
remoteEntryId,
|
|
1997
|
+
virtualExposesId
|
|
1904
1998
|
}),
|
|
1905
|
-
pluginProxyRemoteEntry_default(),
|
|
1906
1999
|
pluginProxyRemotes_default(options),
|
|
1907
2000
|
...pluginModuleParseEnd_default((id) => {
|
|
1908
|
-
return id.includes(getHostAutoInitImportId()) || id.includes(
|
|
1909
|
-
}, {
|
|
2001
|
+
return id.includes(getHostAutoInitImportId()) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes(getLocalSharedImportMapPath());
|
|
2002
|
+
}, {
|
|
2003
|
+
moduleParseTimeout: options.moduleParseTimeout,
|
|
2004
|
+
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
2005
|
+
virtualExposesId
|
|
2006
|
+
}),
|
|
1910
2007
|
...proxySharedModule({ shared }),
|
|
1911
2008
|
{
|
|
1912
2009
|
name: "module-federation-esm-shims",
|
|
1913
2010
|
enforce: "pre",
|
|
1914
2011
|
apply: "build",
|
|
2012
|
+
config(config) {
|
|
2013
|
+
const runtimeInitId = virtualRuntimeInitStatus.getImportId();
|
|
2014
|
+
config.build = config.build || {};
|
|
2015
|
+
config.build.rollupOptions = config.build.rollupOptions || {};
|
|
2016
|
+
if (!Array.isArray(config.build.rollupOptions.output)) {
|
|
2017
|
+
const output = config.build.rollupOptions.output ||= {};
|
|
2018
|
+
const existingManualChunks = output.manualChunks;
|
|
2019
|
+
output.manualChunks = function(id) {
|
|
2020
|
+
if (id.includes(runtimeInitId)) return "runtimeInit";
|
|
2021
|
+
if (id.includes("__loadShare__")) {
|
|
2022
|
+
const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
|
|
2023
|
+
return match ? match[1] : "loadShare";
|
|
2024
|
+
}
|
|
2025
|
+
if (typeof existingManualChunks === "function") return existingManualChunks.apply(this, arguments);
|
|
2026
|
+
if (existingManualChunks && typeof existingManualChunks === "object") {
|
|
2027
|
+
for (const [key, ids] of Object.entries(existingManualChunks)) if (Array.isArray(ids) && ids.some((v) => id.includes(v))) return key;
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
},
|
|
1915
2032
|
load(id) {
|
|
1916
2033
|
if (id.startsWith("\0")) return;
|
|
1917
|
-
if (id.includes(
|
|
2034
|
+
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
1918
2035
|
let code = (0, fs.readFileSync)(id, "utf-8");
|
|
2036
|
+
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
2037
|
+
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
1919
2038
|
/**
|
|
1920
2039
|
* Shared/remote shims only have `export default exportModule`.
|
|
1921
2040
|
*
|
|
@@ -1938,6 +2057,134 @@ function federation(mfUserOptions) {
|
|
|
1938
2057
|
syntheticNamedExports: "__moduleExports"
|
|
1939
2058
|
};
|
|
1940
2059
|
}
|
|
2060
|
+
},
|
|
2061
|
+
generateBundle(_, bundle) {
|
|
2062
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2063
|
+
if (chunk.type !== "chunk") continue;
|
|
2064
|
+
if (fileName.includes("__loadShare__")) continue;
|
|
2065
|
+
let code = chunk.code;
|
|
2066
|
+
let m;
|
|
2067
|
+
const importedFromLoadShare = /* @__PURE__ */ new Set();
|
|
2068
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["'][^"']*__loadShare__[^"']*["']/g;
|
|
2069
|
+
while ((m = importRegex.exec(code)) !== null) for (const spec of m[1].split(",")) {
|
|
2070
|
+
const parts = spec.trim().split(/\s+as\s+/);
|
|
2071
|
+
const local = (parts[1] || parts[0]).trim();
|
|
2072
|
+
if (local) importedFromLoadShare.add(local);
|
|
2073
|
+
}
|
|
2074
|
+
const allInits = [];
|
|
2075
|
+
for (const v of importedFromLoadShare) if (new RegExp("\\(" + v + "\\(\\)\\s*,\\s*\\w+\\(\\w+\\)\\)").test(code)) allInits.push(v);
|
|
2076
|
+
if (allInits.length === 0) continue;
|
|
2077
|
+
const awaits = allInits.map((v) => `await ${v}();`).join("");
|
|
2078
|
+
const lastFromRegex = /\bfrom\s*["'][^"']*["']\s*;?/g;
|
|
2079
|
+
let lastFromEnd = -1;
|
|
2080
|
+
while ((m = lastFromRegex.exec(code)) !== null) lastFromEnd = m.index + m[0].length;
|
|
2081
|
+
if (lastFromEnd !== -1) {
|
|
2082
|
+
chunk.code = code.slice(0, lastFromEnd) + awaits + code.slice(lastFromEnd);
|
|
2083
|
+
continue;
|
|
2084
|
+
}
|
|
2085
|
+
const exportIdx = code.search(/\bexport\s*[{d]/);
|
|
2086
|
+
if (exportIdx !== -1) {
|
|
2087
|
+
chunk.code = code.slice(0, exportIdx) + awaits + code.slice(exportIdx);
|
|
2088
|
+
continue;
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
const proxyChunks = /* @__PURE__ */ new Map();
|
|
2092
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2093
|
+
if (chunk.type !== "chunk") continue;
|
|
2094
|
+
if (fileName.includes("__loadShare__") && fileName.includes("commonjs-proxy")) proxyChunks.set(fileName, {
|
|
2095
|
+
code: chunk.code,
|
|
2096
|
+
fileName
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
if (proxyChunks.size === 0) return;
|
|
2100
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2101
|
+
if (chunk.type !== "chunk") continue;
|
|
2102
|
+
if (fileName.includes("__loadShare__")) continue;
|
|
2103
|
+
let code = chunk.code;
|
|
2104
|
+
let modified = false;
|
|
2105
|
+
for (const [proxyFileName, proxyInfo] of proxyChunks) {
|
|
2106
|
+
const proxyBaseName = proxyFileName.replace(/^.*\//, "").replace(/\.js$/, "").replace(/-[A-Za-z0-9_-]+$/, "");
|
|
2107
|
+
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${proxyBaseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^"']*)["']\\s*;?`).exec(code);
|
|
2108
|
+
if (!importMatch) continue;
|
|
2109
|
+
const fullImport = importMatch[0];
|
|
2110
|
+
const bindings = importMatch[1].split(",").map((s) => {
|
|
2111
|
+
const parts = s.trim().split(/\s+as\s+/);
|
|
2112
|
+
return {
|
|
2113
|
+
imported: parts[0].trim(),
|
|
2114
|
+
local: (parts[1] || parts[0]).trim()
|
|
2115
|
+
};
|
|
2116
|
+
});
|
|
2117
|
+
const proxyCode = proxyInfo.code;
|
|
2118
|
+
const exportMapMatch = proxyCode.match(/export\s*\{([^}]+)\}/);
|
|
2119
|
+
if (!exportMapMatch) continue;
|
|
2120
|
+
const exportMap = {};
|
|
2121
|
+
for (const entry of exportMapMatch[1].split(",")) {
|
|
2122
|
+
const parts = entry.trim().split(/\s+as\s+/);
|
|
2123
|
+
if (parts.length === 2) exportMap[parts[1].trim()] = parts[0].trim();
|
|
2124
|
+
}
|
|
2125
|
+
const inlineable = [];
|
|
2126
|
+
const nonInlineable = [];
|
|
2127
|
+
for (const b of bindings) {
|
|
2128
|
+
const proxyLocal = exportMap[b.imported];
|
|
2129
|
+
if (!proxyLocal) {
|
|
2130
|
+
nonInlineable.push(b);
|
|
2131
|
+
continue;
|
|
2132
|
+
}
|
|
2133
|
+
const funcRe = new RegExp(`function\\s+${proxyLocal}\\s*\\([^)]*\\)\\s*\\{`);
|
|
2134
|
+
if (funcRe.test(proxyCode)) {
|
|
2135
|
+
const funcStart = proxyCode.search(funcRe);
|
|
2136
|
+
let depth = 0;
|
|
2137
|
+
let funcEnd = funcStart;
|
|
2138
|
+
for (let i = proxyCode.indexOf("{", funcStart); i < proxyCode.length; i++) if (proxyCode[i] === "{") depth++;
|
|
2139
|
+
else if (proxyCode[i] === "}") {
|
|
2140
|
+
depth--;
|
|
2141
|
+
if (depth === 0) {
|
|
2142
|
+
funcEnd = i + 1;
|
|
2143
|
+
break;
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
const renamedFunc = proxyCode.slice(funcStart, funcEnd).replace(new RegExp(`function\\s+${proxyLocal}\\s*\\(`), `function ${b.local}(`);
|
|
2147
|
+
inlineable.push({
|
|
2148
|
+
local: b.local,
|
|
2149
|
+
funcBody: renamedFunc
|
|
2150
|
+
});
|
|
2151
|
+
} else nonInlineable.push(b);
|
|
2152
|
+
}
|
|
2153
|
+
if (inlineable.length === 0) continue;
|
|
2154
|
+
let replacement = "";
|
|
2155
|
+
if (nonInlineable.length > 0) replacement = `import{${nonInlineable.map((b) => b.imported === b.local ? b.imported : `${b.imported} as ${b.local}`).join(",")}}from"${importMatch[2]}";`;
|
|
2156
|
+
replacement += inlineable.map((f) => f.funcBody).join("");
|
|
2157
|
+
code = code.replace(fullImport, replacement);
|
|
2158
|
+
modified = true;
|
|
2159
|
+
}
|
|
2160
|
+
if (modified) chunk.code = code;
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
},
|
|
2164
|
+
{
|
|
2165
|
+
name: "module-federation-dev-await-shared-init",
|
|
2166
|
+
apply: "serve",
|
|
2167
|
+
enforce: "post",
|
|
2168
|
+
transform(code, id) {
|
|
2169
|
+
if (!id.includes(".vite/deps/")) return;
|
|
2170
|
+
const initPattern = /\b(init_\w+__loadShare__\w+)\b/g;
|
|
2171
|
+
const initFns = /* @__PURE__ */ new Set();
|
|
2172
|
+
let match;
|
|
2173
|
+
while ((match = initPattern.exec(code)) !== null) initFns.add(match[1]);
|
|
2174
|
+
if (initFns.size === 0) return;
|
|
2175
|
+
if (![...initFns].some((fn) => {
|
|
2176
|
+
return code.includes(`${fn}(),`) || code.includes(`${fn}()`);
|
|
2177
|
+
})) return;
|
|
2178
|
+
if (/await\s+init_\w+__loadShare__/.test(code)) return;
|
|
2179
|
+
if (code.includes("__esmMin")) return;
|
|
2180
|
+
const awaits = [...initFns].map((fn) => `await ${fn}();`).join("\n");
|
|
2181
|
+
const topLevelImportRe = /^import\s/gm;
|
|
2182
|
+
let lastImportIdx = -1;
|
|
2183
|
+
let importMatch;
|
|
2184
|
+
while ((importMatch = topLevelImportRe.exec(code)) !== null) lastImportIdx = importMatch.index;
|
|
2185
|
+
if (lastImportIdx === -1) return;
|
|
2186
|
+
const lineEnd = code.indexOf("\n", lastImportIdx);
|
|
2187
|
+
return code.slice(0, lineEnd + 1) + awaits + "\n" + code.slice(lineEnd + 1);
|
|
1941
2188
|
}
|
|
1942
2189
|
},
|
|
1943
2190
|
PluginDevProxyModuleTopLevelAwait(),
|
|
@@ -1946,16 +2193,29 @@ function federation(mfUserOptions) {
|
|
|
1946
2193
|
enforce: "post",
|
|
1947
2194
|
_options: options,
|
|
1948
2195
|
config(config, { command: _command }) {
|
|
2196
|
+
const isRolldown = !!this?.meta?.rolldownVersion;
|
|
2197
|
+
let implementation = options.implementation;
|
|
2198
|
+
if (isRolldown) implementation = implementation.replace(/\.cjs\.cjs$/, ".esm.js");
|
|
1949
2199
|
config.resolve.alias.push({
|
|
1950
2200
|
find: "@module-federation/runtime",
|
|
1951
|
-
replacement:
|
|
2201
|
+
replacement: implementation
|
|
1952
2202
|
});
|
|
1953
2203
|
config.build = (0, defu.default)(config.build || {}, { commonjsOptions: { strictRequires: "auto" } });
|
|
1954
2204
|
const virtualDir = options.virtualModuleDir || "__mf__virtual";
|
|
1955
|
-
config.optimizeDeps
|
|
1956
|
-
config.optimizeDeps
|
|
1957
|
-
config.optimizeDeps
|
|
1958
|
-
config.optimizeDeps
|
|
2205
|
+
config.optimizeDeps ||= {};
|
|
2206
|
+
config.optimizeDeps.include ||= [];
|
|
2207
|
+
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
2208
|
+
config.optimizeDeps.include.push(virtualDir);
|
|
2209
|
+
options.runtimePlugins.forEach((p) => {
|
|
2210
|
+
const pluginPath = typeof p === "string" ? p : p[0];
|
|
2211
|
+
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
|
|
2212
|
+
});
|
|
2213
|
+
if (isRolldown) config.build = (0, defu.default)(config.build || {}, { target: "esnext" });
|
|
2214
|
+
else {
|
|
2215
|
+
config.optimizeDeps.needsInterop ||= [];
|
|
2216
|
+
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
2217
|
+
config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
|
|
2218
|
+
}
|
|
1959
2219
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
|
1960
2220
|
if (!config.define) config.define = {};
|
|
1961
2221
|
if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = JSON.stringify(resolvedTarget);
|
|
@@ -1963,9 +2223,26 @@ function federation(mfUserOptions) {
|
|
|
1963
2223
|
}
|
|
1964
2224
|
},
|
|
1965
2225
|
...Manifest(),
|
|
1966
|
-
...VarRemoteEntry()
|
|
2226
|
+
...VarRemoteEntry(),
|
|
2227
|
+
...Object.keys(options.exposes).length > 0 ? [{
|
|
2228
|
+
name: "module-federation-fix-preload",
|
|
2229
|
+
enforce: "post",
|
|
2230
|
+
apply: "build",
|
|
2231
|
+
generateBundle(_, bundle) {
|
|
2232
|
+
for (const chunk of Object.values(bundle)) {
|
|
2233
|
+
if (chunk.type !== "chunk") continue;
|
|
2234
|
+
if (!chunk.code.includes("modulepreload")) continue;
|
|
2235
|
+
const replacement = "=function($1){return new URL(\"../\"+$1,import.meta.url).href}";
|
|
2236
|
+
const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
|
|
2237
|
+
if (replaced !== chunk.code) {
|
|
2238
|
+
chunk.code = replaced;
|
|
2239
|
+
continue;
|
|
2240
|
+
}
|
|
2241
|
+
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
}] : []
|
|
1967
2245
|
];
|
|
1968
2246
|
}
|
|
1969
|
-
|
|
1970
2247
|
//#endregion
|
|
1971
|
-
exports.federation = federation;
|
|
2248
|
+
exports.federation = federation;
|