@module-federation/vite 1.19.1 → 1.20.0
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 +40 -0
- package/lib/index.d.ts +22 -1
- package/lib/index.js +884 -229
- package/lib/{pluginDts-9RTNVO8v.js → pluginDts-Dbbi4cnh.js} +15 -9
- package/lib/{ssrEntryLoader-CuZVKlRm.js → ssrEntryLoader-BUD1-3Z2.js} +7 -4
- package/lib/{ssrVmStrategy-Dpw20xiw.js → ssrVmStrategy-C_cJtu5V.js} +1 -1
- package/lib/utils/injectExternalRuntimeCorePlugin.d.ts +21 -0
- package/lib/utils/injectExternalRuntimeCorePlugin.js +54 -0
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +8 -1
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-
|
|
1
|
+
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-Dbbi4cnh.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs$2 from "fs";
|
|
4
4
|
import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -148,7 +148,156 @@ async function mapCodeToCodeWithSourcemap(code) {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
//#endregion
|
|
151
|
+
//#region src/utils/codePositionMap.ts
|
|
152
|
+
const REGEX_PREFIX_KEYWORDS = new Set([
|
|
153
|
+
"await",
|
|
154
|
+
"case",
|
|
155
|
+
"delete",
|
|
156
|
+
"in",
|
|
157
|
+
"instanceof",
|
|
158
|
+
"new",
|
|
159
|
+
"return",
|
|
160
|
+
"throw",
|
|
161
|
+
"typeof",
|
|
162
|
+
"void",
|
|
163
|
+
"yield"
|
|
164
|
+
]);
|
|
165
|
+
function isJsxClosingTagSlash(code, slashIndex) {
|
|
166
|
+
if (code[slashIndex - 1] !== "<") return false;
|
|
167
|
+
let cursor = slashIndex + 1;
|
|
168
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
169
|
+
if (code[cursor] === ">") return true;
|
|
170
|
+
const tagStart = cursor;
|
|
171
|
+
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
172
|
+
if (cursor === tagStart) return false;
|
|
173
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
174
|
+
return code[cursor] === ">";
|
|
175
|
+
}
|
|
176
|
+
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
177
|
+
function createCodePositionMap(code) {
|
|
178
|
+
const positions = Array(code.length).fill(true);
|
|
179
|
+
const mask = (start, end) => {
|
|
180
|
+
for (let index = start; index < end; index++) positions[index] = false;
|
|
181
|
+
};
|
|
182
|
+
let canStartRegex = true;
|
|
183
|
+
for (let index = 0; index < code.length;) {
|
|
184
|
+
const char = code[index];
|
|
185
|
+
const next = code[index + 1];
|
|
186
|
+
if (/\s/.test(char)) {
|
|
187
|
+
index++;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (char === "/" && next === "/") {
|
|
191
|
+
const start = index;
|
|
192
|
+
index += 2;
|
|
193
|
+
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
194
|
+
mask(start, index);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (char === "/" && next === "*") {
|
|
198
|
+
const start = index;
|
|
199
|
+
index += 2;
|
|
200
|
+
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
201
|
+
index = Math.min(code.length, index + 2);
|
|
202
|
+
mask(start, index);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
206
|
+
const quote = char;
|
|
207
|
+
const start = index++;
|
|
208
|
+
while (index < code.length) {
|
|
209
|
+
if (code[index] === "\\") {
|
|
210
|
+
index += 2;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (code[index] === quote) {
|
|
214
|
+
index++;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
index++;
|
|
218
|
+
}
|
|
219
|
+
mask(start, index);
|
|
220
|
+
canStartRegex = false;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
224
|
+
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
225
|
+
const start = index;
|
|
226
|
+
let cursor = index + 1;
|
|
227
|
+
let escaped = false;
|
|
228
|
+
let inCharacterClass = false;
|
|
229
|
+
let closed = false;
|
|
230
|
+
for (; cursor < code.length; cursor++) {
|
|
231
|
+
const regexChar = code[cursor];
|
|
232
|
+
if (regexChar === "\n" || regexChar === "\r") break;
|
|
233
|
+
if (escaped) {
|
|
234
|
+
escaped = false;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (regexChar === "\\") {
|
|
238
|
+
escaped = true;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (regexChar === "[") {
|
|
242
|
+
inCharacterClass = true;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (regexChar === "]" && inCharacterClass) {
|
|
246
|
+
inCharacterClass = false;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (regexChar === "/" && !inCharacterClass) {
|
|
250
|
+
cursor++;
|
|
251
|
+
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
252
|
+
closed = true;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (closed) {
|
|
257
|
+
mask(start, cursor);
|
|
258
|
+
index = cursor;
|
|
259
|
+
canStartRegex = false;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
264
|
+
const start = index++;
|
|
265
|
+
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
266
|
+
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (/\d/.test(char)) {
|
|
270
|
+
index++;
|
|
271
|
+
while (/[\w.]/.test(code[index] || "")) index++;
|
|
272
|
+
canStartRegex = false;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if ((char === "+" || char === "-") && next === char) {
|
|
276
|
+
index += 2;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (char === "!" && next !== "=") {
|
|
280
|
+
index++;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
284
|
+
else if (char !== ".") canStartRegex = true;
|
|
285
|
+
index++;
|
|
286
|
+
}
|
|
287
|
+
return positions;
|
|
288
|
+
}
|
|
289
|
+
//#endregion
|
|
151
290
|
//#region src/utils/htmlEntryUtils.ts
|
|
291
|
+
function findModuleImportSources(code) {
|
|
292
|
+
const codePositions = createCodePositionMap(code);
|
|
293
|
+
const sources = /* @__PURE__ */ new Set();
|
|
294
|
+
for (const pattern of [
|
|
295
|
+
/\b(?:import|export)\s+[^;]*?\bfrom\s*["']([^"']+)["']/g,
|
|
296
|
+
/\bimport\s*\(\s*["']([^"']+)["']/g,
|
|
297
|
+
/\bimport\s*["']([^"']+)["']/g
|
|
298
|
+
]) for (const match of code.matchAll(pattern)) if (codePositions[match.index]) sources.add(match[1]);
|
|
299
|
+
return Array.from(sources);
|
|
300
|
+
}
|
|
152
301
|
function sanitizeDevEntryPath(devEntryPath) {
|
|
153
302
|
return devEntryPath.replace(/\\\\?/g, "/");
|
|
154
303
|
}
|
|
@@ -492,6 +641,13 @@ function normalizeManifest(manifest) {
|
|
|
492
641
|
fileName: manifest.fileName || "mf-manifest.json"
|
|
493
642
|
};
|
|
494
643
|
}
|
|
644
|
+
function normalizeExperiments(experiments) {
|
|
645
|
+
return {
|
|
646
|
+
externalRuntime: experiments?.externalRuntime === true,
|
|
647
|
+
provideExternalRuntime: experiments?.provideExternalRuntime === true,
|
|
648
|
+
ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0
|
|
649
|
+
};
|
|
650
|
+
}
|
|
495
651
|
let config;
|
|
496
652
|
let explicitSharedKeys = /* @__PURE__ */ new Set();
|
|
497
653
|
const explicitSharedKeysByOptions = /* @__PURE__ */ new WeakMap();
|
|
@@ -551,8 +707,10 @@ function normalizeModuleFederationOptions(options) {
|
|
|
551
707
|
target: options.target,
|
|
552
708
|
disableRemote: options.disableRemote,
|
|
553
709
|
disableShared: options.disableShared,
|
|
554
|
-
disableSnapshot: options.disableSnapshot
|
|
710
|
+
disableSnapshot: options.disableSnapshot,
|
|
711
|
+
experiments: normalizeExperiments(options.experiments)
|
|
555
712
|
};
|
|
713
|
+
if (normalized.experiments.ssrMode === "ISLAND" && Object.prototype.hasOwnProperty.call(normalized.shared, "react")) mfWarn("Island expose generation is disabled because experiments.ssrMode is \"ISLAND\" and React is configured as shared. Remove \"react\" from shared to generate island exposes, or remove ssrMode to use standard shared rendering.");
|
|
556
714
|
explicitSharedKeysByOptions.set(normalized, new Set(explicitSharedKeys));
|
|
557
715
|
return config = normalized;
|
|
558
716
|
}
|
|
@@ -569,6 +727,7 @@ const cacheMap = {};
|
|
|
569
727
|
const idCacheMap = {};
|
|
570
728
|
const VITE_ID_PREFIX = "/@id/";
|
|
571
729
|
const VITE_ENCODED_NULL_BYTE_PREFIX = `${VITE_ID_PREFIX}__x00__`;
|
|
730
|
+
const MF_OWNER_INFIX = "__mf_owner__";
|
|
572
731
|
function escapeRegExp$2(value) {
|
|
573
732
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
574
733
|
}
|
|
@@ -717,6 +876,147 @@ function serializeRuntimeOptions(options) {
|
|
|
717
876
|
return `{${topLevelProps.join(", ")}}`;
|
|
718
877
|
}
|
|
719
878
|
//#endregion
|
|
879
|
+
//#region src/utils/reactIsland.ts
|
|
880
|
+
const SOURCE_EXTENSIONS = [
|
|
881
|
+
".tsx",
|
|
882
|
+
".jsx",
|
|
883
|
+
".ts",
|
|
884
|
+
".js",
|
|
885
|
+
".mts",
|
|
886
|
+
".mjs",
|
|
887
|
+
".cts",
|
|
888
|
+
".cjs"
|
|
889
|
+
];
|
|
890
|
+
function stripQueryAndHash$2(id) {
|
|
891
|
+
return id.split(/[?#]/, 1)[0];
|
|
892
|
+
}
|
|
893
|
+
function resolveSourceFile(importPath, root) {
|
|
894
|
+
const cleanImport = stripQueryAndHash$2(importPath);
|
|
895
|
+
if (!cleanImport.startsWith(".") && !path$1.isAbsolute(cleanImport)) return;
|
|
896
|
+
const candidate = path$1.isAbsolute(cleanImport) ? cleanImport : path$1.resolve(root, cleanImport);
|
|
897
|
+
return [
|
|
898
|
+
candidate,
|
|
899
|
+
...SOURCE_EXTENSIONS.map((extension) => `${candidate}${extension}`),
|
|
900
|
+
...SOURCE_EXTENSIONS.map((extension) => path$1.join(candidate, `index${extension}`))
|
|
901
|
+
].find((filePath) => {
|
|
902
|
+
try {
|
|
903
|
+
return fs$1.statSync(filePath).isFile();
|
|
904
|
+
} catch {
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
function localDefaultReexport(source) {
|
|
910
|
+
const match = source.match(/export\s*{\s*(?:default(?:\s+as\s+default)?|[A-Za-z_$][\w$]*\s+as\s+default)\s*}\s*from\s*["']([^"']+)["']/);
|
|
911
|
+
return match?.[1]?.startsWith(".") ? match[1] : void 0;
|
|
912
|
+
}
|
|
913
|
+
function isReactComponentSource(source, filePath = "component.tsx") {
|
|
914
|
+
if (!(/\bexport\s+default\b/.test(source) || /\bexport\s*{[^}]*\bdefault\b[^}]*}(?:\s*from\s*["'][^"']+["'])?/.test(source))) return false;
|
|
915
|
+
const extension = path$1.extname(stripQueryAndHash$2(filePath)).toLowerCase();
|
|
916
|
+
const canContainJsx = extension === ".tsx" || extension === ".jsx";
|
|
917
|
+
const hasJsx = /<>|<\s*[A-Za-z][\w.:-]*(?:\s[^<>]*?)?\s*\/?>/.test(source);
|
|
918
|
+
const importsReact = /\bfrom\s*["']react["']|\brequire\(\s*["']react["']\s*\)/.test(source);
|
|
919
|
+
const usesReactApi = /\b(?:React\.)?(?:createElement|jsx|jsxs)\s*\(/.test(source);
|
|
920
|
+
const isClientModule = /^\s*["']use client["']\s*;?/m.test(source);
|
|
921
|
+
return canContainJsx && hasJsx || importsReact && (hasJsx || usesReactApi || isClientModule);
|
|
922
|
+
}
|
|
923
|
+
function isReactComponentFile(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
924
|
+
const normalizedPath = path$1.resolve(filePath);
|
|
925
|
+
if (seen.has(normalizedPath)) return false;
|
|
926
|
+
seen.add(normalizedPath);
|
|
927
|
+
let source;
|
|
928
|
+
try {
|
|
929
|
+
source = fs$1.readFileSync(normalizedPath, "utf8");
|
|
930
|
+
} catch {
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
if (isReactComponentSource(source, normalizedPath)) return true;
|
|
934
|
+
const reexport = localDefaultReexport(source);
|
|
935
|
+
if (!reexport) return false;
|
|
936
|
+
const reexportPath = resolveSourceFile(reexport, path$1.dirname(normalizedPath));
|
|
937
|
+
return reexportPath ? isReactComponentFile(reexportPath, seen) : false;
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* React is shared by the normal MF runtime when explicitly configured. When it
|
|
941
|
+
* is local, UI exposes can safely advertise an island capability in addition
|
|
942
|
+
* to their unchanged default export.
|
|
943
|
+
*/
|
|
944
|
+
function getReactIslandExposes(options, root) {
|
|
945
|
+
if (options.experiments.ssrMode !== "ISLAND") return /* @__PURE__ */ new Set();
|
|
946
|
+
if (Object.prototype.hasOwnProperty.call(options.shared, "react")) return /* @__PURE__ */ new Set();
|
|
947
|
+
const islandExposes = /* @__PURE__ */ new Set();
|
|
948
|
+
for (const [key, expose] of Object.entries(options.exposes)) {
|
|
949
|
+
const sourceFile = resolveSourceFile(expose.import, root);
|
|
950
|
+
if (sourceFile && isReactComponentFile(sourceFile)) islandExposes.add(key);
|
|
951
|
+
}
|
|
952
|
+
return islandExposes;
|
|
953
|
+
}
|
|
954
|
+
function generateReactIslandBrowserDefinition(enabled) {
|
|
955
|
+
if (!enabled) return "";
|
|
956
|
+
return `
|
|
957
|
+
exportModule.__mf_island = {
|
|
958
|
+
version: 1,
|
|
959
|
+
renderToHtml() {
|
|
960
|
+
return Promise.reject(new Error("[Module Federation] renderToHtml is only available in the SSR remote entry"));
|
|
961
|
+
},
|
|
962
|
+
hydrate(element, props) {
|
|
963
|
+
const root = element && element.hasAttribute && element.hasAttribute("data-mf-island-state")
|
|
964
|
+
? element
|
|
965
|
+
: element && element.querySelector
|
|
966
|
+
? element.querySelector("[data-mf-island-state]") || element
|
|
967
|
+
: element;
|
|
968
|
+
if (!root) {
|
|
969
|
+
return Promise.reject(new Error("[Module Federation] Cannot hydrate an island without a root element"));
|
|
970
|
+
}
|
|
971
|
+
let serverProps = {};
|
|
972
|
+
const encodedState = root.getAttribute && root.getAttribute("data-mf-island-state");
|
|
973
|
+
if (encodedState) {
|
|
974
|
+
try {
|
|
975
|
+
serverProps = JSON.parse(decodeURIComponent(encodedState));
|
|
976
|
+
} catch {
|
|
977
|
+
serverProps = {};
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
const finalProps = Object.assign({}, serverProps, props || {});
|
|
981
|
+
return Promise.all([import("react"), import("react-dom/client")]).then(([React, ReactDOMClient]) => {
|
|
982
|
+
if (typeof ReactDOMClient.hydrateRoot !== "function") {
|
|
983
|
+
throw new Error("[Module Federation] react-dom/client does not provide hydrateRoot");
|
|
984
|
+
}
|
|
985
|
+
return ReactDOMClient.hydrateRoot(
|
|
986
|
+
root,
|
|
987
|
+
React.createElement(importModule.default, finalProps)
|
|
988
|
+
);
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
}`;
|
|
992
|
+
}
|
|
993
|
+
function generateReactIslandSSRDefinition(enabled) {
|
|
994
|
+
if (!enabled) return "";
|
|
995
|
+
return `
|
|
996
|
+
exportModule.__mf_island = {
|
|
997
|
+
version: 1,
|
|
998
|
+
async renderToHtml(props) {
|
|
999
|
+
if (typeof importModule.default !== "function" && typeof importModule.default !== "object") {
|
|
1000
|
+
throw new Error("[Module Federation] A React island expose must have a default component export");
|
|
1001
|
+
}
|
|
1002
|
+
const loadedProps = typeof importModule.load === "function" ? await importModule.load() : {};
|
|
1003
|
+
const finalProps = Object.assign({}, loadedProps || {}, props || {});
|
|
1004
|
+
const [React, ReactDOMServer] = await Promise.all([
|
|
1005
|
+
import("react"),
|
|
1006
|
+
import("react-dom/server")
|
|
1007
|
+
]);
|
|
1008
|
+
const body = ReactDOMServer.renderToString(
|
|
1009
|
+
React.createElement(importModule.default, finalProps)
|
|
1010
|
+
);
|
|
1011
|
+
const state = encodeURIComponent(JSON.stringify(finalProps));
|
|
1012
|
+
return '<div data-mf-island-state="' + state + '">' + body + '</div>';
|
|
1013
|
+
},
|
|
1014
|
+
hydrate() {
|
|
1015
|
+
return Promise.reject(new Error("[Module Federation] hydrate is only available in the browser remote entry"));
|
|
1016
|
+
}
|
|
1017
|
+
}`;
|
|
1018
|
+
}
|
|
1019
|
+
//#endregion
|
|
720
1020
|
//#region src/virtualModules/virtualExposes.ts
|
|
721
1021
|
const EXPOSES_CSS_MAP_PLACEHOLDER = "__MF_EXPOSES_CSS_MAP__";
|
|
722
1022
|
function getExposesCssMapPlaceholder() {
|
|
@@ -725,7 +1025,7 @@ function getExposesCssMapPlaceholder() {
|
|
|
725
1025
|
function getVirtualExposesId(options) {
|
|
726
1026
|
return `virtual:mf-exposes:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
727
1027
|
}
|
|
728
|
-
function generateExposes(options, remoteDependencyMap = {}, command = "build") {
|
|
1028
|
+
function generateExposes(options, remoteDependencyMap = {}, command = "build", reactIslandExposes = /* @__PURE__ */ new Set()) {
|
|
729
1029
|
return `
|
|
730
1030
|
const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
|
|
731
1031
|
const injectedCssHrefs = new Set();
|
|
@@ -801,6 +1101,7 @@ function generateExposes(options, remoteDependencyMap = {}, command = "build") {
|
|
|
801
1101
|
}
|
|
802
1102
|
const exportModule = {}
|
|
803
1103
|
Object.assign(exportModule, importModule)
|
|
1104
|
+
${generateReactIslandBrowserDefinition(reactIslandExposes.has(key))}
|
|
804
1105
|
Object.defineProperty(exportModule, "__esModule", {
|
|
805
1106
|
value: true,
|
|
806
1107
|
enumerable: false
|
|
@@ -832,7 +1133,7 @@ function getRuntimeInitModule(options) {
|
|
|
832
1133
|
let runtimeInitModule = runtimeInitModules.get(options);
|
|
833
1134
|
if (!runtimeInitModule) {
|
|
834
1135
|
const ownerId = getRuntimeInitOwnerId(options);
|
|
835
|
-
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", `${options.internalName}
|
|
1136
|
+
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", `${options.internalName}${MF_OWNER_INFIX}${ownerId}`);
|
|
836
1137
|
runtimeInitModules.set(options, runtimeInitModule);
|
|
837
1138
|
}
|
|
838
1139
|
return runtimeInitModule;
|
|
@@ -845,7 +1146,7 @@ function getRuntimeRemoteCachePrefix(options) {
|
|
|
845
1146
|
}
|
|
846
1147
|
function getRuntimeRemoteAlias(alias, options) {
|
|
847
1148
|
if (!options) return alias;
|
|
848
|
-
return `${options.internalName}
|
|
1149
|
+
return `${options.internalName}${MF_OWNER_INFIX}${getRuntimeInitOwnerId(options)}__${alias}`;
|
|
849
1150
|
}
|
|
850
1151
|
function getRuntimeInitGlobalKey(ownerImportId) {
|
|
851
1152
|
return `__mf_init__${ownerImportId ?? virtualRuntimeInitStatus.getImportId()}__`;
|
|
@@ -984,145 +1285,6 @@ ${exportStatement}
|
|
|
984
1285
|
`);
|
|
985
1286
|
}
|
|
986
1287
|
//#endregion
|
|
987
|
-
//#region src/utils/codePositionMap.ts
|
|
988
|
-
const REGEX_PREFIX_KEYWORDS = new Set([
|
|
989
|
-
"await",
|
|
990
|
-
"case",
|
|
991
|
-
"delete",
|
|
992
|
-
"in",
|
|
993
|
-
"instanceof",
|
|
994
|
-
"new",
|
|
995
|
-
"return",
|
|
996
|
-
"throw",
|
|
997
|
-
"typeof",
|
|
998
|
-
"void",
|
|
999
|
-
"yield"
|
|
1000
|
-
]);
|
|
1001
|
-
function isJsxClosingTagSlash(code, slashIndex) {
|
|
1002
|
-
if (code[slashIndex - 1] !== "<") return false;
|
|
1003
|
-
let cursor = slashIndex + 1;
|
|
1004
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
1005
|
-
if (code[cursor] === ">") return true;
|
|
1006
|
-
const tagStart = cursor;
|
|
1007
|
-
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
1008
|
-
if (cursor === tagStart) return false;
|
|
1009
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
1010
|
-
return code[cursor] === ">";
|
|
1011
|
-
}
|
|
1012
|
-
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
1013
|
-
function createCodePositionMap(code) {
|
|
1014
|
-
const positions = Array(code.length).fill(true);
|
|
1015
|
-
const mask = (start, end) => {
|
|
1016
|
-
for (let index = start; index < end; index++) positions[index] = false;
|
|
1017
|
-
};
|
|
1018
|
-
let canStartRegex = true;
|
|
1019
|
-
for (let index = 0; index < code.length;) {
|
|
1020
|
-
const char = code[index];
|
|
1021
|
-
const next = code[index + 1];
|
|
1022
|
-
if (/\s/.test(char)) {
|
|
1023
|
-
index++;
|
|
1024
|
-
continue;
|
|
1025
|
-
}
|
|
1026
|
-
if (char === "/" && next === "/") {
|
|
1027
|
-
const start = index;
|
|
1028
|
-
index += 2;
|
|
1029
|
-
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
1030
|
-
mask(start, index);
|
|
1031
|
-
continue;
|
|
1032
|
-
}
|
|
1033
|
-
if (char === "/" && next === "*") {
|
|
1034
|
-
const start = index;
|
|
1035
|
-
index += 2;
|
|
1036
|
-
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
1037
|
-
index = Math.min(code.length, index + 2);
|
|
1038
|
-
mask(start, index);
|
|
1039
|
-
continue;
|
|
1040
|
-
}
|
|
1041
|
-
if (char === "\"" || char === "'" || char === "`") {
|
|
1042
|
-
const quote = char;
|
|
1043
|
-
const start = index++;
|
|
1044
|
-
while (index < code.length) {
|
|
1045
|
-
if (code[index] === "\\") {
|
|
1046
|
-
index += 2;
|
|
1047
|
-
continue;
|
|
1048
|
-
}
|
|
1049
|
-
if (code[index] === quote) {
|
|
1050
|
-
index++;
|
|
1051
|
-
break;
|
|
1052
|
-
}
|
|
1053
|
-
index++;
|
|
1054
|
-
}
|
|
1055
|
-
mask(start, index);
|
|
1056
|
-
canStartRegex = false;
|
|
1057
|
-
continue;
|
|
1058
|
-
}
|
|
1059
|
-
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
1060
|
-
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
1061
|
-
const start = index;
|
|
1062
|
-
let cursor = index + 1;
|
|
1063
|
-
let escaped = false;
|
|
1064
|
-
let inCharacterClass = false;
|
|
1065
|
-
let closed = false;
|
|
1066
|
-
for (; cursor < code.length; cursor++) {
|
|
1067
|
-
const regexChar = code[cursor];
|
|
1068
|
-
if (regexChar === "\n" || regexChar === "\r") break;
|
|
1069
|
-
if (escaped) {
|
|
1070
|
-
escaped = false;
|
|
1071
|
-
continue;
|
|
1072
|
-
}
|
|
1073
|
-
if (regexChar === "\\") {
|
|
1074
|
-
escaped = true;
|
|
1075
|
-
continue;
|
|
1076
|
-
}
|
|
1077
|
-
if (regexChar === "[") {
|
|
1078
|
-
inCharacterClass = true;
|
|
1079
|
-
continue;
|
|
1080
|
-
}
|
|
1081
|
-
if (regexChar === "]" && inCharacterClass) {
|
|
1082
|
-
inCharacterClass = false;
|
|
1083
|
-
continue;
|
|
1084
|
-
}
|
|
1085
|
-
if (regexChar === "/" && !inCharacterClass) {
|
|
1086
|
-
cursor++;
|
|
1087
|
-
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
1088
|
-
closed = true;
|
|
1089
|
-
break;
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
if (closed) {
|
|
1093
|
-
mask(start, cursor);
|
|
1094
|
-
index = cursor;
|
|
1095
|
-
canStartRegex = false;
|
|
1096
|
-
continue;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
1100
|
-
const start = index++;
|
|
1101
|
-
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
1102
|
-
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
1103
|
-
continue;
|
|
1104
|
-
}
|
|
1105
|
-
if (/\d/.test(char)) {
|
|
1106
|
-
index++;
|
|
1107
|
-
while (/[\w.]/.test(code[index] || "")) index++;
|
|
1108
|
-
canStartRegex = false;
|
|
1109
|
-
continue;
|
|
1110
|
-
}
|
|
1111
|
-
if ((char === "+" || char === "-") && next === char) {
|
|
1112
|
-
index += 2;
|
|
1113
|
-
continue;
|
|
1114
|
-
}
|
|
1115
|
-
if (char === "!" && next !== "=") {
|
|
1116
|
-
index++;
|
|
1117
|
-
continue;
|
|
1118
|
-
}
|
|
1119
|
-
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
1120
|
-
else if (char !== ".") canStartRegex = true;
|
|
1121
|
-
index++;
|
|
1122
|
-
}
|
|
1123
|
-
return positions;
|
|
1124
|
-
}
|
|
1125
|
-
//#endregion
|
|
1126
1288
|
//#region src/utils/treeShaking.ts
|
|
1127
1289
|
const legacyTreeShakingState = {
|
|
1128
1290
|
inferredUsage: /* @__PURE__ */ new Map(),
|
|
@@ -1385,6 +1547,79 @@ function collectTreeShakingImports(code, id, shared, findSharedKey, record, mark
|
|
|
1385
1547
|
});
|
|
1386
1548
|
}
|
|
1387
1549
|
//#endregion
|
|
1550
|
+
//#region src/utils/typeArgumentScanner.ts
|
|
1551
|
+
function getTypeArgumentStartContext(source, start) {
|
|
1552
|
+
let previous = start - 1;
|
|
1553
|
+
while (previous >= 0 && /\s/.test(source[previous])) previous--;
|
|
1554
|
+
const previousChar = source[previous] || "";
|
|
1555
|
+
const followsNamedExpression = /[$_\u200C\u200D\p{ID_Continue})\]>]/u.test(previousChar);
|
|
1556
|
+
const startsStandaloneGeneric = previousChar !== "" && "=([{,:".includes(previousChar);
|
|
1557
|
+
if (!followsNamedExpression && !startsStandaloneGeneric) return void 0;
|
|
1558
|
+
return { followsNamedExpression };
|
|
1559
|
+
}
|
|
1560
|
+
function updateTypeArgumentGroupDepth(char, state) {
|
|
1561
|
+
if (char === "(" || char === "[" || char === "{") {
|
|
1562
|
+
state.groupDepth++;
|
|
1563
|
+
return "handled";
|
|
1564
|
+
}
|
|
1565
|
+
if (char !== ")" && char !== "]" && char !== "}") return void 0;
|
|
1566
|
+
if (state.groupDepth === 0) return "invalid";
|
|
1567
|
+
state.groupDepth--;
|
|
1568
|
+
return "handled";
|
|
1569
|
+
}
|
|
1570
|
+
function updateTypeArgumentAngleDepth(source, index, state) {
|
|
1571
|
+
const char = source[index];
|
|
1572
|
+
if (char === "<") {
|
|
1573
|
+
if (source[index + 1] === "=" || source[index + 1] === "<") return "invalid";
|
|
1574
|
+
state.angleDepth++;
|
|
1575
|
+
return "handled";
|
|
1576
|
+
}
|
|
1577
|
+
if (char !== ">") return void 0;
|
|
1578
|
+
if (source[index - 1] === "=" || source[index + 1] === "=") return "handled";
|
|
1579
|
+
state.angleDepth--;
|
|
1580
|
+
return state.angleDepth === 0 ? "closed" : "handled";
|
|
1581
|
+
}
|
|
1582
|
+
function hasLikelyTypeArgumentFollower(source, end, codePositions, followsNamedExpression) {
|
|
1583
|
+
let next = end + 1;
|
|
1584
|
+
while (next < source.length && (!codePositions[next] || /\s/.test(source[next]))) next++;
|
|
1585
|
+
if (next >= source.length || /[([.!?=;,)\]}:|&]/.test(source[next])) return true;
|
|
1586
|
+
const followingToken = source.slice(next).match(/^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*/u)?.[0];
|
|
1587
|
+
return followingToken === "as" || followingToken === "satisfies" || !followsNamedExpression && followingToken !== void 0;
|
|
1588
|
+
}
|
|
1589
|
+
function isInvalidTypeArgumentTerminator(source, index, followsNamedExpression) {
|
|
1590
|
+
const char = source[index];
|
|
1591
|
+
return char === ";" || char === "=" && source[index + 1] !== ">" && followsNamedExpression;
|
|
1592
|
+
}
|
|
1593
|
+
/**
|
|
1594
|
+
* Finds the end of a balanced, type-like angle-bracket range that contains a
|
|
1595
|
+
* comma. Ambiguous syntax returns `undefined` so callers can fail closed.
|
|
1596
|
+
*/
|
|
1597
|
+
function findLikelyTypeArgumentEnd(source, start, codePositions) {
|
|
1598
|
+
const context = getTypeArgumentStartContext(source, start);
|
|
1599
|
+
if (!context) return void 0;
|
|
1600
|
+
const state = {
|
|
1601
|
+
angleDepth: 1,
|
|
1602
|
+
groupDepth: 0,
|
|
1603
|
+
sawTypeComma: false
|
|
1604
|
+
};
|
|
1605
|
+
for (let index = start + 1; index < source.length; index++) {
|
|
1606
|
+
if (!codePositions[index]) continue;
|
|
1607
|
+
const char = source[index];
|
|
1608
|
+
const groupAction = updateTypeArgumentGroupDepth(char, state);
|
|
1609
|
+
if (groupAction === "invalid") return void 0;
|
|
1610
|
+
if (groupAction === "handled") continue;
|
|
1611
|
+
const angleAction = updateTypeArgumentAngleDepth(source, index, state);
|
|
1612
|
+
if (angleAction === "invalid") return void 0;
|
|
1613
|
+
if (angleAction === "closed") return state.sawTypeComma && hasLikelyTypeArgumentFollower(source, index, codePositions, context.followsNamedExpression) ? index : void 0;
|
|
1614
|
+
if (angleAction === "handled") continue;
|
|
1615
|
+
if (char === "," && state.groupDepth === 0) {
|
|
1616
|
+
state.sawTypeComma = true;
|
|
1617
|
+
continue;
|
|
1618
|
+
}
|
|
1619
|
+
if (state.angleDepth === 1 && state.groupDepth === 0 && isInvalidTypeArgumentTerminator(source, index, context.followsNamedExpression)) return;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
//#endregion
|
|
1388
1623
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
1389
1624
|
/**
|
|
1390
1625
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -1436,6 +1671,12 @@ function getPackageEsmEntryPath(pkg) {
|
|
|
1436
1671
|
resolveSubpathWithRequire: false
|
|
1437
1672
|
}) || resolvePackageEntryFromProjectRoot(pkg);
|
|
1438
1673
|
}
|
|
1674
|
+
const DEFAULT_SHARED_EXPORT_CONDITIONS = [
|
|
1675
|
+
"browser",
|
|
1676
|
+
"import",
|
|
1677
|
+
"module",
|
|
1678
|
+
"default"
|
|
1679
|
+
];
|
|
1439
1680
|
function hasCodeMatch(source, regex, codePositions) {
|
|
1440
1681
|
regex.lastIndex = 0;
|
|
1441
1682
|
let match;
|
|
@@ -1445,12 +1686,12 @@ function hasCodeMatch(source, regex, codePositions) {
|
|
|
1445
1686
|
function hasCommonJsExports(source) {
|
|
1446
1687
|
return hasCodeMatch(source, /\bmodule\s*(?:\.exports|\[\s*['"]exports['"]\s*\])|\bexports\s*(?:\.|\[|[,)]|=(?!=|>))/g, createCodePositionMap(source));
|
|
1447
1688
|
}
|
|
1448
|
-
function inspectSharedExportsFromFile(entryPath) {
|
|
1689
|
+
function inspectSharedExportsFromFile(entryPath, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1449
1690
|
try {
|
|
1450
1691
|
if (!entryPath) return void 0;
|
|
1451
1692
|
const source = readFileSync(entryPath, "utf-8");
|
|
1452
1693
|
const scanState = { complete: true };
|
|
1453
|
-
const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState);
|
|
1694
|
+
const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState, exportConditions);
|
|
1454
1695
|
const commonJs = hasCommonJsExports(source);
|
|
1455
1696
|
return {
|
|
1456
1697
|
namedExports: scanState.complete && !commonJs ? namedExports : void 0,
|
|
@@ -1460,17 +1701,12 @@ function inspectSharedExportsFromFile(entryPath) {
|
|
|
1460
1701
|
return;
|
|
1461
1702
|
}
|
|
1462
1703
|
}
|
|
1463
|
-
function resolveConfiguredImportPath(importSource) {
|
|
1704
|
+
function resolveConfiguredImportPath(importSource, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1464
1705
|
if (path$1.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
|
|
1465
1706
|
const projectRoot = getPackageDetectionCwd();
|
|
1466
1707
|
if (importSource.startsWith(".")) return resolveFileLikeModule(path$1.resolve(projectRoot, importSource));
|
|
1467
1708
|
const esmEntry = getInstalledPackageEntry(importSource, {
|
|
1468
|
-
conditions:
|
|
1469
|
-
"browser",
|
|
1470
|
-
"import",
|
|
1471
|
-
"module",
|
|
1472
|
-
"default"
|
|
1473
|
-
],
|
|
1709
|
+
conditions: exportConditions,
|
|
1474
1710
|
resolveSubpathWithRequire: false
|
|
1475
1711
|
});
|
|
1476
1712
|
if (esmEntry) return esmEntry;
|
|
@@ -1521,16 +1757,11 @@ function resolveRelativeModule(filePath, specifier) {
|
|
|
1521
1757
|
if (existsSync(candidate)) return candidate;
|
|
1522
1758
|
}
|
|
1523
1759
|
}
|
|
1524
|
-
function resolveReExportModule(filePath, specifier) {
|
|
1760
|
+
function resolveReExportModule(filePath, specifier, exportConditions) {
|
|
1525
1761
|
if (specifier.startsWith(".")) return resolveRelativeModule(filePath, specifier);
|
|
1526
1762
|
const esmEntry = getInstalledPackageEntry(specifier, {
|
|
1527
1763
|
cwd: path$1.dirname(filePath),
|
|
1528
|
-
conditions:
|
|
1529
|
-
"browser",
|
|
1530
|
-
"import",
|
|
1531
|
-
"module",
|
|
1532
|
-
"default"
|
|
1533
|
-
],
|
|
1764
|
+
conditions: exportConditions,
|
|
1534
1765
|
resolveSubpathWithRequire: false
|
|
1535
1766
|
});
|
|
1536
1767
|
if (esmEntry) return esmEntry;
|
|
@@ -1540,7 +1771,7 @@ function resolveReExportModule(filePath, specifier) {
|
|
|
1540
1771
|
return;
|
|
1541
1772
|
}
|
|
1542
1773
|
}
|
|
1543
|
-
function hasTopLevelDeclaratorComma(source, start) {
|
|
1774
|
+
function hasTopLevelDeclaratorComma(source, start, codePositions) {
|
|
1544
1775
|
let depth = 0;
|
|
1545
1776
|
let quote;
|
|
1546
1777
|
let escaped = false;
|
|
@@ -1623,6 +1854,14 @@ function hasTopLevelDeclaratorComma(source, start) {
|
|
|
1623
1854
|
continue;
|
|
1624
1855
|
}
|
|
1625
1856
|
if (char === "!" && source[index + 1] !== "=") continue;
|
|
1857
|
+
if (char === "<") {
|
|
1858
|
+
const typeArgumentEnd = findLikelyTypeArgumentEnd(source, index, codePositions);
|
|
1859
|
+
if (typeArgumentEnd !== void 0) {
|
|
1860
|
+
index = typeArgumentEnd;
|
|
1861
|
+
canStartRegex = false;
|
|
1862
|
+
continue;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1626
1865
|
if (char === "(" || char === "[" || char === "{") {
|
|
1627
1866
|
depth++;
|
|
1628
1867
|
canStartRegex = true;
|
|
@@ -1663,7 +1902,7 @@ function hasUnsupportedBindingPattern(source, start) {
|
|
|
1663
1902
|
}
|
|
1664
1903
|
return true;
|
|
1665
1904
|
}
|
|
1666
|
-
function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }) {
|
|
1905
|
+
function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1667
1906
|
const names = /* @__PURE__ */ new Set();
|
|
1668
1907
|
const codePositions = createCodePositionMap(source);
|
|
1669
1908
|
const recognizedExportStarts = /* @__PURE__ */ new Set();
|
|
@@ -1680,7 +1919,7 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
1680
1919
|
const exportedVariableDeclarationRegex = /export\s+(?:const|let|var)\s+/g;
|
|
1681
1920
|
while ((match = exportedVariableDeclarationRegex.exec(source)) !== null) {
|
|
1682
1921
|
if (!codePositions[match.index]) continue;
|
|
1683
|
-
if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
1922
|
+
if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex, codePositions)) scanState.complete = false;
|
|
1684
1923
|
if (hasUnsupportedBindingPattern(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
1685
1924
|
}
|
|
1686
1925
|
if (hasCodeMatch(source, /export\s+import\s+/g, codePositions) || hasCodeMatch(source, /export\s*=/g, codePositions)) scanState.complete = false;
|
|
@@ -1733,23 +1972,24 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
1733
1972
|
if (!codePositions[match.index]) continue;
|
|
1734
1973
|
recognizedExportStarts.add(match.index);
|
|
1735
1974
|
const specifier = match[1];
|
|
1736
|
-
const resolvedPath = resolveReExportModule(filePath, specifier);
|
|
1975
|
+
const resolvedPath = resolveReExportModule(filePath, specifier, exportConditions);
|
|
1737
1976
|
if (!resolvedPath) {
|
|
1738
1977
|
scanState.complete = false;
|
|
1739
1978
|
continue;
|
|
1740
1979
|
}
|
|
1741
1980
|
if (visited.has(resolvedPath)) continue;
|
|
1742
|
-
if (path$1.extname(resolvedPath) === ".cjs") {
|
|
1743
|
-
scanState.complete = false;
|
|
1744
|
-
continue;
|
|
1745
|
-
}
|
|
1746
1981
|
try {
|
|
1747
1982
|
const reExportSource = readFileSync(resolvedPath, "utf-8");
|
|
1748
|
-
if (hasCommonJsExports(reExportSource)) {
|
|
1749
|
-
|
|
1983
|
+
if (path$1.extname(resolvedPath) === ".cjs" || hasCommonJsExports(reExportSource)) {
|
|
1984
|
+
const requiredNames = getRequiredNamedExports(resolvedPath);
|
|
1985
|
+
if (!requiredNames?.length) {
|
|
1986
|
+
scanState.complete = false;
|
|
1987
|
+
continue;
|
|
1988
|
+
}
|
|
1989
|
+
for (const name of requiredNames) names.add(name);
|
|
1750
1990
|
continue;
|
|
1751
1991
|
}
|
|
1752
|
-
const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState);
|
|
1992
|
+
const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState, exportConditions);
|
|
1753
1993
|
for (const name of reExportNames) names.add(name);
|
|
1754
1994
|
} catch {
|
|
1755
1995
|
scanState.complete = false;
|
|
@@ -1781,34 +2021,29 @@ function getRequiredNamedExports(specifier) {
|
|
|
1781
2021
|
return;
|
|
1782
2022
|
}
|
|
1783
2023
|
}
|
|
1784
|
-
function getPackageNamedExports(pkg) {
|
|
2024
|
+
function getPackageNamedExports(pkg, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1785
2025
|
const esmEntryPath = getInstalledPackageEntry(pkg, {
|
|
1786
|
-
conditions:
|
|
1787
|
-
"browser",
|
|
1788
|
-
"import",
|
|
1789
|
-
"module",
|
|
1790
|
-
"default"
|
|
1791
|
-
],
|
|
2026
|
+
conditions: exportConditions,
|
|
1792
2027
|
resolveSubpathWithRequire: false
|
|
1793
2028
|
});
|
|
1794
2029
|
if (esmEntryPath) {
|
|
1795
|
-
const inspection = inspectSharedExportsFromFile(esmEntryPath);
|
|
2030
|
+
const inspection = inspectSharedExportsFromFile(esmEntryPath, exportConditions);
|
|
1796
2031
|
if (!inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs") return getRequiredNamedExports(esmEntryPath);
|
|
1797
2032
|
if (inspection.namedExports !== void 0) return inspection.namedExports;
|
|
1798
2033
|
return;
|
|
1799
2034
|
}
|
|
1800
2035
|
return getRequiredNamedExports(pkg);
|
|
1801
2036
|
}
|
|
1802
|
-
function getSharedNamedExports(pkg, shareItem) {
|
|
2037
|
+
function getSharedNamedExports(pkg, shareItem, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1803
2038
|
const configuredImport = shareItem?.shareConfig.import;
|
|
1804
2039
|
if (typeof configuredImport === "string") {
|
|
1805
|
-
const configuredImportPath = resolveConfiguredImportPath(configuredImport);
|
|
1806
|
-
const inspection = inspectSharedExportsFromFile(configuredImportPath);
|
|
2040
|
+
const configuredImportPath = resolveConfiguredImportPath(configuredImport, exportConditions);
|
|
2041
|
+
const inspection = inspectSharedExportsFromFile(configuredImportPath, exportConditions);
|
|
1807
2042
|
if (configuredImportPath && (inspection?.commonJs || path$1.extname(configuredImportPath) === ".cjs")) return getRequiredNamedExports(configuredImportPath);
|
|
1808
2043
|
if (inspection?.namedExports !== void 0) return inspection.namedExports;
|
|
1809
2044
|
return;
|
|
1810
2045
|
}
|
|
1811
|
-
return getPackageNamedExports(pkg);
|
|
2046
|
+
return getPackageNamedExports(pkg, exportConditions);
|
|
1812
2047
|
}
|
|
1813
2048
|
function getLocalProviderImportPath(pkg) {
|
|
1814
2049
|
try {
|
|
@@ -1980,7 +2215,7 @@ function getSharedVirtualModuleState(options) {
|
|
|
1980
2215
|
treeShakingProviderCacheMap: {},
|
|
1981
2216
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
1982
2217
|
loadShareCacheMap: {},
|
|
1983
|
-
ownerKey: `${options.internalName}
|
|
2218
|
+
ownerKey: `${options.internalName}${MF_OWNER_INFIX}${nextSharedVirtualModuleOwnerId++}`
|
|
1984
2219
|
};
|
|
1985
2220
|
sharedVirtualModuleStates.set(options, state);
|
|
1986
2221
|
}
|
|
@@ -2081,7 +2316,7 @@ export default { get, init };
|
|
|
2081
2316
|
`, true);
|
|
2082
2317
|
materializedTreeShakingProviders.add(pkg);
|
|
2083
2318
|
}
|
|
2084
|
-
function writePreBuildLibPath(pkg, shareItem, options) {
|
|
2319
|
+
function writePreBuildLibPath(pkg, shareItem, options, exportConditions) {
|
|
2085
2320
|
const { preBuildCacheMap, preBuildShareItemMap } = getSharedVirtualModuleState(options);
|
|
2086
2321
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = createScopedSharedVirtualModule(pkg, PREBUILD_TAG, options);
|
|
2087
2322
|
preBuildShareItemMap[pkg] = shareItem;
|
|
@@ -2131,7 +2366,7 @@ function writePreBuildLibPath(pkg, shareItem, options) {
|
|
|
2131
2366
|
`, true);
|
|
2132
2367
|
return;
|
|
2133
2368
|
}
|
|
2134
|
-
const namedExports = getSharedNamedExports(pkg, shareItem) ?? [];
|
|
2369
|
+
const namedExports = getSharedNamedExports(pkg, shareItem, exportConditions) ?? [];
|
|
2135
2370
|
if (namedExports.length > 0) {
|
|
2136
2371
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
2137
2372
|
const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
|
|
@@ -2185,17 +2420,23 @@ function getLoadShareModulePath(pkg, isRolldown, options) {
|
|
|
2185
2420
|
if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown, options);
|
|
2186
2421
|
return loadShareCacheMap[pkg].getImportId();
|
|
2187
2422
|
}
|
|
2188
|
-
function
|
|
2189
|
-
if (!id.includes(
|
|
2423
|
+
function getCachedSharedVirtualPkg(id, tag) {
|
|
2424
|
+
if (!id.includes(tag)) return;
|
|
2190
2425
|
const normalized = normalizeVirtualModuleId(id);
|
|
2191
2426
|
if (!normalized.startsWith("virtual:mf:")) return;
|
|
2192
|
-
const start = normalized.indexOf(
|
|
2427
|
+
const start = normalized.indexOf(tag);
|
|
2193
2428
|
if (start === -1) return;
|
|
2194
|
-
const encodedPkgStart = start +
|
|
2195
|
-
const end = normalized.indexOf(
|
|
2429
|
+
const encodedPkgStart = start + tag.length;
|
|
2430
|
+
const end = normalized.indexOf(tag, encodedPkgStart);
|
|
2196
2431
|
if (end === -1) return;
|
|
2197
2432
|
return packageNameDecode(normalized.slice(encodedPkgStart, end));
|
|
2198
2433
|
}
|
|
2434
|
+
function getCachedPreBuildPkg(id) {
|
|
2435
|
+
return getCachedSharedVirtualPkg(id, PREBUILD_TAG);
|
|
2436
|
+
}
|
|
2437
|
+
function getCachedLoadSharePkg(id) {
|
|
2438
|
+
return getCachedSharedVirtualPkg(id, LOAD_SHARE_TAG);
|
|
2439
|
+
}
|
|
2199
2440
|
function materializeCachedLoadShareModule(options) {
|
|
2200
2441
|
const pkg = getCachedLoadSharePkg(options.id);
|
|
2201
2442
|
if (!pkg) return;
|
|
@@ -2207,6 +2448,18 @@ function materializeCachedLoadShareModule(options) {
|
|
|
2207
2448
|
options.addUsedShares(pkg);
|
|
2208
2449
|
options.writeLocalSharedImportMap();
|
|
2209
2450
|
}
|
|
2451
|
+
function findCurrentLoadShareForStaleOwnerId(id, shared, findSharedKey, options) {
|
|
2452
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
2453
|
+
if (!pkg) return;
|
|
2454
|
+
const normalized = normalizeVirtualModuleId(id);
|
|
2455
|
+
if (!normalized.startsWith("virtual:mf:")) return;
|
|
2456
|
+
const encodedKey = normalized.slice(11);
|
|
2457
|
+
const ownerStart = encodedKey.indexOf(MF_OWNER_INFIX);
|
|
2458
|
+
if (ownerStart === -1) return;
|
|
2459
|
+
if (encodedKey.slice(0, ownerStart) !== packageNameEncode(options.internalName)) return;
|
|
2460
|
+
if (!findSharedKey(pkg, shared)) return;
|
|
2461
|
+
return getSharedVirtualModuleState(options).loadShareCacheMap[pkg];
|
|
2462
|
+
}
|
|
2210
2463
|
function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
2211
2464
|
return treeShakingConsumer ? `__mfReadTreeShakingSharedSelection(__mfModuleCache.share, ${cacheDescriptor}, ${JSON.stringify(treeShakingConsumer)})` : `__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})`;
|
|
2212
2465
|
}
|
|
@@ -2330,7 +2583,7 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
|
|
|
2330
2583
|
? Object.assign({}, normalized)
|
|
2331
2584
|
: normalized;
|
|
2332
2585
|
};`;
|
|
2333
|
-
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
2586
|
+
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exportConditions) {
|
|
2334
2587
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
2335
2588
|
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
2336
2589
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
@@ -2340,7 +2593,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2340
2593
|
const runtimeInitOwnerImportId = options ? getRuntimeInitStatusImportId(options) : void 0;
|
|
2341
2594
|
const treeShakingConsumer = command === "build" && shareItem.shareConfig.treeShaking ? resolvedOptions.name : void 0;
|
|
2342
2595
|
if (shareItem.shareConfig.import === false) {
|
|
2343
|
-
const detectedNamedExports = getPackageNamedExports(pkg);
|
|
2596
|
+
const detectedNamedExports = getPackageNamedExports(pkg, exportConditions);
|
|
2344
2597
|
const namedExports = detectedNamedExports ?? [];
|
|
2345
2598
|
let exportLine;
|
|
2346
2599
|
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer);
|
|
@@ -2364,7 +2617,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2364
2617
|
const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
|
|
2365
2618
|
const lazyLocalFallbackSource = command !== "build" ? concreteSharedImportSource || localProviderPath || devImportSource : concreteSharedImportSource || localProviderPath || sharedImportSource;
|
|
2366
2619
|
const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
|
|
2367
|
-
const detectedNamedExports = getSharedNamedExports(pkg, shareItem);
|
|
2620
|
+
const detectedNamedExports = getSharedNamedExports(pkg, shareItem, exportConditions);
|
|
2368
2621
|
const namedExports = detectedNamedExports ?? [];
|
|
2369
2622
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
2370
2623
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
@@ -2497,7 +2750,7 @@ function getLocalOwnerKey(options) {
|
|
|
2497
2750
|
ownerId = nextLocalOwnerId++;
|
|
2498
2751
|
localOwnerIds.set(options, ownerId);
|
|
2499
2752
|
}
|
|
2500
|
-
return `${options.internalName}
|
|
2753
|
+
return `${options.internalName}${MF_OWNER_INFIX}${ownerId}`;
|
|
2501
2754
|
}
|
|
2502
2755
|
function getLocalSharedImportMapPath(options) {
|
|
2503
2756
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
@@ -4093,7 +4346,7 @@ function getRemoteVirtualModule(remote, command, enableSsrInit = false, consumer
|
|
|
4093
4346
|
}
|
|
4094
4347
|
const cacheKey = `${remote}__${command}__${options.shareStrategy}__${consumer}__${enableSsrInit ? "ssr-init" : "no-ssr-init"}`;
|
|
4095
4348
|
if (!instanceCache.has(cacheKey)) {
|
|
4096
|
-
const virtual = new VirtualModule(`${consumer === "unified" ? remote : `${remote}__mf_consumer__${consumer}`}
|
|
4349
|
+
const virtual = new VirtualModule(`${consumer === "unified" ? remote : `${remote}__mf_consumer__${consumer}`}${MF_OWNER_INFIX}${getRemoteOptionsId(options)}`, LOAD_REMOTE_TAG, ".js", options.internalName);
|
|
4097
4350
|
virtual.writeSync(generateRemotes(remote, command, enableSsrInit, consumer, options));
|
|
4098
4351
|
instanceCache.set(cacheKey, virtual);
|
|
4099
4352
|
}
|
|
@@ -4418,6 +4671,9 @@ function getFirstHtmlEntryFile(entryFiles) {
|
|
|
4418
4671
|
function stripQueryAndHash$1(file) {
|
|
4419
4672
|
return file.split(/[?#]/)[0];
|
|
4420
4673
|
}
|
|
4674
|
+
function isReactRouterClientRouteInput(file) {
|
|
4675
|
+
return /[?&]__react-router-build-client-route(?:[=&]|$)/.test(file);
|
|
4676
|
+
}
|
|
4421
4677
|
function resolveDevHashEntryFileName$1(fileName) {
|
|
4422
4678
|
if (!fileName.includes("[hash")) return fileName;
|
|
4423
4679
|
const normalized = fileName.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
|
|
@@ -4536,7 +4792,11 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4536
4792
|
: import(src);
|
|
4537
4793
|
` : "";
|
|
4538
4794
|
const importExpression = (src) => useSystemImportFallback ? `__mfImport(${JSON.stringify(src)})` : `import(${JSON.stringify(src)})`;
|
|
4539
|
-
const
|
|
4795
|
+
const isEncodedVirtualEntry = entrySrc.startsWith(VITE_ENCODED_NULL_BYTE_PREFIX);
|
|
4796
|
+
const entryImportDeclaration = isEncodedVirtualEntry ? `const __mfEntryUrl = ${JSON.stringify(entrySrc)};
|
|
4797
|
+
` : "";
|
|
4798
|
+
const entryImportExpression = isEncodedVirtualEntry ? "import(/* @vite-ignore */ __mfEntryUrl)" : importExpression(entrySrc);
|
|
4799
|
+
const remotePreloads = !options?.skipRemotePreload && (federationOptions ?? getNormalizeModuleFederationOptions())?.shareStrategy !== "loaded-first" ? Object.entries(getUsedRemotesMap(federationOptions)).flatMap(([, remotes]) => Array.from(remotes)).sort().map((remote) => `__mfPreloadRemote(${JSON.stringify(getRuntimeRemoteId(remote, (federationOptions ?? getNormalizeModuleFederationOptions()).remotes, federationOptions))}, ${JSON.stringify(remote)})`).join(",") : "";
|
|
4540
4800
|
const remoteCachePrefix = getRuntimeRemoteCachePrefix(federationOptions);
|
|
4541
4801
|
const preloadBlock = remotePreloads ? `
|
|
4542
4802
|
const runtime = await initHost();
|
|
@@ -4568,11 +4828,12 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4568
4828
|
if (__mfModuleCache.pendingShareLoads) {
|
|
4569
4829
|
await Promise.all(__mfModuleCache.pendingShareLoads);
|
|
4570
4830
|
}
|
|
4571
|
-
})().then(() => ${
|
|
4831
|
+
})().then(() => ${entryImportExpression});
|
|
4572
4832
|
`;
|
|
4573
4833
|
return [
|
|
4574
4834
|
getRuntimeModuleCacheBootstrapCode(),
|
|
4575
4835
|
importHelper,
|
|
4836
|
+
entryImportDeclaration,
|
|
4576
4837
|
importCode
|
|
4577
4838
|
].join("\n");
|
|
4578
4839
|
}
|
|
@@ -4616,6 +4877,16 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4616
4877
|
addEntryFile(scriptSrc.startsWith("/") ? path$1.resolve(viteConfig.root, scriptSrc.slice(1)) : path$1.resolve(path$1.dirname(htmlPath), scriptSrc));
|
|
4617
4878
|
}
|
|
4618
4879
|
}
|
|
4880
|
+
function addEntryRemoteImports(entrySrc) {
|
|
4881
|
+
if (!federationOptions || /^(?:[a-z]+:)?\/\//i.test(entrySrc)) return;
|
|
4882
|
+
const file = path$1.resolve(viteConfig.root, stripQueryAndHash$1(entrySrc).replace(/^\//, ""));
|
|
4883
|
+
if (!fs$2.existsSync(file)) return;
|
|
4884
|
+
const code = fs$2.readFileSync(file, "utf-8");
|
|
4885
|
+
for (const source of findModuleImportSources(code)) {
|
|
4886
|
+
const remote = Object.keys(federationOptions.remotes).find((name) => source === name || source.startsWith(`${name}/`));
|
|
4887
|
+
if (remote) addUsedRemote(remote, source, federationOptions);
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4619
4890
|
return [{
|
|
4620
4891
|
name: "add-entry",
|
|
4621
4892
|
apply: "serve",
|
|
@@ -4643,9 +4914,10 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4643
4914
|
const initSrc = params.get("init");
|
|
4644
4915
|
const entrySrc = params.get("entry");
|
|
4645
4916
|
if (initSrc && entrySrc) {
|
|
4917
|
+
const withBase = (src) => viteConfig.base + src.replace(/^\//, "");
|
|
4646
4918
|
res.statusCode = 200;
|
|
4647
4919
|
res.setHeader("Content-Type", "application/javascript");
|
|
4648
|
-
res.end(getBootstrapSource(initSrc, entrySrc));
|
|
4920
|
+
res.end(getBootstrapSource(withBase(initSrc), withBase(entrySrc)));
|
|
4649
4921
|
return;
|
|
4650
4922
|
}
|
|
4651
4923
|
}
|
|
@@ -4668,9 +4940,12 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4668
4940
|
const base = viteConfig.base.replace(/\/$/, "");
|
|
4669
4941
|
const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
|
|
4670
4942
|
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
4943
|
+
const entrySrc = stripBase(originalSrc);
|
|
4944
|
+
addEntryRemoteImports(entrySrc);
|
|
4945
|
+
const resolvedEntrySrc = entrySrc.startsWith("virtual:") ? toViteEncodedId(entrySrc) : entrySrc;
|
|
4671
4946
|
return toViteEncodedId(`${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
4672
4947
|
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
4673
|
-
entry: sanitizeDevEntryPath(
|
|
4948
|
+
entry: sanitizeDevEntryPath(resolvedEntrySrc)
|
|
4674
4949
|
}).toString()}`);
|
|
4675
4950
|
});
|
|
4676
4951
|
return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
|
|
@@ -4710,8 +4985,8 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4710
4985
|
const inputOptions = getBuildInput(config);
|
|
4711
4986
|
if (!inputOptions) htmlFilePath = path$1.resolve(config.root, "index.html");
|
|
4712
4987
|
else if (typeof inputOptions === "string") entryFiles = [resolveProjectId(inputOptions)];
|
|
4713
|
-
else if (Array.isArray(inputOptions)) entryFiles = inputOptions.map(resolveProjectId);
|
|
4714
|
-
else if (typeof inputOptions === "object") entryFiles = Object.values(inputOptions).map((input) => resolveProjectId(String(input)));
|
|
4988
|
+
else if (Array.isArray(inputOptions)) entryFiles = inputOptions.filter((input) => !isReactRouterClientRouteInput(String(input))).map(resolveProjectId);
|
|
4989
|
+
else if (typeof inputOptions === "object") entryFiles = Object.values(inputOptions).filter((input) => !isReactRouterClientRouteInput(String(input))).map((input) => resolveProjectId(String(input)));
|
|
4715
4990
|
if (entryFiles.length > 0) htmlFilePath = getFirstHtmlEntryFile(entryFiles);
|
|
4716
4991
|
if (htmlFilePath) addHtmlScriptEntries(htmlFilePath);
|
|
4717
4992
|
},
|
|
@@ -4898,6 +5173,7 @@ function checkAliasConflicts(options) {
|
|
|
4898
5173
|
//#region src/plugins/hmr/react.ts
|
|
4899
5174
|
const REACT_REFRESH_PATH = "/@react-refresh";
|
|
4900
5175
|
const LOCAL_REACT_REFRESH_PATH = "/@mf-react-refresh-local";
|
|
5176
|
+
const HOST_REACT_REFRESH_URL = "__MF_REACT_REFRESH_URL__";
|
|
4901
5177
|
function stripQuery(url) {
|
|
4902
5178
|
return url?.replace(/\?.*$/, "");
|
|
4903
5179
|
}
|
|
@@ -4923,7 +5199,7 @@ function resolveReactRefreshRuntime(root) {
|
|
|
4923
5199
|
*/
|
|
4924
5200
|
const REACT_REFRESH_PROXY_MODULE = [
|
|
4925
5201
|
`const __remoteUrl = new URL(import.meta.url);`,
|
|
4926
|
-
`const __target = window.location.origin === __remoteUrl.origin ? new URL('.${LOCAL_REACT_REFRESH_PATH}', __remoteUrl).href : window.location.origin + '${REACT_REFRESH_PATH}';`,
|
|
5202
|
+
`const __target = window.location.origin === __remoteUrl.origin ? new URL('.${LOCAL_REACT_REFRESH_PATH}', __remoteUrl).href : globalThis.${HOST_REACT_REFRESH_URL} || window.location.origin + '${REACT_REFRESH_PATH}';`,
|
|
4927
5203
|
`const __rt = await import(__target);`,
|
|
4928
5204
|
`export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;`,
|
|
4929
5205
|
`export const register = __rt.register;`,
|
|
@@ -4936,6 +5212,14 @@ const REACT_REFRESH_PROXY_MODULE = [
|
|
|
4936
5212
|
const reactAdapter = {
|
|
4937
5213
|
name: "react",
|
|
4938
5214
|
pluginNames: ["vite:react-refresh", "vite:react-swc"],
|
|
5215
|
+
host: { transformIndexHtml({ server }) {
|
|
5216
|
+
const refreshPath = `${server.config.base.replace(/\/$/, "")}${REACT_REFRESH_PATH}`;
|
|
5217
|
+
return [{
|
|
5218
|
+
tag: "script",
|
|
5219
|
+
children: `globalThis.${HOST_REACT_REFRESH_URL} = new URL(${JSON.stringify(refreshPath)}, window.location.origin).href;`,
|
|
5220
|
+
injectTo: "head-prepend"
|
|
5221
|
+
}];
|
|
5222
|
+
} },
|
|
4939
5223
|
remote: { configureServer({ server }) {
|
|
4940
5224
|
let reactRefreshRuntime;
|
|
4941
5225
|
server.middlewares.use((req, res, next) => {
|
|
@@ -5368,6 +5652,203 @@ function pluginDevRemoteHmr(options) {
|
|
|
5368
5652
|
};
|
|
5369
5653
|
}
|
|
5370
5654
|
//#endregion
|
|
5655
|
+
//#region src/plugins/pluginExternalRuntimeCore.ts
|
|
5656
|
+
const EXTERNAL_RUNTIME_CORE_VIRTUAL_ID = "\0virtual:mf-external-runtime-core";
|
|
5657
|
+
/** Package remotes import — rewritten to the host global shim. */
|
|
5658
|
+
const RUNTIME_CORE_PACKAGE = "@module-federation/runtime-core";
|
|
5659
|
+
/**
|
|
5660
|
+
* Already depended on via `@module-federation/runtime`. Prefer this for Node
|
|
5661
|
+
* introspection so we do not need a direct `runtime-core` dependency.
|
|
5662
|
+
*/
|
|
5663
|
+
const RUNTIME_CORE_INTROSPECT_PACKAGE = "@module-federation/runtime/core";
|
|
5664
|
+
function isRuntimeCoreId(id) {
|
|
5665
|
+
return id === "@module-federation/runtime-core" || id === `@module-federation/runtime-core/`;
|
|
5666
|
+
}
|
|
5667
|
+
/** True when the importer is part of an SSR remote graph (skip browser shim). */
|
|
5668
|
+
function isSsrRemoteRuntimeImporter(importer) {
|
|
5669
|
+
if (!importer) return false;
|
|
5670
|
+
return importer.includes("virtual:mf-REMOTE_ENTRY_SSR_ID") || importer.includes("virtual:mf-exposes-ssr:") || importer.includes("/__mf_ssr__/");
|
|
5671
|
+
}
|
|
5672
|
+
function collectRuntimeCoreExportShapes(runtimeCoreModule) {
|
|
5673
|
+
return Object.keys(runtimeCoreModule).filter((key) => key !== "default" && key !== "__esModule").sort().map((name) => ({
|
|
5674
|
+
name,
|
|
5675
|
+
callable: typeof runtimeCoreModule[name] === "function"
|
|
5676
|
+
}));
|
|
5677
|
+
}
|
|
5678
|
+
/**
|
|
5679
|
+
* Builds a shim that defers reading `globalThis._FEDERATION_RUNTIME_CORE` until
|
|
5680
|
+
* an export is accessed. Vite dev does not guarantee host `beforeInit` runs
|
|
5681
|
+
* before remote graph modules evaluate, so an eager throw at import time can
|
|
5682
|
+
* fail even when `provideExternalRuntime` is correctly configured.
|
|
5683
|
+
*/
|
|
5684
|
+
function buildExternalRuntimeCoreShimCode(exportShapes) {
|
|
5685
|
+
return `${[
|
|
5686
|
+
"function __mfGetExternalRuntimeCore() {",
|
|
5687
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5688
|
+
" if (!mod) {",
|
|
5689
|
+
" throw new Error(\"[Module Federation] experiments.externalRuntime is enabled, but globalThis._FEDERATION_RUNTIME_CORE is missing. Enable experiments.provideExternalRuntime on the host consumer.\");",
|
|
5690
|
+
" }",
|
|
5691
|
+
" return mod;",
|
|
5692
|
+
"}",
|
|
5693
|
+
"function __mfCreateLazyRuntimeCoreFunction(exportName) {",
|
|
5694
|
+
" const target = function (...args) {",
|
|
5695
|
+
" return Reflect.apply(__mfGetExternalRuntimeCore()[exportName], this, args);",
|
|
5696
|
+
" };",
|
|
5697
|
+
" return new Proxy(target, {",
|
|
5698
|
+
" get(_target, prop) {",
|
|
5699
|
+
" if (prop === \"__mf_is_external_runtime_core_export\") return true;",
|
|
5700
|
+
" // Avoid thenable detection / introspection throwing before host init.",
|
|
5701
|
+
" if (prop === \"then\") return undefined;",
|
|
5702
|
+
" const value = __mfGetExternalRuntimeCore()[exportName];",
|
|
5703
|
+
" if (prop === \"prototype\") return value?.prototype;",
|
|
5704
|
+
" if (prop === Symbol.hasInstance) {",
|
|
5705
|
+
" return (instance) => instance instanceof value;",
|
|
5706
|
+
" }",
|
|
5707
|
+
" if (value == null) return value;",
|
|
5708
|
+
" const inner = Reflect.get(value, prop, value);",
|
|
5709
|
+
" return typeof inner === \"function\" ? inner.bind(value) : inner;",
|
|
5710
|
+
" },",
|
|
5711
|
+
" set(_target, prop, nextValue) {",
|
|
5712
|
+
" __mfGetExternalRuntimeCore()[exportName][prop] = nextValue;",
|
|
5713
|
+
" return true;",
|
|
5714
|
+
" },",
|
|
5715
|
+
" has(_target, prop) {",
|
|
5716
|
+
" if (prop === \"then\" || prop === \"__mf_is_external_runtime_core_export\") {",
|
|
5717
|
+
" return prop === \"__mf_is_external_runtime_core_export\";",
|
|
5718
|
+
" }",
|
|
5719
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5720
|
+
" if (!mod) return false;",
|
|
5721
|
+
" return prop in Object(mod[exportName]);",
|
|
5722
|
+
" },",
|
|
5723
|
+
" ownKeys() {",
|
|
5724
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5725
|
+
" if (!mod) return [];",
|
|
5726
|
+
" return Reflect.ownKeys(Object(mod[exportName]));",
|
|
5727
|
+
" },",
|
|
5728
|
+
" getOwnPropertyDescriptor(_target, prop) {",
|
|
5729
|
+
" if (prop === \"then\") return undefined;",
|
|
5730
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5731
|
+
" if (!mod) return undefined;",
|
|
5732
|
+
" return Object.getOwnPropertyDescriptor(Object(mod[exportName]), prop);",
|
|
5733
|
+
" },",
|
|
5734
|
+
" apply(_target, thisArg, args) {",
|
|
5735
|
+
" return Reflect.apply(__mfGetExternalRuntimeCore()[exportName], thisArg, args);",
|
|
5736
|
+
" },",
|
|
5737
|
+
" construct(_target, args) {",
|
|
5738
|
+
" const Ctor = __mfGetExternalRuntimeCore()[exportName];",
|
|
5739
|
+
" return new Ctor(...args);",
|
|
5740
|
+
" },",
|
|
5741
|
+
" });",
|
|
5742
|
+
"}",
|
|
5743
|
+
"function __mfCreateLazyRuntimeCoreObject(exportName) {",
|
|
5744
|
+
" return new Proxy(Object.create(null), {",
|
|
5745
|
+
" get(_target, prop) {",
|
|
5746
|
+
" if (prop === \"__mf_is_external_runtime_core_export\") return true;",
|
|
5747
|
+
" if (prop === \"then\") return undefined;",
|
|
5748
|
+
" const value = __mfGetExternalRuntimeCore()[exportName];",
|
|
5749
|
+
" const inner = Reflect.get(value, prop, value);",
|
|
5750
|
+
" return typeof inner === \"function\" ? inner.bind(value) : inner;",
|
|
5751
|
+
" },",
|
|
5752
|
+
" set(_target, prop, nextValue) {",
|
|
5753
|
+
" __mfGetExternalRuntimeCore()[exportName][prop] = nextValue;",
|
|
5754
|
+
" return true;",
|
|
5755
|
+
" },",
|
|
5756
|
+
" has(_target, prop) {",
|
|
5757
|
+
" if (prop === \"then\" || prop === \"__mf_is_external_runtime_core_export\") {",
|
|
5758
|
+
" return prop === \"__mf_is_external_runtime_core_export\";",
|
|
5759
|
+
" }",
|
|
5760
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5761
|
+
" return !!mod && prop in Object(mod[exportName]);",
|
|
5762
|
+
" },",
|
|
5763
|
+
" ownKeys() {",
|
|
5764
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5765
|
+
" return mod ? Reflect.ownKeys(Object(mod[exportName])) : [];",
|
|
5766
|
+
" },",
|
|
5767
|
+
" getOwnPropertyDescriptor(_target, prop) {",
|
|
5768
|
+
" if (prop === \"then\") return undefined;",
|
|
5769
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5770
|
+
" if (!mod) return undefined;",
|
|
5771
|
+
" const descriptor = Object.getOwnPropertyDescriptor(Object(mod[exportName]), prop);",
|
|
5772
|
+
" return descriptor && { ...descriptor, configurable: true };",
|
|
5773
|
+
" },",
|
|
5774
|
+
" });",
|
|
5775
|
+
"}",
|
|
5776
|
+
"export default /*#__PURE__*/ new Proxy(Object.create(null), {",
|
|
5777
|
+
" get(_target, prop) {",
|
|
5778
|
+
" if (prop === \"__esModule\") return true;",
|
|
5779
|
+
" if (prop === \"then\") return undefined;",
|
|
5780
|
+
" const mod = __mfGetExternalRuntimeCore();",
|
|
5781
|
+
" const resolved = mod.default ?? mod;",
|
|
5782
|
+
" const value = resolved[prop];",
|
|
5783
|
+
" return typeof value === \"function\" ? value.bind(resolved) : value;",
|
|
5784
|
+
" },",
|
|
5785
|
+
" has(_target, prop) {",
|
|
5786
|
+
" if (prop === \"then\") return false;",
|
|
5787
|
+
" if (prop === \"__esModule\") return true;",
|
|
5788
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
5789
|
+
" if (!mod) return false;",
|
|
5790
|
+
" const resolved = mod.default ?? mod;",
|
|
5791
|
+
" return prop in Object(resolved);",
|
|
5792
|
+
" },",
|
|
5793
|
+
"});",
|
|
5794
|
+
exportShapes.map(({ name, callable }) => `export const ${name} = /*#__PURE__*/ ${callable ? "__mfCreateLazyRuntimeCoreFunction" : "__mfCreateLazyRuntimeCoreObject"}(${JSON.stringify(name)});`).join("\n")
|
|
5795
|
+
].filter(Boolean).join("\n")}\n`;
|
|
5796
|
+
}
|
|
5797
|
+
let cachedExportShapes;
|
|
5798
|
+
async function importRuntimeCoreForIntrospection(packageName) {
|
|
5799
|
+
try {
|
|
5800
|
+
return await import(pathToFileURL$1(resolveImportPath(packageName)).href);
|
|
5801
|
+
} catch {
|
|
5802
|
+
return await import(packageName);
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
async function resolveRuntimeCoreExportShapes() {
|
|
5806
|
+
if (cachedExportShapes) return cachedExportShapes;
|
|
5807
|
+
try {
|
|
5808
|
+
cachedExportShapes = collectRuntimeCoreExportShapes(await importRuntimeCoreForIntrospection(RUNTIME_CORE_INTROSPECT_PACKAGE));
|
|
5809
|
+
} catch {
|
|
5810
|
+
try {
|
|
5811
|
+
cachedExportShapes = collectRuntimeCoreExportShapes(await importRuntimeCoreForIntrospection(RUNTIME_CORE_PACKAGE));
|
|
5812
|
+
} catch {
|
|
5813
|
+
cachedExportShapes = [];
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
return cachedExportShapes;
|
|
5817
|
+
}
|
|
5818
|
+
/**
|
|
5819
|
+
* Replaces `@module-federation/runtime-core` with a virtual module that reads
|
|
5820
|
+
* `globalThis._FEDERATION_RUNTIME_CORE` (webpack/Rspack `externalRuntime` parity).
|
|
5821
|
+
*/
|
|
5822
|
+
function pluginExternalRuntimeCore() {
|
|
5823
|
+
let shimCodePromise;
|
|
5824
|
+
const getShimCode = () => {
|
|
5825
|
+
if (!shimCodePromise) shimCodePromise = resolveRuntimeCoreExportShapes().then((shapes) => {
|
|
5826
|
+
if (shapes.length === 0) throw createModuleFederationError(`Unable to introspect exports from ${RUNTIME_CORE_INTROSPECT_PACKAGE} for experiments.externalRuntime.`);
|
|
5827
|
+
return buildExternalRuntimeCoreShimCode(shapes);
|
|
5828
|
+
});
|
|
5829
|
+
return shimCodePromise;
|
|
5830
|
+
};
|
|
5831
|
+
return {
|
|
5832
|
+
name: "module-federation-external-runtime-core",
|
|
5833
|
+
enforce: "pre",
|
|
5834
|
+
config(config) {
|
|
5835
|
+
config.optimizeDeps ??= {};
|
|
5836
|
+
config.optimizeDeps.exclude ??= [];
|
|
5837
|
+
if (!config.optimizeDeps.exclude.includes("@module-federation/runtime-core")) config.optimizeDeps.exclude.push(RUNTIME_CORE_PACKAGE);
|
|
5838
|
+
if (Array.isArray(config.optimizeDeps.include)) config.optimizeDeps.include = config.optimizeDeps.include.filter((dep) => dep !== "@module-federation/runtime-core" && !String(dep).startsWith(`@module-federation/runtime-core/`));
|
|
5839
|
+
},
|
|
5840
|
+
resolveId(source, importer) {
|
|
5841
|
+
if (!isRuntimeCoreId(source)) return;
|
|
5842
|
+
if (isSsrRemoteRuntimeImporter(importer)) return;
|
|
5843
|
+
return EXTERNAL_RUNTIME_CORE_VIRTUAL_ID;
|
|
5844
|
+
},
|
|
5845
|
+
async load(id) {
|
|
5846
|
+
if (id !== "\0virtual:mf-external-runtime-core") return;
|
|
5847
|
+
return getShimCode();
|
|
5848
|
+
}
|
|
5849
|
+
};
|
|
5850
|
+
}
|
|
5851
|
+
//#endregion
|
|
5371
5852
|
//#region src/virtualModules/index.ts
|
|
5372
5853
|
function initVirtualModules(command, remoteEntryId, enableSsrInit = false, options) {
|
|
5373
5854
|
writeLocalSharedImportMap(options);
|
|
@@ -5761,7 +6242,7 @@ function getVirtualExposesSSRId(options) {
|
|
|
5761
6242
|
* build so Node resolves them via its own module cache — this is what
|
|
5762
6243
|
* guarantees the React singleton is shared with react-dom/server.
|
|
5763
6244
|
*/
|
|
5764
|
-
function generateExposesSSR(options) {
|
|
6245
|
+
function generateExposesSSR(options, reactIslandExposes = /* @__PURE__ */ new Set()) {
|
|
5765
6246
|
return `
|
|
5766
6247
|
export default {
|
|
5767
6248
|
${Object.keys(options.exposes).map((key) => {
|
|
@@ -5770,6 +6251,7 @@ function generateExposesSSR(options) {
|
|
|
5770
6251
|
const importModule = await import(${JSON.stringify(options.exposes[key].import)})
|
|
5771
6252
|
const exportModule = {}
|
|
5772
6253
|
Object.assign(exportModule, importModule)
|
|
6254
|
+
${generateReactIslandSSRDefinition(reactIslandExposes.has(key))}
|
|
5773
6255
|
Object.defineProperty(exportModule, "__esModule", {
|
|
5774
6256
|
value: true,
|
|
5775
6257
|
enumerable: false
|
|
@@ -6354,12 +6836,16 @@ function resolveDevHashEntryFileName(fileName) {
|
|
|
6354
6836
|
return path$1.extname(baseName) ? normalized : `${normalized}.js`;
|
|
6355
6837
|
}
|
|
6356
6838
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
6357
|
-
let viteConfig, _command, root;
|
|
6839
|
+
let viteConfig, _command, root, originalConfigBase;
|
|
6358
6840
|
let exposeRemoteDependencies = {};
|
|
6359
6841
|
let exposeRemoteDependenciesDirty = true;
|
|
6360
6842
|
let refreshPromise;
|
|
6361
6843
|
let dependencyInvalidationVersion = 0;
|
|
6362
|
-
|
|
6844
|
+
let reactIslandExposes = /* @__PURE__ */ new Set();
|
|
6845
|
+
const isHostAutoInitId = (id) => {
|
|
6846
|
+
const cleanId = id.split("?")[0];
|
|
6847
|
+
return cleanId.includes(getHostAutoInitPath(options)) || cleanId.includes(getHostAutoInitPath());
|
|
6848
|
+
};
|
|
6363
6849
|
function isRemoteImport(source) {
|
|
6364
6850
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
6365
6851
|
}
|
|
@@ -6425,9 +6911,11 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6425
6911
|
configResolved(config) {
|
|
6426
6912
|
viteConfig = config;
|
|
6427
6913
|
root = config.root;
|
|
6914
|
+
reactIslandExposes = getReactIslandExposes(options, root);
|
|
6428
6915
|
},
|
|
6429
|
-
config(
|
|
6916
|
+
config(config, { command }) {
|
|
6430
6917
|
_command = command;
|
|
6918
|
+
originalConfigBase = config.base;
|
|
6431
6919
|
},
|
|
6432
6920
|
async buildStart() {
|
|
6433
6921
|
await refreshExposeRemoteDependencies(this);
|
|
@@ -6460,7 +6948,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6460
6948
|
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
6461
6949
|
if (id === virtualExposesId) {
|
|
6462
6950
|
await refreshExposeRemoteDependencies(this);
|
|
6463
|
-
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
6951
|
+
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
6464
6952
|
}
|
|
6465
6953
|
if (_command === "serve" && isHostAutoInitId(id)) return id;
|
|
6466
6954
|
},
|
|
@@ -6470,12 +6958,12 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6470
6958
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
6471
6959
|
if (id === virtualExposesId) {
|
|
6472
6960
|
await refreshExposeRemoteDependencies(this);
|
|
6473
|
-
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
6961
|
+
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
6474
6962
|
}
|
|
6475
6963
|
if (isHostAutoInitId(id)) {
|
|
6476
6964
|
if (_command === "serve") {
|
|
6477
6965
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
6478
|
-
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base);
|
|
6966
|
+
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base, originalConfigBase);
|
|
6479
6967
|
const publicPath = JSON.stringify((resolvedPublicPath === "auto" ? "/" : resolvedPublicPath) + resolveDevHashEntryFileName(options.filename));
|
|
6480
6968
|
const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
|
|
6481
6969
|
const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
|
|
@@ -7393,6 +7881,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7393
7881
|
let isServe = false;
|
|
7394
7882
|
let viteConfig;
|
|
7395
7883
|
let isNuxtProject = false;
|
|
7884
|
+
let reactIslandExposes = /* @__PURE__ */ new Set();
|
|
7396
7885
|
const findNuxtExposesChunk = (bundle) => {
|
|
7397
7886
|
const exposeKeys = Object.keys(options.exposes);
|
|
7398
7887
|
if (exposeKeys.length === 0) return;
|
|
@@ -7436,6 +7925,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7436
7925
|
configResolved(config) {
|
|
7437
7926
|
viteConfig = config;
|
|
7438
7927
|
isNuxtProject = isNuxtProjectRoot(config.root);
|
|
7928
|
+
reactIslandExposes = getReactIslandExposes(options, config.root);
|
|
7439
7929
|
},
|
|
7440
7930
|
configureServer(server) {
|
|
7441
7931
|
const base = "/__mf_ssr__";
|
|
@@ -7503,7 +7993,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7503
7993
|
server.middlewares.use(exposesPath, (_req, res) => {
|
|
7504
7994
|
res.setHeader("Content-Type", "application/javascript");
|
|
7505
7995
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
7506
|
-
res.end(generateExposesSSR(options));
|
|
7996
|
+
res.end(generateExposesSSR(options, reactIslandExposes));
|
|
7507
7997
|
});
|
|
7508
7998
|
},
|
|
7509
7999
|
resolveId(id) {
|
|
@@ -7514,7 +8004,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7514
8004
|
},
|
|
7515
8005
|
load(id) {
|
|
7516
8006
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return generateRemoteEntrySSR(options);
|
|
7517
|
-
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return generateExposesSSR(options);
|
|
8007
|
+
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return generateExposesSSR(options, reactIslandExposes);
|
|
7518
8008
|
},
|
|
7519
8009
|
buildStart() {
|
|
7520
8010
|
if (isServe) return;
|
|
@@ -7766,6 +8256,42 @@ function isTestEnv() {
|
|
|
7766
8256
|
return process.env.NODE_ENV === "test" || process.env.VITEST != null || process.env.JEST_WORKER_ID != null;
|
|
7767
8257
|
}
|
|
7768
8258
|
//#endregion
|
|
8259
|
+
//#region src/utils/sharedExportConditions.ts
|
|
8260
|
+
const DEFAULT_CLIENT_EXPORT_CONDITIONS = [
|
|
8261
|
+
"browser",
|
|
8262
|
+
"import",
|
|
8263
|
+
"module",
|
|
8264
|
+
"default"
|
|
8265
|
+
];
|
|
8266
|
+
const DEFAULT_NODE_SSR_EXPORT_CONDITIONS = [
|
|
8267
|
+
"node",
|
|
8268
|
+
"import",
|
|
8269
|
+
"module",
|
|
8270
|
+
"default"
|
|
8271
|
+
];
|
|
8272
|
+
const DEFAULT_WEBWORKER_SSR_EXPORT_CONDITIONS = [
|
|
8273
|
+
"worker",
|
|
8274
|
+
"browser",
|
|
8275
|
+
"import",
|
|
8276
|
+
"module",
|
|
8277
|
+
"default"
|
|
8278
|
+
];
|
|
8279
|
+
const VITE_DEV_PROD_CONDITION = "development|production";
|
|
8280
|
+
function appendConditions(conditions, fallbackConditions) {
|
|
8281
|
+
return [...new Set([...conditions, ...fallbackConditions])];
|
|
8282
|
+
}
|
|
8283
|
+
function resolveViteModeCondition(conditions, isProduction) {
|
|
8284
|
+
const modeCondition = isProduction ? "production" : "development";
|
|
8285
|
+
return [...new Set(conditions.map((condition) => condition === VITE_DEV_PROD_CONDITION ? modeCondition : condition))];
|
|
8286
|
+
}
|
|
8287
|
+
function getSharedExportConditions({ environmentConditions, isProduction, isSsr, rootConditions, ssrConditions, ssrTarget = "node" }) {
|
|
8288
|
+
if (environmentConditions !== void 0) return resolveViteModeCondition(appendConditions(environmentConditions, ["import", "default"]), isProduction);
|
|
8289
|
+
const defaultConditions = isSsr ? ssrTarget === "webworker" ? DEFAULT_WEBWORKER_SSR_EXPORT_CONDITIONS : DEFAULT_NODE_SSR_EXPORT_CONDITIONS : DEFAULT_CLIENT_EXPORT_CONDITIONS;
|
|
8290
|
+
const configuredConditions = isSsr ? ssrConditions ?? rootConditions : rootConditions;
|
|
8291
|
+
if (configuredConditions !== void 0) return resolveViteModeCondition(appendConditions(configuredConditions, defaultConditions), isProduction);
|
|
8292
|
+
return [...defaultConditions];
|
|
8293
|
+
}
|
|
8294
|
+
//#endregion
|
|
7769
8295
|
//#region src/utils/normalizeOptimizeDeps.ts
|
|
7770
8296
|
var normalizeOptimizeDeps_default = {
|
|
7771
8297
|
name: "normalizeOptimizeDeps",
|
|
@@ -7857,6 +8383,9 @@ function isSharedResolverInternalImporter(importer) {
|
|
|
7857
8383
|
function isCommonJsImporter(importer) {
|
|
7858
8384
|
return !!importer && (importer.endsWith(".cjs") || importer.includes("/cjs/"));
|
|
7859
8385
|
}
|
|
8386
|
+
function isReactDomSelfReference(source, importer) {
|
|
8387
|
+
return source === "react-dom" && getPackageNameFromNodeModulePath(importer ?? "") === "react-dom";
|
|
8388
|
+
}
|
|
7860
8389
|
function isOutputChunk(chunk) {
|
|
7861
8390
|
return chunk.type === "chunk";
|
|
7862
8391
|
}
|
|
@@ -7911,10 +8440,57 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
7911
8440
|
function canResolveSharedSubpath(subpath, projectRoot) {
|
|
7912
8441
|
try {
|
|
7913
8442
|
return isViteOptimizableEntry(createRequire$1(pathToFileURL(path$1.join(projectRoot, "package.json"))).resolve(subpath));
|
|
7914
|
-
} catch {
|
|
8443
|
+
} catch (error) {
|
|
8444
|
+
if (error?.code === "ERR_PACKAGE_PATH_NOT_EXPORTED" && !isBarePackageSubpath(subpath)) {
|
|
8445
|
+
const entry = resolveViteImportPackageEntry(subpath, projectRoot);
|
|
8446
|
+
return entry !== void 0 && existsSync(entry) && isViteOptimizableEntry(entry);
|
|
8447
|
+
}
|
|
7915
8448
|
return false;
|
|
7916
8449
|
}
|
|
7917
8450
|
}
|
|
8451
|
+
const VITE_DEV_IMPORT_CONDITIONS = new Set([
|
|
8452
|
+
"browser",
|
|
8453
|
+
"development",
|
|
8454
|
+
"import",
|
|
8455
|
+
"module",
|
|
8456
|
+
"default"
|
|
8457
|
+
]);
|
|
8458
|
+
function resolveConditionalExportTarget(target) {
|
|
8459
|
+
if (typeof target === "string") return target;
|
|
8460
|
+
if (Array.isArray(target)) {
|
|
8461
|
+
for (const candidate of target) {
|
|
8462
|
+
const resolved = resolveConditionalExportTarget(candidate);
|
|
8463
|
+
if (resolved) return resolved;
|
|
8464
|
+
}
|
|
8465
|
+
return;
|
|
8466
|
+
}
|
|
8467
|
+
if (!target || typeof target !== "object") return void 0;
|
|
8468
|
+
for (const [condition, candidate] of Object.entries(target)) {
|
|
8469
|
+
if (!VITE_DEV_IMPORT_CONDITIONS.has(condition)) continue;
|
|
8470
|
+
const resolved = resolveConditionalExportTarget(candidate);
|
|
8471
|
+
if (resolved) return resolved;
|
|
8472
|
+
}
|
|
8473
|
+
}
|
|
8474
|
+
function resolveViteImportPackageEntry(packageName, projectRoot) {
|
|
8475
|
+
const installed = getInstalledPackageJson(packageName, { cwd: projectRoot });
|
|
8476
|
+
if (!installed) return void 0;
|
|
8477
|
+
const exportsField = installed.packageJson.exports;
|
|
8478
|
+
let rootExport = exportsField;
|
|
8479
|
+
if (exportsField && typeof exportsField === "object" && !Array.isArray(exportsField)) {
|
|
8480
|
+
const exportsRecord = exportsField;
|
|
8481
|
+
if (Object.keys(exportsRecord).some((key) => key.startsWith("."))) rootExport = exportsRecord["."];
|
|
8482
|
+
}
|
|
8483
|
+
const target = resolveConditionalExportTarget(rootExport);
|
|
8484
|
+
if (!target?.startsWith("./")) return void 0;
|
|
8485
|
+
const resolved = path$1.resolve(installed.dir, target);
|
|
8486
|
+
const relative = path$1.relative(installed.dir, resolved);
|
|
8487
|
+
if (relative.startsWith(`..${path$1.sep}`) || path$1.isAbsolute(relative)) return void 0;
|
|
8488
|
+
return resolved;
|
|
8489
|
+
}
|
|
8490
|
+
function isBarePackageSubpath(specifier) {
|
|
8491
|
+
const segments = specifier.split("/");
|
|
8492
|
+
return specifier.startsWith("@") ? segments.length > 2 : segments.length > 1;
|
|
8493
|
+
}
|
|
7918
8494
|
/**
|
|
7919
8495
|
* Vite's dependency scanner cannot see through the virtual loadShare modules
|
|
7920
8496
|
* generated for shared packages. As a result, dependencies of a linked/shared
|
|
@@ -7990,8 +8566,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
7990
8566
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
7991
8567
|
name: "module-federation:optimize-shared-resolver",
|
|
7992
8568
|
load(id) {
|
|
7993
|
-
if (id
|
|
7994
|
-
const
|
|
8569
|
+
if (!id.startsWith("module-federation:optimized-require-")) return;
|
|
8570
|
+
const sourcePackage = id.slice(36);
|
|
8571
|
+
if (sourcePackage !== "react" && sourcePackage !== "react-dom") return;
|
|
8572
|
+
const loadSharePath = getLoadShareModulePath(sourcePackage, isRolldown, options);
|
|
7995
8573
|
const source = JSON.stringify(loadSharePath);
|
|
7996
8574
|
return "import * as __mfShared from " + source + ";\nexport * from " + source + ";\nexport default __mfShared.default ?? __mfShared;";
|
|
7997
8575
|
},
|
|
@@ -8007,13 +8585,14 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
8007
8585
|
const shareItem = shared[key];
|
|
8008
8586
|
const isReactSingleton = source === "react" && key === "react" && shareItem.shareConfig?.singleton === true;
|
|
8009
8587
|
const isReactRequire = resolveOptions?.kind?.startsWith("require") && isReactSingleton;
|
|
8010
|
-
|
|
8011
|
-
if (
|
|
8012
|
-
if (
|
|
8588
|
+
const isReactDomRequire = resolveOptions?.kind?.startsWith("require") && isReactDomSelfReference(source, importer);
|
|
8589
|
+
if (resolveOptions?.kind?.startsWith("require") && !isReactRequire && !isReactDomRequire) return;
|
|
8590
|
+
if (isCommonJsImporter(importer) && !isReactSingleton && !isReactDomRequire) return;
|
|
8591
|
+
if (isReactRequire || isReactDomRequire) {
|
|
8013
8592
|
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
8014
8593
|
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
8015
8594
|
addUsedShares(source, options);
|
|
8016
|
-
return { id:
|
|
8595
|
+
return { id: `module-federation:optimized-require-${source}` };
|
|
8017
8596
|
}
|
|
8018
8597
|
const loadSharePath = getLoadShareModulePath(source, isRolldown, options);
|
|
8019
8598
|
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
@@ -8040,7 +8619,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
8040
8619
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
8041
8620
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
8042
8621
|
if (!findSharedKey(args.path, shared) || isAssetLikeImport(args.path)) return;
|
|
8043
|
-
if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path)) return;
|
|
8622
|
+
if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path) && !isReactDomSelfReference(args.path, args.importer)) return;
|
|
8044
8623
|
return {
|
|
8045
8624
|
path: args.path,
|
|
8046
8625
|
namespace: "mf-shared"
|
|
@@ -8110,8 +8689,10 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
8110
8689
|
writeLoadShareModule(subpath, shareItem, _command, isRolldown, options);
|
|
8111
8690
|
writePreBuildLibPath(subpath, shareItem, options);
|
|
8112
8691
|
addUsedShares(subpath, options);
|
|
8113
|
-
if (canResolveSubpath)
|
|
8114
|
-
|
|
8692
|
+
if (canResolveSubpath) {
|
|
8693
|
+
optimizeDeps.include.push(subpath);
|
|
8694
|
+
if (key === "react-dom") optimizeDeps.include.push(`${key} > ${subpath}`);
|
|
8695
|
+
} else optimizeDeps.exclude.push(subpath);
|
|
8115
8696
|
}
|
|
8116
8697
|
}
|
|
8117
8698
|
}
|
|
@@ -8169,11 +8750,39 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
8169
8750
|
}
|
|
8170
8751
|
function loadPluginDts(options) {
|
|
8171
8752
|
if (options.dts === false) return [];
|
|
8172
|
-
return [import("./pluginDts-
|
|
8753
|
+
return [import("./pluginDts-Dbbi4cnh.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
|
|
8754
|
+
}
|
|
8755
|
+
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
8756
|
+
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
8757
|
+
return specifier === INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN || specifier.includes("injectExternalRuntimeCorePlugin") || specifier.includes("inject-external-runtime-core-plugin");
|
|
8758
|
+
}
|
|
8759
|
+
function hasInjectExternalRuntimeCorePlugin(runtimePlugins) {
|
|
8760
|
+
return runtimePlugins.some((plugin) => {
|
|
8761
|
+
return isInjectExternalRuntimeCorePlugin(typeof plugin === "string" ? plugin : plugin[0]);
|
|
8762
|
+
});
|
|
8763
|
+
}
|
|
8764
|
+
function resolveInjectExternalRuntimeCorePlugin() {
|
|
8765
|
+
try {
|
|
8766
|
+
return normalizePathForImport(resolveImportPath(INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN));
|
|
8767
|
+
} catch {
|
|
8768
|
+
for (const rel of ["./utils/injectExternalRuntimeCorePlugin.js", "./utils/injectExternalRuntimeCorePlugin.ts"]) {
|
|
8769
|
+
const candidate = fileURLToPath(new URL(rel, import.meta.url));
|
|
8770
|
+
if (existsSync(candidate)) return normalizePathForImport(candidate);
|
|
8771
|
+
}
|
|
8772
|
+
return INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN;
|
|
8773
|
+
}
|
|
8774
|
+
}
|
|
8775
|
+
function applyExternalRuntimeExperiments(options) {
|
|
8776
|
+
const { experiments } = options;
|
|
8777
|
+
if (experiments.provideExternalRuntime) {
|
|
8778
|
+
if (Object.keys(options.exposes).length > 0) throw createModuleFederationError("You can only set provideExternalRuntime: true in pure consumer which not expose modules.");
|
|
8779
|
+
if (!hasInjectExternalRuntimeCorePlugin(options.runtimePlugins)) options.runtimePlugins = options.runtimePlugins.concat(resolveInjectExternalRuntimeCorePlugin());
|
|
8780
|
+
}
|
|
8173
8781
|
}
|
|
8174
8782
|
function federation(mfUserOptions) {
|
|
8175
8783
|
if (isTestEnv()) return [];
|
|
8176
8784
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
8785
|
+
applyExternalRuntimeExperiments(options);
|
|
8177
8786
|
const isVinext = hasPackageDependency("vinext");
|
|
8178
8787
|
const { name, shared, filename, hostInitInjectLocation } = options;
|
|
8179
8788
|
const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
@@ -8183,7 +8792,45 @@ function federation(mfUserOptions) {
|
|
|
8183
8792
|
let command;
|
|
8184
8793
|
let desiredRolldownOutput;
|
|
8185
8794
|
let isSsrBuild = false;
|
|
8795
|
+
let isProduction = false;
|
|
8796
|
+
let rootResolveConditions;
|
|
8797
|
+
let ssrResolveConditions;
|
|
8798
|
+
let ssrTarget = "node";
|
|
8186
8799
|
const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
|
|
8800
|
+
const getLoadHookExportConditions = (context, loadOptions) => {
|
|
8801
|
+
const environment = context.environment;
|
|
8802
|
+
const isSsr = loadOptions?.ssr === true || isSsrBuild || environment?.config?.consumer === "server" || Boolean(environment?.config?.build?.ssr) || environment?.name === "ssr" || environment?.name === "server";
|
|
8803
|
+
return getSharedExportConditions({
|
|
8804
|
+
environmentConditions: environment?.config?.resolve?.conditions,
|
|
8805
|
+
isProduction: environment?.config?.isProduction ?? isProduction,
|
|
8806
|
+
isSsr,
|
|
8807
|
+
rootConditions: rootResolveConditions,
|
|
8808
|
+
ssrConditions: ssrResolveConditions,
|
|
8809
|
+
ssrTarget
|
|
8810
|
+
});
|
|
8811
|
+
};
|
|
8812
|
+
const refreshPreBuildModuleForEnvironment = (id, context, loadOptions) => {
|
|
8813
|
+
const pkg = getCachedPreBuildPkg(id);
|
|
8814
|
+
if (!pkg) return "not-applicable";
|
|
8815
|
+
const key = findSharedKey(pkg, shared);
|
|
8816
|
+
if (!key) return "not-applicable";
|
|
8817
|
+
const requestedModule = VirtualModule.findById(id);
|
|
8818
|
+
const ownedModule = VirtualModule.findById(getPreBuildLibImportId(pkg, options));
|
|
8819
|
+
if (!requestedModule || requestedModule !== ownedModule) return "not-owned";
|
|
8820
|
+
writePreBuildLibPath(pkg, shared[key], options, getLoadHookExportConditions(context, loadOptions));
|
|
8821
|
+
return "refreshed";
|
|
8822
|
+
};
|
|
8823
|
+
const refreshLoadShareModuleForEnvironment = (id, context, loadOptions) => {
|
|
8824
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
8825
|
+
if (!pkg) return "not-applicable";
|
|
8826
|
+
const key = findSharedKey(pkg, shared);
|
|
8827
|
+
if (!key) return "not-applicable";
|
|
8828
|
+
const requestedModule = VirtualModule.findById(id);
|
|
8829
|
+
const ownedModule = VirtualModule.findById(getLoadShareModulePath(pkg, false, options));
|
|
8830
|
+
if (!requestedModule || requestedModule !== ownedModule) return "not-owned";
|
|
8831
|
+
writeLoadShareModule(pkg, shared[key], command, getIsRolldown(context), options, getLoadHookExportConditions(context, loadOptions));
|
|
8832
|
+
return "refreshed";
|
|
8833
|
+
};
|
|
8187
8834
|
return [
|
|
8188
8835
|
{
|
|
8189
8836
|
name: "vite:module-federation-virtual-modules",
|
|
@@ -8201,18 +8848,21 @@ function federation(mfUserOptions) {
|
|
|
8201
8848
|
writeLocalSharedImportMap: () => writeLocalSharedImportMap(options),
|
|
8202
8849
|
federationOptions: options
|
|
8203
8850
|
});
|
|
8204
|
-
virtualModule = VirtualModule.findById(id);
|
|
8851
|
+
virtualModule = VirtualModule.findById(id) ?? findCurrentLoadShareForStaleOwnerId(id, options.shared, findSharedKey, options);
|
|
8205
8852
|
}
|
|
8206
8853
|
if (!virtualModule) return;
|
|
8207
8854
|
return virtualModule.getResolvedId();
|
|
8208
8855
|
},
|
|
8209
|
-
load(id) {
|
|
8856
|
+
load(id, loadOptions) {
|
|
8857
|
+
if (command !== "build" && id.includes("__loadShare__") && refreshLoadShareModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
8858
|
+
if (id.includes("__prebuild__") && refreshPreBuildModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
8210
8859
|
const virtualModule = VirtualModule.findById(id);
|
|
8211
8860
|
if (!virtualModule) return;
|
|
8212
8861
|
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
8213
8862
|
return virtualModule.code;
|
|
8214
8863
|
}
|
|
8215
8864
|
},
|
|
8865
|
+
...options.experiments.externalRuntime ? [pluginExternalRuntimeCore()] : [],
|
|
8216
8866
|
createEarlyVirtualModulesPlugin(options),
|
|
8217
8867
|
...isVinext ? [{
|
|
8218
8868
|
name: "module-federation-vinext-react-server-build-alias",
|
|
@@ -8238,7 +8888,11 @@ function federation(mfUserOptions) {
|
|
|
8238
8888
|
config(_config, env) {
|
|
8239
8889
|
command = env.command;
|
|
8240
8890
|
},
|
|
8241
|
-
configResolved() {
|
|
8891
|
+
configResolved(config) {
|
|
8892
|
+
rootResolveConditions = config.resolve?.conditions ? [...config.resolve.conditions] : void 0;
|
|
8893
|
+
ssrResolveConditions = config.ssr?.resolve?.conditions ? [...config.ssr.resolve.conditions] : void 0;
|
|
8894
|
+
ssrTarget = config.ssr?.target ?? "node";
|
|
8895
|
+
isProduction = config.isProduction;
|
|
8242
8896
|
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0);
|
|
8243
8897
|
initVirtualModules(command, remoteEntryId, ssrCapabilities.enableSsrInitBootstrap, options);
|
|
8244
8898
|
}
|
|
@@ -8302,7 +8956,7 @@ function federation(mfUserOptions) {
|
|
|
8302
8956
|
enforce: "pre",
|
|
8303
8957
|
apply: "build",
|
|
8304
8958
|
config(config) {
|
|
8305
|
-
isSsrBuild = config.build?.ssr
|
|
8959
|
+
isSsrBuild = Boolean(config.build?.ssr);
|
|
8306
8960
|
const runtimeInitId = getRuntimeInitStatusImportId(options);
|
|
8307
8961
|
config.build = config.build || {};
|
|
8308
8962
|
if (config.build.modulePreload !== false) {
|
|
@@ -8422,8 +9076,9 @@ function federation(mfUserOptions) {
|
|
|
8422
9076
|
};
|
|
8423
9077
|
}
|
|
8424
9078
|
},
|
|
8425
|
-
load(id) {
|
|
9079
|
+
load(id, loadOptions) {
|
|
8426
9080
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
9081
|
+
if (id.includes("__loadShare__") && refreshLoadShareModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
8427
9082
|
const virtualModule = VirtualModule.findById(id);
|
|
8428
9083
|
if (!virtualModule?.code) return null;
|
|
8429
9084
|
let code = virtualModule.code;
|
|
@@ -8490,7 +9145,7 @@ function federation(mfUserOptions) {
|
|
|
8490
9145
|
_options: options,
|
|
8491
9146
|
config(config, { command: _command }) {
|
|
8492
9147
|
const isRolldown = getIsRolldown(this);
|
|
8493
|
-
isSsrBuild = _command === "build" && config.build?.ssr
|
|
9148
|
+
isSsrBuild = _command === "build" && Boolean(config.build?.ssr);
|
|
8494
9149
|
const needsRuntimeHelpers = Object.keys(options.shared ?? {}).length > 0;
|
|
8495
9150
|
if (needsRuntimeHelpers) appendResolveAlias(config, {
|
|
8496
9151
|
find: /^@module-federation\/runtime\/helpers$/,
|