@module-federation/vite 1.23.1 → 1.23.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/lib/{dtsConstants-Bs4FukGL.js → dtsConstants-DSTzyKSG.js} +12 -3
- package/lib/index.d.ts +1 -260
- package/lib/index.js +629 -143
- package/lib/{logger--uKHOVjR.js → logger-DOwfTlw5.js} +1 -1
- package/lib/normalizeModuleFederationOptions-DNUlv-AL.d.ts +303 -0
- package/lib/{pluginDts-DxgS2FEd.js → pluginDts-CVyHPAEq.js} +3 -3
- package/lib/{ssrEntryLoader-DmqLXUmm.js → ssrEntryLoader-DjZj-5Lw.js} +61 -28
- package/lib/{ssrVmStrategy-B_e3yqa2.js → ssrVmStrategy-Dk5xXVvR.js} +15 -20
- package/lib/utils/ssrEntryLoader.d.ts +2 -59
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as resolvePublicPath, a as matchesSharedSource, c as filterId, d as getNodeModulesSuffix, f as isAssetLikeImport, g as normalizeNodeModulePath, h as isViteOptimizableEntry, i as invalidateSharedKeyMatcher, l as getBasePath$1, m as isNuxtClientBase, n as getSharedRequest, p as isNodeModulePath, r as getSharedRuntimeKey, s as ensureTrailingSlash, t as findSharedKey, u as getCommonSharedSubpaths, v as stripQueryAndHash, y as stripViteFsPrefix } from "./sharedKeyMatcher-Od_nYxJA.js";
|
|
2
|
-
import { a as CodeRewriter, c as
|
|
3
|
-
import { C as isReactCoreShare, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-
|
|
2
|
+
import { a as CodeRewriter, c as isAbsoluteUrl, d as resolveHashPlaceholderFileName, i as createCodePositionMap, l as normalizePathForImport, o as createSourceMap, r as mfWarn, t as createModuleFederationError, u as rebaseImport } from "./logger-DOwfTlw5.js";
|
|
3
|
+
import { C as isReactCoreShare, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-DSTzyKSG.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as fs$2 from "fs";
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -15,6 +15,8 @@ import * as fs$1 from "node:fs";
|
|
|
15
15
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
|
|
16
16
|
import { pathToFileURL as pathToFileURL$1 } from "node:url";
|
|
17
17
|
import { isIPv6 } from "node:net";
|
|
18
|
+
import { inferAutoPublicPath } from "@module-federation/sdk";
|
|
19
|
+
import { readFile } from "node:fs/promises";
|
|
18
20
|
//#region src/utils/regexEscape.ts
|
|
19
21
|
const REGEXP_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
|
|
20
22
|
/**
|
|
@@ -279,9 +281,17 @@ function isClientEnvironment(ctx) {
|
|
|
279
281
|
* the legacy root `build.ssr` flag.
|
|
280
282
|
*/
|
|
281
283
|
function isServerBuildContext(ctx, config) {
|
|
284
|
+
return isServerContext(ctx, Boolean(config?.build?.ssr));
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Whether a hook runs for a server graph. Hooks without an environment context
|
|
288
|
+
* (Vite 5) use `legacySsr`, such as the root `build.ssr` flag or the load
|
|
289
|
+
* hook's `ssr` option.
|
|
290
|
+
*/
|
|
291
|
+
function isServerContext(ctx, legacySsr) {
|
|
282
292
|
const target = resolveEnvironmentConsumerTarget(ctx);
|
|
283
293
|
if (target) return target === "server";
|
|
284
|
-
return
|
|
294
|
+
return legacySsr;
|
|
285
295
|
}
|
|
286
296
|
function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
287
297
|
if (!hasMultiEnvironment) return "unified";
|
|
@@ -723,13 +733,18 @@ function normalizeExperiments(experiments) {
|
|
|
723
733
|
return {
|
|
724
734
|
externalRuntime: experiments?.externalRuntime === true,
|
|
725
735
|
provideExternalRuntime: experiments?.provideExternalRuntime === true,
|
|
726
|
-
ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0
|
|
736
|
+
ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0,
|
|
737
|
+
hostProvidesAllShared: experiments?.hostProvidesAllShared === true
|
|
727
738
|
};
|
|
728
739
|
}
|
|
729
740
|
function normalizeSsrEntryLoader(ssrEntryLoader) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
741
|
+
if (!ssrEntryLoader) return void 0;
|
|
742
|
+
const normalized = {};
|
|
743
|
+
if (ssrEntryLoader.strategy === "temp-file" || ssrEntryLoader.strategy === "vm") normalized.strategy = ssrEntryLoader.strategy;
|
|
744
|
+
if (Number.isFinite(ssrEntryLoader.maxAgeMs)) normalized.maxAgeMs = ssrEntryLoader.maxAgeMs;
|
|
745
|
+
if (Number.isFinite(ssrEntryLoader.fetchTimeoutMs)) normalized.fetchTimeoutMs = ssrEntryLoader.fetchTimeoutMs;
|
|
746
|
+
if (Number.isFinite(ssrEntryLoader.fetchMaxBytes)) normalized.fetchMaxBytes = ssrEntryLoader.fetchMaxBytes;
|
|
747
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
733
748
|
}
|
|
734
749
|
let config;
|
|
735
750
|
let explicitSharedKeys = /* @__PURE__ */ new Set();
|
|
@@ -3297,7 +3312,7 @@ function generateEagerWorkspaceSingletonExports(edges, namedExports, importSourc
|
|
|
3297
3312
|
__mfApplyEagerShareExportsWhenReady(exportModule);
|
|
3298
3313
|
export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
|
|
3299
3314
|
}
|
|
3300
|
-
function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false) {
|
|
3315
|
+
function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false, ssrLocalFallback = true) {
|
|
3301
3316
|
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3302
3317
|
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3303
3318
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
@@ -3337,7 +3352,7 @@ function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource
|
|
|
3337
3352
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3338
3353
|
});
|
|
3339
3354
|
})`;
|
|
3340
|
-
const synchronousFallbackConditions = [...
|
|
3355
|
+
const synchronousFallbackConditions = [...ssrLocalFallback ? ["import.meta.env.SSR"] : [], ...serveLocalFallback ? ["(import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')"] : []];
|
|
3341
3356
|
const trackPendingLoad = `__mfTrackPendingShareLoad(${deferredEntryFallback ? deferredEntryLoad : deferredInitLoad});`;
|
|
3342
3357
|
return `${declarations}
|
|
3343
3358
|
const __mfApplyLazyShareExports = (mod) => {
|
|
@@ -3543,7 +3558,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3543
3558
|
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3544
3559
|
} else if (usesDeferredEntryInjectedSingletonFallback) {
|
|
3545
3560
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3546
|
-
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true);
|
|
3561
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true, pkg !== REACT_DOM_CLIENT_SHARE);
|
|
3547
3562
|
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, liveNamedExports);
|
|
3548
3563
|
else if (usesDeferredSingletonFallback) {
|
|
3549
3564
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
@@ -3738,16 +3753,22 @@ function generateLocalSharedImportMap(options) {
|
|
|
3738
3753
|
const __mfGetCachedReactFamily = (keys, reactKeys, localVersion, requiredExport) => {
|
|
3739
3754
|
const cache = globalThis.__mf_module_cache__?.share;
|
|
3740
3755
|
const react = reactKeys.map((key) => cache?.[key]).find((value) => value !== undefined);
|
|
3741
|
-
const
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3756
|
+
const isOlder = (version) => {
|
|
3757
|
+
const actual = String(version || '').split(/[^0-9]+/).map(Number);
|
|
3758
|
+
const expected = String(localVersion || '').split(/[^0-9]+/).map(Number);
|
|
3759
|
+
for (let index = 0; index < Math.max(actual.length, expected.length); index++) {
|
|
3760
|
+
if ((actual[index] || 0) < (expected[index] || 0)) return true;
|
|
3761
|
+
if ((actual[index] || 0) > (expected[index] || 0)) return false;
|
|
3762
|
+
}
|
|
3763
|
+
return false;
|
|
3764
|
+
};
|
|
3765
|
+
if (isOlder(react?.version ?? react?.default?.version)) return undefined;
|
|
3748
3766
|
for (const key of keys) {
|
|
3749
3767
|
const cached = cache?.[key];
|
|
3750
3768
|
if (cached === undefined) continue;
|
|
3769
|
+
// A host seed from an older React family is not coherent with the newer cached react
|
|
3770
|
+
const cachedVersion = cached?.version ?? cached?.default?.version;
|
|
3771
|
+
if (cachedVersion !== undefined && isOlder(cachedVersion)) continue;
|
|
3751
3772
|
if (!requiredExport || typeof cached?.[requiredExport] === 'function' || typeof cached?.default?.[requiredExport] === 'function') return cached;
|
|
3752
3773
|
}
|
|
3753
3774
|
return undefined;
|
|
@@ -5830,6 +5851,22 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5830
5851
|
}));
|
|
5831
5852
|
}
|
|
5832
5853
|
` : ""}
|
|
5854
|
+
// The seed called this container's get() directly, so the Runtime's
|
|
5855
|
+
// provider never learned it is in use and a remote could load its own
|
|
5856
|
+
// copy (#1396). Mark it once the host is bound to the local copy.
|
|
5857
|
+
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
5858
|
+
if (!share.lib || share.treeShaking || share.shareConfig?.import === false) continue;
|
|
5859
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
5860
|
+
if (__mfReadSharedCacheOwner(__mfModuleCache.share, cacheDescriptor) !== ${cacheOwner}) continue;
|
|
5861
|
+
for (const scopeName of Array.isArray(share.scope) ? share.scope : [share.scope || "default"]) {
|
|
5862
|
+
const versions = runtime.shareScopeMap?.[scopeName]?.[pkg];
|
|
5863
|
+
const provider = versions?.[share.version];
|
|
5864
|
+
if (!provider || provider.get !== share.get || provider.lib) continue;
|
|
5865
|
+
if (Object.values(versions).some((other) => other !== provider && (other?.lib || other?.loaded))) continue;
|
|
5866
|
+
provider.lib = share.lib;
|
|
5867
|
+
provider.loaded = true;
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5833
5870
|
return runtime;
|
|
5834
5871
|
})();
|
|
5835
5872
|
}
|
|
@@ -6196,9 +6233,23 @@ function getLazyRemotePendingExport() {
|
|
|
6196
6233
|
};`;
|
|
6197
6234
|
}
|
|
6198
6235
|
function getEagerRemotePendingExport() {
|
|
6199
|
-
return `export
|
|
6236
|
+
return `export let __mf_remote_pending =
|
|
6200
6237
|
__mfRemotePending ??
|
|
6201
|
-
__mfStartRemoteLoad().then(__mfAssignRemoteModule)
|
|
6238
|
+
__mfStartRemoteLoad().then(__mfAssignRemoteModule);
|
|
6239
|
+
__mf_remote_pending.then(undefined, () => {
|
|
6240
|
+
let attempt;
|
|
6241
|
+
const retry = {
|
|
6242
|
+
then(onFulfilled, onRejected) {
|
|
6243
|
+
attempt ||= __mfStartRemoteLoad().then(__mfAssignRemoteModule, (error) => {
|
|
6244
|
+
attempt = undefined;
|
|
6245
|
+
throw error;
|
|
6246
|
+
});
|
|
6247
|
+
return attempt.then(onFulfilled, onRejected);
|
|
6248
|
+
},
|
|
6249
|
+
};
|
|
6250
|
+
if (__mfRemotePending) __mfRemotePending = retry;
|
|
6251
|
+
__mf_remote_pending = retry;
|
|
6252
|
+
});`;
|
|
6202
6253
|
}
|
|
6203
6254
|
function getServerThenExport() {
|
|
6204
6255
|
return `export function then(onFulfilled, onRejected) {
|
|
@@ -6212,7 +6263,15 @@ function getServerThenExport() {
|
|
|
6212
6263
|
__moduleExports: exportModule,
|
|
6213
6264
|
__mf_remote_pending: __mfRemotePending,
|
|
6214
6265
|
};
|
|
6215
|
-
})
|
|
6266
|
+
}, () => ({
|
|
6267
|
+
get default() {
|
|
6268
|
+
return __mfDefaultExport;
|
|
6269
|
+
},
|
|
6270
|
+
get __moduleExports() {
|
|
6271
|
+
return exportModule;
|
|
6272
|
+
},
|
|
6273
|
+
__mf_remote_pending: { then: (resolve, reject) => __mf_remote_pending.then(resolve, reject) },
|
|
6274
|
+
}))
|
|
6216
6275
|
.then(onFulfilled, onRejected);
|
|
6217
6276
|
}`;
|
|
6218
6277
|
}
|
|
@@ -6456,6 +6515,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
6456
6515
|
let emittedFileName;
|
|
6457
6516
|
let skipTransformIds = /* @__PURE__ */ new Set();
|
|
6458
6517
|
let injectedTransformIds = /* @__PURE__ */ new Set();
|
|
6518
|
+
const virtualEntryCode = /* @__PURE__ */ new Map();
|
|
6459
6519
|
const ignoredHtmlScriptSources = /* @__PURE__ */ new Set();
|
|
6460
6520
|
let bootstrapDir = "";
|
|
6461
6521
|
function skipSvelteKitSsrBuild() {
|
|
@@ -6841,7 +6901,12 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6841
6901
|
}
|
|
6842
6902
|
if (htmlFilePath) addHtmlScriptEntries(htmlFilePath);
|
|
6843
6903
|
},
|
|
6844
|
-
buildStart() {
|
|
6904
|
+
async buildStart() {
|
|
6905
|
+
if (inject === "entry" && waitsForInit && isClientEnvironment(this)) for (const entry of [...entryFiles]) {
|
|
6906
|
+
if (path$1.isAbsolute(entry)) continue;
|
|
6907
|
+
const resolved = await this.resolve(entry, void 0, { skipSelf: true }).catch(() => null);
|
|
6908
|
+
if (resolved && !resolved.external && (_command === "serve" || !resolved.id.startsWith("\0"))) addEntryFile(resolveProjectId(resolved.id));
|
|
6909
|
+
}
|
|
6845
6910
|
if (_command === "serve") return;
|
|
6846
6911
|
if (skipSvelteKitSsrBuild()) return;
|
|
6847
6912
|
if (this.environment?.name === "ssr") return;
|
|
@@ -6947,11 +7012,18 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6947
7012
|
};
|
|
6948
7013
|
setTimeout(retry, 0);
|
|
6949
7014
|
},
|
|
7015
|
+
load(id) {
|
|
7016
|
+
return virtualEntryCode.get(id);
|
|
7017
|
+
},
|
|
6950
7018
|
transform(code, id) {
|
|
6951
7019
|
if (skipSvelteKitSsrBuild()) return;
|
|
6952
7020
|
if (viteConfig?.command === "build" && !waitsForInit) return;
|
|
6953
7021
|
if (isSvelteKitServerModule(id)) return;
|
|
6954
|
-
if (hasEntryBootstrapParam(id)) return
|
|
7022
|
+
if (hasEntryBootstrapParam(id)) return {
|
|
7023
|
+
code,
|
|
7024
|
+
map: null,
|
|
7025
|
+
moduleSideEffects: true
|
|
7026
|
+
};
|
|
6955
7027
|
if (normalizeModuleId(id).endsWith(".html")) return;
|
|
6956
7028
|
const projectId = resolveProjectId(id);
|
|
6957
7029
|
if (skipTransformIds.has(projectId)) return;
|
|
@@ -6985,7 +7057,11 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6985
7057
|
clientInjected = true;
|
|
6986
7058
|
injectedTransformIds.add(projectId);
|
|
6987
7059
|
if (!waitsForInit) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
|
|
6988
|
-
|
|
7060
|
+
let entrySrc = id.includes("?") ? `${id}&${ENTRY_BOOTSTRAP_QUERY.slice(1)}` : `${id}${ENTRY_BOOTSTRAP_QUERY}`;
|
|
7061
|
+
if (entrySrc.startsWith("\0")) {
|
|
7062
|
+
virtualEntryCode.set(entrySrc, code);
|
|
7063
|
+
entrySrc = toViteEncodedId(entrySrc.slice(1));
|
|
7064
|
+
}
|
|
6989
7065
|
return mapCodeToCodeWithSourcemap(getBootstrapSource(getEntryPath(), entrySrc, false, { skipRemotePreload: _command === "serve" && isNuxtEntryAsyncModule }));
|
|
6990
7066
|
}
|
|
6991
7067
|
}
|
|
@@ -8058,7 +8134,7 @@ function ${helperName}(names) {
|
|
|
8058
8134
|
}
|
|
8059
8135
|
//#endregion
|
|
8060
8136
|
//#region package.json
|
|
8061
|
-
var version$1 = "1.23.
|
|
8137
|
+
var version$1 = "1.23.3";
|
|
8062
8138
|
//#endregion
|
|
8063
8139
|
//#region src/virtualModules/virtualExposesSSR.ts
|
|
8064
8140
|
/**
|
|
@@ -8160,6 +8236,8 @@ function generateRemoteEntrySSR(options) {
|
|
|
8160
8236
|
const sharedSingletons = ${JSON.stringify(sharedSingletons)};
|
|
8161
8237
|
const moduleCacheKey = Symbol.for(${JSON.stringify(MODULE_CACHE_SHARE_SCOPE_KEY)});
|
|
8162
8238
|
let exposesMapPromise;
|
|
8239
|
+
// One identity per container, so a re-entrant init with the same initScope finds it.
|
|
8240
|
+
const initToken = { from: ${JSON.stringify(options.name)} };
|
|
8163
8241
|
|
|
8164
8242
|
function createShareInitError(errors) {
|
|
8165
8243
|
const details = errors.map(({ scopeName, pkg, error }) => {
|
|
@@ -8188,7 +8266,6 @@ function generateRemoteEntrySSR(options) {
|
|
|
8188
8266
|
remotes: [],
|
|
8189
8267
|
shared: {},
|
|
8190
8268
|
});
|
|
8191
|
-
const initToken = { from: ${JSON.stringify(options.name)} };
|
|
8192
8269
|
if (initScope.indexOf(initToken) >= 0) return;
|
|
8193
8270
|
initScope.push(initToken);
|
|
8194
8271
|
const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)})
|
|
@@ -8525,18 +8602,21 @@ const Manifest = (providedOptions) => {
|
|
|
8525
8602
|
publicPath = mfOptions.publicPath === "auto" ? "auto" : resolvePublicPath(mfOptions, base, _originalConfigBase);
|
|
8526
8603
|
},
|
|
8527
8604
|
/**
|
|
8528
|
-
*
|
|
8529
|
-
*
|
|
8530
|
-
*
|
|
8531
|
-
*
|
|
8532
|
-
*
|
|
8605
|
+
* The client manifest only advertises an SSR entry its own bundle
|
|
8606
|
+
* emitted. The SSR entry usually lands in a separate build: a standalone
|
|
8607
|
+
* `vite build --ssr` (possibly with its own `filename`, e.g.
|
|
8608
|
+
* `defineConfig(({ isSsrBuild }) => ...)`) or the `ssr` environment,
|
|
8609
|
+
* which the builder may run before or after `client`. Whichever build
|
|
8610
|
+
* finishes with the SSR entry on disk points the manifest and stats at it.
|
|
8533
8611
|
*/
|
|
8534
8612
|
writeBundle(outputOptions) {
|
|
8535
8613
|
if (!mfManifestName || _command !== "build" || isConsumerProject) return;
|
|
8536
|
-
const environment = this.environment;
|
|
8537
|
-
if (!(environment ? environment.name === "ssr" : Boolean(viteConfig?.build?.ssr))) return;
|
|
8538
8614
|
const ssrEntryName = getSsrRemoteEntryFileName(mfOptions);
|
|
8539
|
-
const outDirs = [...new Set([
|
|
8615
|
+
const outDirs = [...new Set([
|
|
8616
|
+
outputOptions.dir,
|
|
8617
|
+
viteConfig?.environments?.client?.build?.outDir,
|
|
8618
|
+
viteConfig?.environments?.ssr?.build?.outDir
|
|
8619
|
+
].filter((dir) => typeof dir === "string").map((dir) => path$1.resolve(root, dir)))];
|
|
8540
8620
|
if (!outDirs.some((dir) => fs$1.existsSync(path$1.resolve(dir, ssrEntryName)))) return;
|
|
8541
8621
|
for (const dir of outDirs) for (const fileName of [mfManifestName, mfManifestStatsName]) {
|
|
8542
8622
|
if (!fileName) continue;
|
|
@@ -8545,8 +8625,12 @@ const Manifest = (providedOptions) => {
|
|
|
8545
8625
|
try {
|
|
8546
8626
|
const data = JSON.parse(fs$1.readFileSync(file, "utf8"));
|
|
8547
8627
|
const entry = data?.metaData?.ssrRemoteEntry;
|
|
8548
|
-
if (!
|
|
8549
|
-
|
|
8628
|
+
if (!data?.metaData || entry?.name === ssrEntryName) continue;
|
|
8629
|
+
data.metaData.ssrRemoteEntry = Object.assign({
|
|
8630
|
+
name: ssrEntryName,
|
|
8631
|
+
path: "",
|
|
8632
|
+
type: "module"
|
|
8633
|
+
}, typeof entry === "object" ? entry : null, { name: ssrEntryName });
|
|
8550
8634
|
fs$1.writeFileSync(file, JSON.stringify(data));
|
|
8551
8635
|
} catch {}
|
|
8552
8636
|
}
|
|
@@ -8564,7 +8648,7 @@ const Manifest = (providedOptions) => {
|
|
|
8564
8648
|
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions);
|
|
8565
8649
|
const foundSsrRemoteEntryFile = Object.values(bundle).find((file) => file.fileName === expectedSsrRemoteEntryFile)?.fileName;
|
|
8566
8650
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
8567
|
-
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) :
|
|
8651
|
+
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) : void 0);
|
|
8568
8652
|
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
8569
8653
|
if (allCssAssets.size > 0) {
|
|
8570
8654
|
const secondaryCss = /* @__PURE__ */ new Set();
|
|
@@ -8640,11 +8724,12 @@ const Manifest = (providedOptions) => {
|
|
|
8640
8724
|
path: "",
|
|
8641
8725
|
type: "module"
|
|
8642
8726
|
};
|
|
8643
|
-
const
|
|
8644
|
-
|
|
8727
|
+
const resolvedSsrRemoteEntryFile = _command === "serve" ? ssrRemoteEntryFile || getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(filename)) : ssrRemoteEntryFile;
|
|
8728
|
+
const ssrRemoteEntry = resolvedSsrRemoteEntryFile ? {
|
|
8729
|
+
name: resolvedSsrRemoteEntryFile,
|
|
8645
8730
|
path: _command === "serve" ? "/__mf_ssr__/" : "",
|
|
8646
8731
|
type: "module"
|
|
8647
|
-
};
|
|
8732
|
+
} : void 0;
|
|
8648
8733
|
const varRemoteEntry = varFilename ? {
|
|
8649
8734
|
name: varFilename,
|
|
8650
8735
|
path: "",
|
|
@@ -8769,6 +8854,106 @@ function getStatsFileName(manifestFileName) {
|
|
|
8769
8854
|
return parsed.dir ? normalizePathForImport(path$1.join(parsed.dir, fileName)) : fileName;
|
|
8770
8855
|
}
|
|
8771
8856
|
//#endregion
|
|
8857
|
+
//#region src/utils/sharedSource.ts
|
|
8858
|
+
const pendingEntryLookups = /* @__PURE__ */ new Map();
|
|
8859
|
+
const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
|
|
8860
|
+
/** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
|
|
8861
|
+
function isSharedEntryLookup(source, importer, options) {
|
|
8862
|
+
return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
|
|
8863
|
+
}
|
|
8864
|
+
/**
|
|
8865
|
+
* Runs one of the plugin's own `this.resolve()` calls (a shared entry lookup, a
|
|
8866
|
+
* parse-barrier external probe), marked so `isSharedEntryLookup` recognizes it
|
|
8867
|
+
* and the share hooks neither proxy it nor register a used share for it.
|
|
8868
|
+
*/
|
|
8869
|
+
async function resolveInternally(context, source, importer, options = {}) {
|
|
8870
|
+
const lookupKey = getEntryLookupKey(source, importer);
|
|
8871
|
+
pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
|
|
8872
|
+
try {
|
|
8873
|
+
return await context.resolve(source, importer, {
|
|
8874
|
+
...options,
|
|
8875
|
+
skipSelf: true,
|
|
8876
|
+
custom: {
|
|
8877
|
+
...options.custom,
|
|
8878
|
+
__mfSharedEntryLookup: true
|
|
8879
|
+
}
|
|
8880
|
+
});
|
|
8881
|
+
} finally {
|
|
8882
|
+
const remaining = pendingEntryLookups.get(lookupKey) - 1;
|
|
8883
|
+
if (remaining) pendingEntryLookups.set(lookupKey, remaining);
|
|
8884
|
+
else pendingEntryLookups.delete(lookupKey);
|
|
8885
|
+
}
|
|
8886
|
+
}
|
|
8887
|
+
/** Identify shared entries through Vite, with a cache scoped to this federation instance. */
|
|
8888
|
+
function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
8889
|
+
const caches = /* @__PURE__ */ new Map();
|
|
8890
|
+
async function matchEntry(source, suffix, resolveEntry) {
|
|
8891
|
+
const packageName = getPackageNameFromNodeModulePath(source);
|
|
8892
|
+
if (!packageName) return;
|
|
8893
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
8894
|
+
if (findSharedKey(packageName, shared)) candidates.add(packageName);
|
|
8895
|
+
if (findSharedKey(suffix, shared)) candidates.add(suffix);
|
|
8896
|
+
for (const key of Object.keys(shared)) {
|
|
8897
|
+
const request = getSharedRequest(key, shared[key]);
|
|
8898
|
+
if (getPackageName(request) !== packageName) continue;
|
|
8899
|
+
if (!request.endsWith("/")) candidates.add(request);
|
|
8900
|
+
for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
|
|
8901
|
+
}
|
|
8902
|
+
if (candidates.size === 0) return;
|
|
8903
|
+
const resolvedSource = await resolveEntry(source);
|
|
8904
|
+
if (!resolvedSource) return;
|
|
8905
|
+
for (const candidate of candidates) {
|
|
8906
|
+
const entry = await resolveEntry(candidate);
|
|
8907
|
+
if (!entry) continue;
|
|
8908
|
+
const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
|
|
8909
|
+
if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
|
|
8910
|
+
}
|
|
8911
|
+
}
|
|
8912
|
+
return {
|
|
8913
|
+
clear() {
|
|
8914
|
+
caches.clear();
|
|
8915
|
+
},
|
|
8916
|
+
async resolve(context, source, options = {}) {
|
|
8917
|
+
if (source.startsWith("\0") || source.includes("#")) return;
|
|
8918
|
+
const queryIndex = source.indexOf("?");
|
|
8919
|
+
const query = queryIndex === -1 ? "" : source.slice(queryIndex + 1);
|
|
8920
|
+
if (query && [...new URLSearchParams(query).keys()].some((key) => ![
|
|
8921
|
+
"v",
|
|
8922
|
+
"t",
|
|
8923
|
+
"import"
|
|
8924
|
+
].includes(key))) return;
|
|
8925
|
+
if (findSharedKey(source, shared)) return source;
|
|
8926
|
+
const suffix = getNodeModulesSuffix(source);
|
|
8927
|
+
if (!suffix) return;
|
|
8928
|
+
const normalizedSource = stripViteFsPrefix(normalizeNodeModulePath(source));
|
|
8929
|
+
const environment = context.environment ?? !!options.ssr;
|
|
8930
|
+
const cacheable = !options.isEntry && !options.scan && (!options.kind || options.kind === "import-statement") && Object.keys(options.attributes ?? {}).length === 0 && Object.keys(options.custom ?? {}).length === 0;
|
|
8931
|
+
let cache = cacheable ? caches.get(environment) : void 0;
|
|
8932
|
+
if (cacheable && !cache) {
|
|
8933
|
+
cache = /* @__PURE__ */ new Map();
|
|
8934
|
+
caches.set(environment, cache);
|
|
8935
|
+
}
|
|
8936
|
+
if (cache?.has(normalizedSource)) return cache.get(normalizedSource);
|
|
8937
|
+
const { root, conditions } = getResolutionConfig(context, options);
|
|
8938
|
+
const result = await matchEntry(normalizedSource, suffix, async (request) => {
|
|
8939
|
+
if (!path$1.isAbsolute(request) && !isPackageExportAvailable(request, {
|
|
8940
|
+
cwd: root,
|
|
8941
|
+
conditions
|
|
8942
|
+
})) return void 0;
|
|
8943
|
+
const importer = path$1.join(root, "package.json");
|
|
8944
|
+
try {
|
|
8945
|
+
const resolved = await resolveInternally(context, request, importer, options);
|
|
8946
|
+
return resolved && !resolved.external ? resolved.id : void 0;
|
|
8947
|
+
} catch {
|
|
8948
|
+
return;
|
|
8949
|
+
}
|
|
8950
|
+
});
|
|
8951
|
+
cache?.set(normalizedSource, result);
|
|
8952
|
+
return result;
|
|
8953
|
+
}
|
|
8954
|
+
};
|
|
8955
|
+
}
|
|
8956
|
+
//#endregion
|
|
8772
8957
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
8773
8958
|
function createModuleParseController() {
|
|
8774
8959
|
return {
|
|
@@ -8910,7 +9095,7 @@ function pluginModuleParseEnd_default(excludeFn, options, controller = createMod
|
|
|
8910
9095
|
if (typeof this.resolve !== "function") return;
|
|
8911
9096
|
if (controller.resolutionProbed.has(pendingId)) return;
|
|
8912
9097
|
controller.resolutionProbed.add(pendingId);
|
|
8913
|
-
this
|
|
9098
|
+
resolveInternally(this, pendingId, id).then((resolved) => {
|
|
8914
9099
|
if (!resolved?.external) return;
|
|
8915
9100
|
controller.externalSet.add(pendingId);
|
|
8916
9101
|
controller.parseStartSet.delete(pendingId);
|
|
@@ -8919,7 +9104,7 @@ function pluginModuleParseEnd_default(excludeFn, options, controller = createMod
|
|
|
8919
9104
|
};
|
|
8920
9105
|
const addPendingIds = (ids) => {
|
|
8921
9106
|
for (const pendingId of ids || []) {
|
|
8922
|
-
if (
|
|
9107
|
+
if (controller.externalSet.has(pendingId) || matchesExternal(configuredExternal, pendingId, id) || excludeFn(pendingId)) continue;
|
|
8923
9108
|
controller.parseStartSet.add(pendingId);
|
|
8924
9109
|
if (!controller.parseEndSet.has(pendingId)) probeExternal(pendingId);
|
|
8925
9110
|
}
|
|
@@ -9219,96 +9404,6 @@ function pluginProxyRemotes_default(options) {
|
|
|
9219
9404
|
};
|
|
9220
9405
|
}
|
|
9221
9406
|
//#endregion
|
|
9222
|
-
//#region src/utils/sharedSource.ts
|
|
9223
|
-
const pendingEntryLookups = /* @__PURE__ */ new Map();
|
|
9224
|
-
const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
|
|
9225
|
-
/** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
|
|
9226
|
-
function isSharedEntryLookup(source, importer, options) {
|
|
9227
|
-
return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
|
|
9228
|
-
}
|
|
9229
|
-
/** Identify shared entries through Vite, with a cache scoped to this federation instance. */
|
|
9230
|
-
function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
9231
|
-
const caches = /* @__PURE__ */ new Map();
|
|
9232
|
-
async function matchEntry(source, suffix, resolveEntry) {
|
|
9233
|
-
const packageName = getPackageNameFromNodeModulePath(source);
|
|
9234
|
-
if (!packageName) return;
|
|
9235
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
9236
|
-
if (findSharedKey(packageName, shared)) candidates.add(packageName);
|
|
9237
|
-
if (findSharedKey(suffix, shared)) candidates.add(suffix);
|
|
9238
|
-
for (const key of Object.keys(shared)) {
|
|
9239
|
-
const request = getSharedRequest(key, shared[key]);
|
|
9240
|
-
if (getPackageName(request) !== packageName) continue;
|
|
9241
|
-
if (!request.endsWith("/")) candidates.add(request);
|
|
9242
|
-
for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
|
|
9243
|
-
}
|
|
9244
|
-
if (candidates.size === 0) return;
|
|
9245
|
-
const resolvedSource = await resolveEntry(source);
|
|
9246
|
-
if (!resolvedSource) return;
|
|
9247
|
-
for (const candidate of candidates) {
|
|
9248
|
-
const entry = await resolveEntry(candidate);
|
|
9249
|
-
if (!entry) continue;
|
|
9250
|
-
const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
|
|
9251
|
-
if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
|
|
9252
|
-
}
|
|
9253
|
-
}
|
|
9254
|
-
return {
|
|
9255
|
-
clear() {
|
|
9256
|
-
caches.clear();
|
|
9257
|
-
},
|
|
9258
|
-
async resolve(context, source, options = {}) {
|
|
9259
|
-
if (source.startsWith("\0") || source.includes("#")) return;
|
|
9260
|
-
const queryIndex = source.indexOf("?");
|
|
9261
|
-
const query = queryIndex === -1 ? "" : source.slice(queryIndex + 1);
|
|
9262
|
-
if (query && [...new URLSearchParams(query).keys()].some((key) => ![
|
|
9263
|
-
"v",
|
|
9264
|
-
"t",
|
|
9265
|
-
"import"
|
|
9266
|
-
].includes(key))) return;
|
|
9267
|
-
if (findSharedKey(source, shared)) return source;
|
|
9268
|
-
const suffix = getNodeModulesSuffix(source);
|
|
9269
|
-
if (!suffix) return;
|
|
9270
|
-
const normalizedSource = stripViteFsPrefix(normalizeNodeModulePath(source));
|
|
9271
|
-
const environment = context.environment ?? !!options.ssr;
|
|
9272
|
-
const cacheable = !options.isEntry && !options.scan && (!options.kind || options.kind === "import-statement") && Object.keys(options.attributes ?? {}).length === 0 && Object.keys(options.custom ?? {}).length === 0;
|
|
9273
|
-
let cache = cacheable ? caches.get(environment) : void 0;
|
|
9274
|
-
if (cacheable && !cache) {
|
|
9275
|
-
cache = /* @__PURE__ */ new Map();
|
|
9276
|
-
caches.set(environment, cache);
|
|
9277
|
-
}
|
|
9278
|
-
if (cache?.has(normalizedSource)) return cache.get(normalizedSource);
|
|
9279
|
-
const { root, conditions } = getResolutionConfig(context, options);
|
|
9280
|
-
const result = await matchEntry(normalizedSource, suffix, async (request) => {
|
|
9281
|
-
if (!path$1.isAbsolute(request) && !isPackageExportAvailable(request, {
|
|
9282
|
-
cwd: root,
|
|
9283
|
-
conditions
|
|
9284
|
-
})) return void 0;
|
|
9285
|
-
const importer = path$1.join(root, "package.json");
|
|
9286
|
-
const lookupKey = getEntryLookupKey(request, importer);
|
|
9287
|
-
pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
|
|
9288
|
-
try {
|
|
9289
|
-
const resolved = await context.resolve(request, importer, {
|
|
9290
|
-
...options,
|
|
9291
|
-
skipSelf: true,
|
|
9292
|
-
custom: {
|
|
9293
|
-
...options.custom,
|
|
9294
|
-
__mfSharedEntryLookup: true
|
|
9295
|
-
}
|
|
9296
|
-
});
|
|
9297
|
-
return resolved && !resolved.external ? resolved.id : void 0;
|
|
9298
|
-
} catch {
|
|
9299
|
-
return;
|
|
9300
|
-
} finally {
|
|
9301
|
-
const remaining = pendingEntryLookups.get(lookupKey) - 1;
|
|
9302
|
-
if (remaining) pendingEntryLookups.set(lookupKey, remaining);
|
|
9303
|
-
else pendingEntryLookups.delete(lookupKey);
|
|
9304
|
-
}
|
|
9305
|
-
});
|
|
9306
|
-
cache?.set(normalizedSource, result);
|
|
9307
|
-
return result;
|
|
9308
|
-
}
|
|
9309
|
-
};
|
|
9310
|
-
}
|
|
9311
|
-
//#endregion
|
|
9312
9407
|
//#region src/utils/PromiseStore.ts
|
|
9313
9408
|
/**
|
|
9314
9409
|
* example:
|
|
@@ -9522,8 +9617,9 @@ function isSharedPackageDependency(sharedKey, dependency) {
|
|
|
9522
9617
|
function isConfiguredSharedPackage(pkg, shared) {
|
|
9523
9618
|
return Object.keys(shared).some((key) => getPackageName(key) === pkg);
|
|
9524
9619
|
}
|
|
9525
|
-
function shouldKeepSharedImportLocal(source, importer, sharedKey, shared, importerPackage) {
|
|
9620
|
+
function shouldKeepSharedImportLocal(source, importer, sharedKey, shared, importerPackage, federationOptions) {
|
|
9526
9621
|
if (!importer || shared[sharedKey]?.shareConfig.import === false) return false;
|
|
9622
|
+
if (hasRemotes(federationOptions)) return false;
|
|
9527
9623
|
const prebuildImporter = importer.includes("__prebuild__") ? VirtualModule.findModule(PREBUILD_TAG, importer) : void 0;
|
|
9528
9624
|
const fallbackPackage = prebuildImporter ? getPackageName(prebuildImporter.name) : importerPackage;
|
|
9529
9625
|
if (!fallbackPackage || !isConfiguredSharedPackage(fallbackPackage, shared)) return false;
|
|
@@ -9941,7 +10037,7 @@ function proxySharedModule(options) {
|
|
|
9941
10037
|
if (shouldSkipTaggedImporterProxy(key, "__loadShare__")) return;
|
|
9942
10038
|
if (shouldSkipTaggedImporterProxy(key, "__prebuild__")) return;
|
|
9943
10039
|
const shareSource = key === "vue" && sharedSource.startsWith("vue/dist/") ? key : sharedSource;
|
|
9944
|
-
if (shouldKeepSharedImportLocal(
|
|
10040
|
+
if (shouldKeepSharedImportLocal(shareSource, importer, key, shared, importerPackage, federationOptions)) {
|
|
9945
10041
|
const localSource = getPrebuildResolutionSource(shareSource, shared[key]);
|
|
9946
10042
|
return tryResolveFromProjectRoot(localSource) || localSource;
|
|
9947
10043
|
}
|
|
@@ -10441,6 +10537,8 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10441
10537
|
return exposeKeys.every((key) => code.includes(JSON.stringify(key)));
|
|
10442
10538
|
})?.fileName;
|
|
10443
10539
|
};
|
|
10540
|
+
const isNuxtLike = () => isNuxtProject || isNuxtClientBase(getBasePath$1(viteConfig?.base));
|
|
10541
|
+
const findEmittedExposesChunk = (bundle) => Object.values(bundle).find((file) => file.type === "chunk" && file.facadeModuleId === virtualExposesSSRId)?.fileName;
|
|
10444
10542
|
return [{
|
|
10445
10543
|
name: "mf:ssr-remote-entry:pre",
|
|
10446
10544
|
enforce: "pre",
|
|
@@ -10483,7 +10581,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10483
10581
|
const base = "/__mf_ssr__";
|
|
10484
10582
|
const basePath = getBasePath$1(viteConfig?.base);
|
|
10485
10583
|
const ssrEntryFileName = getSsrRemoteEntryFileName(options);
|
|
10486
|
-
if (
|
|
10584
|
+
if (isNuxtLike()) server.middlewares.use((req, _res, next) => {
|
|
10487
10585
|
if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
|
|
10488
10586
|
next();
|
|
10489
10587
|
});
|
|
@@ -10570,16 +10668,26 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10570
10668
|
fileName: ssrOutputFilename,
|
|
10571
10669
|
preserveSignature: "strict"
|
|
10572
10670
|
});
|
|
10671
|
+
else if (Object.keys(options.exposes).length > 0 && !isNuxtLike()) this.emitFile({
|
|
10672
|
+
type: "chunk",
|
|
10673
|
+
id: virtualExposesSSRId,
|
|
10674
|
+
name: "ssrExposes",
|
|
10675
|
+
preserveSignature: "strict"
|
|
10676
|
+
});
|
|
10573
10677
|
},
|
|
10574
10678
|
generateBundle: {
|
|
10575
10679
|
order: "post",
|
|
10576
10680
|
handler(_options, bundle) {
|
|
10577
10681
|
const isRolldown = getIsRolldown(this);
|
|
10578
10682
|
const environment = this.environment;
|
|
10579
|
-
const exposesChunk = findNuxtExposesChunk(bundle);
|
|
10683
|
+
const exposesChunk = findNuxtExposesChunk(bundle) ?? findEmittedExposesChunk(bundle);
|
|
10580
10684
|
if (!isRolldown && isSsrRemoteEntryBuild(environment)) {
|
|
10581
10685
|
let source = getSsrRemoteEntrySource();
|
|
10582
|
-
if (exposesChunk)
|
|
10686
|
+
if (exposesChunk) {
|
|
10687
|
+
let exposesImport = path$1.posix.relative(path$1.posix.dirname(ssrOutputFilename), exposesChunk);
|
|
10688
|
+
if (!exposesImport.startsWith(".")) exposesImport = `./${exposesImport}`;
|
|
10689
|
+
source = source.replace(/import\("virtual:mf-exposes-ssr:[^"]+"\)/g, `import("${exposesImport}")`);
|
|
10690
|
+
}
|
|
10583
10691
|
this.emitFile({
|
|
10584
10692
|
type: "asset",
|
|
10585
10693
|
fileName: ssrOutputFilename,
|
|
@@ -10900,6 +11008,360 @@ function isTestEnv() {
|
|
|
10900
11008
|
return process.env.NODE_ENV === "test" || process.env.VITEST != null || process.env.JEST_WORKER_ID != null;
|
|
10901
11009
|
}
|
|
10902
11010
|
//#endregion
|
|
11011
|
+
//#region src/utils/hostProvidesAllShared.ts
|
|
11012
|
+
/** Virtual-module prefix of the host's per-share re-export entries. */
|
|
11013
|
+
const SHARE_MODULE_PREFIX = "\0mf-host-provided-share:";
|
|
11014
|
+
/** `./a/b` → `a/b`, `.` → `index`: the fixed entry name of an expose, without `.js`. */
|
|
11015
|
+
function exposeEntryName(exposeKey) {
|
|
11016
|
+
return exposeKey === "." ? "index" : exposeKey.replace(/^\.\//, "");
|
|
11017
|
+
}
|
|
11018
|
+
/** Bare specifier a host uses for an expose: `remote` for `.`, `remote/a/b` otherwise. */
|
|
11019
|
+
function remoteSpecifier(remoteName, exposeKey) {
|
|
11020
|
+
const entry = exposeEntryName(exposeKey);
|
|
11021
|
+
return entry === "index" ? remoteName : `${remoteName}/${entry}`;
|
|
11022
|
+
}
|
|
11023
|
+
/** `id` is a remote alias or a subpath of one. */
|
|
11024
|
+
function isRemoteSpecifier(id, remoteKeys) {
|
|
11025
|
+
return remoteKeys.some((key) => id === key || id.startsWith(`${key}/`));
|
|
11026
|
+
}
|
|
11027
|
+
/**
|
|
11028
|
+
* The shared key that owns `id`: an exact match, else the longest key `id` is a subpath
|
|
11029
|
+
* of (`lodash-es/debounce` → `lodash-es`). Used to spot an unshared subpath of a shared
|
|
11030
|
+
* package, which would bundle a private copy of that package into a remote.
|
|
11031
|
+
*/
|
|
11032
|
+
function sharedKeyOwning(id, sharedKeys) {
|
|
11033
|
+
let owner;
|
|
11034
|
+
for (const key of sharedKeys) {
|
|
11035
|
+
if (id !== key && !id.startsWith(`${key}/`)) continue;
|
|
11036
|
+
if (!owner || key.length > owner.length) owner = key;
|
|
11037
|
+
}
|
|
11038
|
+
return owner;
|
|
11039
|
+
}
|
|
11040
|
+
/** Chunk name of the host's re-export entry for a shared key. */
|
|
11041
|
+
function shareChunkName(key) {
|
|
11042
|
+
return `shared/${key.replace(/^@/, "").replace(/[^\w-]+/g, "-")}`;
|
|
11043
|
+
}
|
|
11044
|
+
/** Reads a remote's `mf-manifest.json` from a URL or a path relative to `root`. */
|
|
11045
|
+
async function readHostProvidesAllSharedManifest(location, root) {
|
|
11046
|
+
let source;
|
|
11047
|
+
if (isAbsoluteUrl(location)) {
|
|
11048
|
+
const response = await fetch(location);
|
|
11049
|
+
if (!response.ok) throw new Error(`Failed to fetch ${location}: ${response.status} ${response.statusText}`);
|
|
11050
|
+
source = await response.text();
|
|
11051
|
+
} else source = await readFile(path$1.resolve(root, location), "utf8");
|
|
11052
|
+
const manifest = JSON.parse(source);
|
|
11053
|
+
if (!manifest.metaData || !Array.isArray(manifest.exposes)) throw new Error(`${location} is not a Module Federation manifest.`);
|
|
11054
|
+
if (manifest.metaData.remoteEntry) throw new Error(`${location} describes a Module Federation runtime remote (it has a remoteEntry). Build the remote with \`experiments: { hostProvidesAllShared: true }\`.`);
|
|
11055
|
+
return manifest;
|
|
11056
|
+
}
|
|
11057
|
+
/** URL prefix of a remote's files: `metaData.publicPath`, `auto` inferred from the manifest URL. */
|
|
11058
|
+
function remotePublicPath(manifest, location) {
|
|
11059
|
+
const publicPath = manifest.metaData.publicPath ?? "auto";
|
|
11060
|
+
if (publicPath !== "auto") return ensureTrailingSlash(publicPath);
|
|
11061
|
+
if (!isAbsoluteUrl(location)) throw new Error(`${location}: publicPath is "auto", which can only be inferred from a manifest URL. Reference the manifest by URL or set \`base\` / \`publicPath\` in the remote build.`);
|
|
11062
|
+
return ensureTrailingSlash(inferAutoPublicPath(location));
|
|
11063
|
+
}
|
|
11064
|
+
/** Import-map entries (`remote/Expose` → URL) for every expose of every remote. */
|
|
11065
|
+
async function collectRemoteImports(remotes, root) {
|
|
11066
|
+
const imports = {};
|
|
11067
|
+
for (const [alias, remote] of Object.entries(remotes)) {
|
|
11068
|
+
const manifest = await readHostProvidesAllSharedManifest(remote.entry, root);
|
|
11069
|
+
const publicPath = remotePublicPath(manifest, remote.entry);
|
|
11070
|
+
for (const expose of manifest.exposes) {
|
|
11071
|
+
const file = expose.assets.js.sync[0];
|
|
11072
|
+
if (!expose.path || !file) continue;
|
|
11073
|
+
imports[remoteSpecifier(alias, expose.path)] = isAbsoluteUrl(remote.entry) ? new URL(file, new URL(publicPath, remote.entry)).href : publicPath + file;
|
|
11074
|
+
}
|
|
11075
|
+
}
|
|
11076
|
+
return imports;
|
|
11077
|
+
}
|
|
11078
|
+
/** Top-level options that only the Module Federation runtime or `remoteEntry.js` pipeline reads. */
|
|
11079
|
+
const IGNORED_OPTIONS = [
|
|
11080
|
+
"filename",
|
|
11081
|
+
"ssrFilename",
|
|
11082
|
+
"varFilename",
|
|
11083
|
+
"library",
|
|
11084
|
+
"runtime",
|
|
11085
|
+
"shareScope",
|
|
11086
|
+
"shareStrategy",
|
|
11087
|
+
"runtimePlugins",
|
|
11088
|
+
"implementation",
|
|
11089
|
+
"getPublicPath",
|
|
11090
|
+
"ignoreOrigin",
|
|
11091
|
+
"virtualModuleDir",
|
|
11092
|
+
"hostInitInjectLocation",
|
|
11093
|
+
"bundleAllCSS",
|
|
11094
|
+
"treeShakingDir",
|
|
11095
|
+
"injectTreeShakingUsedExports",
|
|
11096
|
+
"treeShakingSharedPlugins",
|
|
11097
|
+
"treeShakingSharedExcludePlugins",
|
|
11098
|
+
"moduleParseTimeout",
|
|
11099
|
+
"moduleParseIdleTimeout",
|
|
11100
|
+
"target",
|
|
11101
|
+
"ssrExternals",
|
|
11102
|
+
"ssrEntryLoader",
|
|
11103
|
+
"disableRemote",
|
|
11104
|
+
"disableShared",
|
|
11105
|
+
"disableSnapshot"
|
|
11106
|
+
];
|
|
11107
|
+
const IGNORED_EXPERIMENTS = [
|
|
11108
|
+
"externalRuntime",
|
|
11109
|
+
"provideExternalRuntime",
|
|
11110
|
+
"ssrMode"
|
|
11111
|
+
];
|
|
11112
|
+
/** Per-share options: version negotiation, aliasing and fallbacks do not exist in this mode. */
|
|
11113
|
+
const IGNORED_SHARE_OPTIONS = [
|
|
11114
|
+
"eager",
|
|
11115
|
+
"requiredVersion",
|
|
11116
|
+
"strictVersion",
|
|
11117
|
+
"import",
|
|
11118
|
+
"request",
|
|
11119
|
+
"shareKey",
|
|
11120
|
+
"name",
|
|
11121
|
+
"version",
|
|
11122
|
+
"shareScope",
|
|
11123
|
+
"treeShaking",
|
|
11124
|
+
"allowNodeModulesSuffixMatch",
|
|
11125
|
+
"suppressMissingImportWarning"
|
|
11126
|
+
];
|
|
11127
|
+
const isSet = (value) => value !== void 0 && value !== false && !(Array.isArray(value) && value.length === 0);
|
|
11128
|
+
/** A single warning naming every option the user set that import-map mode ignores. */
|
|
11129
|
+
function getIgnoredOptionWarning(options) {
|
|
11130
|
+
const shared = options.shared;
|
|
11131
|
+
const ignored = [
|
|
11132
|
+
...IGNORED_OPTIONS.filter((key) => isSet(options[key])).map((key) => `\`${key}\``),
|
|
11133
|
+
...IGNORED_EXPERIMENTS.filter((key) => isSet(options.experiments?.[key])).map((key) => `\`experiments.${key}\``),
|
|
11134
|
+
...shared && !Array.isArray(shared) ? Object.entries(shared).flatMap(([key, config]) => typeof config === "object" && config !== null ? IGNORED_SHARE_OPTIONS.filter((option) => option === "import" ? config.import !== void 0 : isSet(config[option])).map((option) => `\`shared.${key}.${option}\``) : []) : []
|
|
11135
|
+
];
|
|
11136
|
+
if (ignored.length === 0) return void 0;
|
|
11137
|
+
return `experiments.hostProvidesAllShared: ${ignored.join(", ")} ignored. The Module Federation runtime is not used and the host provides the only copy of every shared key.`;
|
|
11138
|
+
}
|
|
11139
|
+
//#endregion
|
|
11140
|
+
//#region src/plugins/pluginHostProvidesAllSharedHost.ts
|
|
11141
|
+
const ESM_SYNTAX_RE = /(^|[\s;])(export|import)[\s{*]/m;
|
|
11142
|
+
const DEFAULT_EXPORT_RE = /export\s+default\b|export\s*\{[^}]*\bas\s+default\b/;
|
|
11143
|
+
const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/;
|
|
11144
|
+
/**
|
|
11145
|
+
* Export names of a CommonJS package, read by loading it in Node from the project root
|
|
11146
|
+
* (what the bundler's interop exposes as named imports). Empty when it cannot be loaded
|
|
11147
|
+
* in Node, e.g. because it touches `window`.
|
|
11148
|
+
*/
|
|
11149
|
+
function cjsExportNames(key, root) {
|
|
11150
|
+
try {
|
|
11151
|
+
const exported = createRequire(path$1.join(root, "package.json"))(key);
|
|
11152
|
+
return Object.keys(exported ?? {}).filter((name) => name !== "default" && name !== "__esModule" && IDENTIFIER_RE.test(name));
|
|
11153
|
+
} catch {
|
|
11154
|
+
return [];
|
|
11155
|
+
}
|
|
11156
|
+
}
|
|
11157
|
+
/** Shape of a shared module, sniffed from its real package entry (never a pre-bundle). */
|
|
11158
|
+
function detectShareShape(key, entry, root) {
|
|
11159
|
+
const source = entry && fs$1.existsSync(entry) ? fs$1.readFileSync(entry, "utf8") : "";
|
|
11160
|
+
if (source !== "" && !ESM_SYNTAX_RE.test(source)) return {
|
|
11161
|
+
kind: "cjs",
|
|
11162
|
+
names: cjsExportNames(key, root)
|
|
11163
|
+
};
|
|
11164
|
+
return {
|
|
11165
|
+
kind: "esm",
|
|
11166
|
+
hasDefault: DEFAULT_EXPORT_RE.test(source)
|
|
11167
|
+
};
|
|
11168
|
+
}
|
|
11169
|
+
/**
|
|
11170
|
+
* Body of the re-export entry for one shared key. `export *` never forwards `default` and
|
|
11171
|
+
* forwards nothing named from CommonJS, so an ESM module adds `default` only when it has
|
|
11172
|
+
* one, and a CommonJS module re-exports each key explicitly (`react/jsx-runtime` → `jsx`,
|
|
11173
|
+
* `jsxs`) so remotes can `import { jsxs }`.
|
|
11174
|
+
*/
|
|
11175
|
+
function shareModuleCode(key, shape) {
|
|
11176
|
+
const spec = JSON.stringify(key);
|
|
11177
|
+
if (shape.kind === "cjs") return `import __mf_cjs from ${spec};\nexport default __mf_cjs;\n${shape.names.length ? `export const { ${shape.names.join(", ")} } = __mf_cjs;\n` : ""}`;
|
|
11178
|
+
return `export * from ${spec};\n${shape.hasDefault ? `export { default } from ${spec};\n` : ""}`;
|
|
11179
|
+
}
|
|
11180
|
+
/** BUILD: shared key → URL of its emitted entry chunk. */
|
|
11181
|
+
function bundledShareImports(bundle, base) {
|
|
11182
|
+
const imports = {};
|
|
11183
|
+
for (const chunk of Object.values(bundle)) if (chunk.type === "chunk" && chunk.facadeModuleId?.startsWith("\0mf-host-provided-share:")) imports[chunk.facadeModuleId.slice(24)] = `${base}${chunk.fileName}`;
|
|
11184
|
+
return imports;
|
|
11185
|
+
}
|
|
11186
|
+
/**
|
|
11187
|
+
* DEV: shared key → dev-server URL of its virtual re-export module. Vite serves `\0` ids
|
|
11188
|
+
* at `/@id/__x00__<id>`; import analysis then rewrites the module's own `from '<key>'` to
|
|
11189
|
+
* the same pre-bundle URL the host's code gets, so host and remotes share one instance.
|
|
11190
|
+
*/
|
|
11191
|
+
function devShareImports(sharedKeys, base) {
|
|
11192
|
+
const prefix = `${base}@id/__x00__${SHARE_MODULE_PREFIX.slice(1)}`;
|
|
11193
|
+
return Object.fromEntries(sharedKeys.map((key) => [key, `${prefix}${key}`]));
|
|
11194
|
+
}
|
|
11195
|
+
function importMapTag(imports) {
|
|
11196
|
+
return {
|
|
11197
|
+
tag: "script",
|
|
11198
|
+
attrs: { type: "importmap" },
|
|
11199
|
+
children: JSON.stringify({ imports }, null, 2),
|
|
11200
|
+
injectTo: "head-prepend"
|
|
11201
|
+
};
|
|
11202
|
+
}
|
|
11203
|
+
/**
|
|
11204
|
+
* Host side of `experiments.hostProvidesAllShared`. The host provides every shared key:
|
|
11205
|
+
*
|
|
11206
|
+
* 1. one re-export module per shared key, emitted in a build as a `preserveSignature:
|
|
11207
|
+
* 'strict'` entry chunk that the bundler dedupes with the host's own imports, and served
|
|
11208
|
+
* in dev as a virtual module; either way host and remotes land on one module instance;
|
|
11209
|
+
* 2. an import map in `index.html` pointing each shared key at that module and each remote
|
|
11210
|
+
* expose at the entry listed in the remote's `mf-manifest.json`.
|
|
11211
|
+
*/
|
|
11212
|
+
function pluginHostProvidesAllSharedHost(options) {
|
|
11213
|
+
const sharedKeys = Object.keys(options.shared);
|
|
11214
|
+
const remoteKeys = Object.keys(options.remotes);
|
|
11215
|
+
let isBuild = true;
|
|
11216
|
+
let base = "/";
|
|
11217
|
+
let root = process.cwd();
|
|
11218
|
+
let remoteImports = {};
|
|
11219
|
+
let resolveEntry;
|
|
11220
|
+
return {
|
|
11221
|
+
name: "module-federation:host-provides-all-shared-host",
|
|
11222
|
+
enforce: "pre",
|
|
11223
|
+
configResolved(config) {
|
|
11224
|
+
isBuild = config.command === "build";
|
|
11225
|
+
base = ensureTrailingSlash(config.base);
|
|
11226
|
+
root = config.root;
|
|
11227
|
+
resolveEntry = isBuild ? void 0 : config.createResolver();
|
|
11228
|
+
},
|
|
11229
|
+
async buildStart() {
|
|
11230
|
+
remoteImports = await collectRemoteImports(options.remotes, root);
|
|
11231
|
+
if (!isBuild) return;
|
|
11232
|
+
for (const key of sharedKeys) this.emitFile({
|
|
11233
|
+
type: "chunk",
|
|
11234
|
+
id: `${SHARE_MODULE_PREFIX}${key}`,
|
|
11235
|
+
name: shareChunkName(key),
|
|
11236
|
+
preserveSignature: "strict"
|
|
11237
|
+
});
|
|
11238
|
+
},
|
|
11239
|
+
resolveId(id) {
|
|
11240
|
+
if (id.startsWith("\0mf-host-provided-share:")) return id;
|
|
11241
|
+
if (!isRemoteSpecifier(id, remoteKeys)) return null;
|
|
11242
|
+
return {
|
|
11243
|
+
id: isBuild ? id : remoteImports[id] ?? id,
|
|
11244
|
+
external: true
|
|
11245
|
+
};
|
|
11246
|
+
},
|
|
11247
|
+
async load(id) {
|
|
11248
|
+
if (!id.startsWith("\0mf-host-provided-share:")) return null;
|
|
11249
|
+
const key = id.slice(24);
|
|
11250
|
+
const entry = resolveEntry ? await resolveEntry(key) : (await this.resolve(key, void 0, { skipSelf: true }))?.id;
|
|
11251
|
+
return shareModuleCode(key, detectShareShape(key, entry && stripQueryAndHash(entry), root));
|
|
11252
|
+
},
|
|
11253
|
+
transformIndexHtml: {
|
|
11254
|
+
order: "post",
|
|
11255
|
+
handler(html, context) {
|
|
11256
|
+
const shares = context.bundle ? bundledShareImports(context.bundle, base) : devShareImports(sharedKeys, base);
|
|
11257
|
+
return {
|
|
11258
|
+
html,
|
|
11259
|
+
tags: [importMapTag({
|
|
11260
|
+
...remoteImports,
|
|
11261
|
+
...shares
|
|
11262
|
+
})]
|
|
11263
|
+
};
|
|
11264
|
+
}
|
|
11265
|
+
}
|
|
11266
|
+
};
|
|
11267
|
+
}
|
|
11268
|
+
//#endregion
|
|
11269
|
+
//#region src/plugins/pluginHostProvidesAllSharedRemote.ts
|
|
11270
|
+
/**
|
|
11271
|
+
* Remote side of `experiments.hostProvidesAllShared`. The remote ships only its own code:
|
|
11272
|
+
*
|
|
11273
|
+
* - one fixed-name, signature-preserving entry per expose (`./Button` → `Button.js`), so
|
|
11274
|
+
* the host can map `<remote>/Button` to a stable URL;
|
|
11275
|
+
* - every shared key, and every configured remote, stays an external bare import that the
|
|
11276
|
+
* host's import map resolves at runtime;
|
|
11277
|
+
* - a standard `mf-manifest.json` without `remoteEntry`, listing each expose's entry file.
|
|
11278
|
+
*/
|
|
11279
|
+
function pluginHostProvidesAllSharedRemote(options) {
|
|
11280
|
+
const sharedKeys = Object.keys(options.shared);
|
|
11281
|
+
const remoteKeys = Object.keys(options.remotes);
|
|
11282
|
+
const isExternal = (id) => sharedKeys.includes(id) || isRemoteSpecifier(id, remoteKeys);
|
|
11283
|
+
const unsharedSubpaths = /* @__PURE__ */ new Map();
|
|
11284
|
+
let publicPath = "/";
|
|
11285
|
+
return {
|
|
11286
|
+
name: "module-federation:host-provides-all-shared-remote",
|
|
11287
|
+
enforce: "pre",
|
|
11288
|
+
apply: "build",
|
|
11289
|
+
config(config) {
|
|
11290
|
+
const root = path$1.resolve(config.root ?? process.cwd());
|
|
11291
|
+
return { build: { rollupOptions: {
|
|
11292
|
+
input: Object.fromEntries(Object.entries(options.exposes).map(([key, expose]) => [exposeEntryName(key), path$1.resolve(root, expose.import)])),
|
|
11293
|
+
external: isExternal,
|
|
11294
|
+
preserveEntrySignatures: "strict",
|
|
11295
|
+
output: {
|
|
11296
|
+
entryFileNames: "[name].js",
|
|
11297
|
+
chunkFileNames: "assets/[name]-[hash].js"
|
|
11298
|
+
}
|
|
11299
|
+
} } };
|
|
11300
|
+
},
|
|
11301
|
+
configResolved(config) {
|
|
11302
|
+
publicPath = options.publicPath ?? config.base;
|
|
11303
|
+
},
|
|
11304
|
+
buildStart() {
|
|
11305
|
+
unsharedSubpaths.clear();
|
|
11306
|
+
},
|
|
11307
|
+
resolveId(id, importer) {
|
|
11308
|
+
if (importer && !isExternal(id) && sharedKeyOwning(id, sharedKeys)) unsharedSubpaths.set(id, importer);
|
|
11309
|
+
return null;
|
|
11310
|
+
},
|
|
11311
|
+
buildEnd() {
|
|
11312
|
+
for (const [id, importer] of unsharedSubpaths) this.warn(`"${id}" (imported by ${importer}) is a subpath of a shared package but is not shared itself, so a private copy is bundled into this remote. Add it to \`shared\`.`);
|
|
11313
|
+
},
|
|
11314
|
+
generateBundle(_outputOptions, bundle) {
|
|
11315
|
+
const { name } = options;
|
|
11316
|
+
const exposes = [];
|
|
11317
|
+
for (const key of Object.keys(options.exposes)) {
|
|
11318
|
+
const entryName = exposeEntryName(key);
|
|
11319
|
+
const chunk = Object.values(bundle).find((item) => item.type === "chunk" && item.isEntry && item.name === entryName);
|
|
11320
|
+
if (!chunk) continue;
|
|
11321
|
+
exposes.push({
|
|
11322
|
+
id: `${name}:${entryName}`,
|
|
11323
|
+
name: entryName,
|
|
11324
|
+
path: key,
|
|
11325
|
+
assets: {
|
|
11326
|
+
js: {
|
|
11327
|
+
sync: [chunk.fileName],
|
|
11328
|
+
async: []
|
|
11329
|
+
},
|
|
11330
|
+
css: {
|
|
11331
|
+
sync: [],
|
|
11332
|
+
async: []
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
});
|
|
11336
|
+
}
|
|
11337
|
+
const manifest = {
|
|
11338
|
+
id: name,
|
|
11339
|
+
name,
|
|
11340
|
+
metaData: {
|
|
11341
|
+
name,
|
|
11342
|
+
type: "app",
|
|
11343
|
+
buildInfo: {
|
|
11344
|
+
buildVersion: getBuildVersion(),
|
|
11345
|
+
buildName: name
|
|
11346
|
+
},
|
|
11347
|
+
globalName: name,
|
|
11348
|
+
pluginVersion: version$1,
|
|
11349
|
+
publicPath,
|
|
11350
|
+
types: resolveTypesMeta(options.dts)
|
|
11351
|
+
},
|
|
11352
|
+
shared: [],
|
|
11353
|
+
remotes: [],
|
|
11354
|
+
exposes
|
|
11355
|
+
};
|
|
11356
|
+
this.emitFile({
|
|
11357
|
+
type: "asset",
|
|
11358
|
+
fileName: typeof options.manifest === "object" && options.manifest.fileName || "mf-manifest.json",
|
|
11359
|
+
source: `${JSON.stringify(manifest, null, 2)}\n`
|
|
11360
|
+
});
|
|
11361
|
+
}
|
|
11362
|
+
};
|
|
11363
|
+
}
|
|
11364
|
+
//#endregion
|
|
10903
11365
|
//#region src/utils/normalizeOptimizeDeps.ts
|
|
10904
11366
|
var normalizeOptimizeDeps_default = {
|
|
10905
11367
|
name: "normalizeOptimizeDeps",
|
|
@@ -11499,7 +11961,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
11499
11961
|
resolveImportPath(ssrEntryLoaderSpecifier);
|
|
11500
11962
|
options.runtimePlugins.push([ssrEntryLoaderSpecifier, {
|
|
11501
11963
|
resolvedShared,
|
|
11502
|
-
...options.ssrEntryLoader
|
|
11964
|
+
...options.ssrEntryLoader
|
|
11503
11965
|
}]);
|
|
11504
11966
|
} catch {}
|
|
11505
11967
|
}
|
|
@@ -11514,9 +11976,21 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
11514
11976
|
});
|
|
11515
11977
|
if (options.target && define.ENV_TARGET !== JSON.stringify(options.target)) mfWarn(`ENV_TARGET define (${define.ENV_TARGET}) differs from target option ("${options.target}"). ENV_TARGET will not be overridden.`);
|
|
11516
11978
|
}
|
|
11979
|
+
/** Dynamic remote type hints are a runtime plugin; hostProvidesAllShared has no runtime. */
|
|
11980
|
+
function withoutDynamicRemoteTypeHints(options) {
|
|
11981
|
+
if (options.dev === false) return options;
|
|
11982
|
+
const dev = options.dev === true || options.dev === void 0 ? {} : options.dev;
|
|
11983
|
+
return {
|
|
11984
|
+
...options,
|
|
11985
|
+
dev: {
|
|
11986
|
+
...dev,
|
|
11987
|
+
disableDynamicRemoteTypeHints: true
|
|
11988
|
+
}
|
|
11989
|
+
};
|
|
11990
|
+
}
|
|
11517
11991
|
function loadPluginDts(options) {
|
|
11518
11992
|
if (options.dts === false) return [];
|
|
11519
|
-
return [import("./pluginDts-
|
|
11993
|
+
return [import("./pluginDts-CVyHPAEq.js").then(({ default: pluginDts }) => pluginDts(options))];
|
|
11520
11994
|
}
|
|
11521
11995
|
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
11522
11996
|
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
@@ -11545,11 +12019,16 @@ function applyExternalRuntimeExperiments(options) {
|
|
|
11545
12019
|
function federation(mfUserOptions) {
|
|
11546
12020
|
if (isTestEnv()) return [];
|
|
11547
12021
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
12022
|
+
if (!options.name) throw createModuleFederationError("name is required");
|
|
12023
|
+
if (options.experiments.hostProvidesAllShared) {
|
|
12024
|
+
const ignored = getIgnoredOptionWarning(mfUserOptions);
|
|
12025
|
+
if (ignored) mfWarn(ignored);
|
|
12026
|
+
return [Object.keys(options.exposes).length > 0 ? pluginHostProvidesAllSharedRemote(options) : pluginHostProvidesAllSharedHost(options), ...loadPluginDts(withoutDynamicRemoteTypeHints(options))];
|
|
12027
|
+
}
|
|
11548
12028
|
applyExternalRuntimeExperiments(options);
|
|
11549
12029
|
const isVinext = hasPackageDependency("vinext");
|
|
11550
|
-
const {
|
|
12030
|
+
const { shared, filename, hostInitInjectLocation } = options;
|
|
11551
12031
|
const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
11552
|
-
if (!name) throw createModuleFederationError("name is required");
|
|
11553
12032
|
const remoteEntryId = getRemoteEntryId(options);
|
|
11554
12033
|
const virtualExposesId = getVirtualExposesId(options);
|
|
11555
12034
|
const moduleParseController = createModuleParseController();
|
|
@@ -11567,6 +12046,7 @@ function federation(mfUserOptions) {
|
|
|
11567
12046
|
let rootResolveConditions;
|
|
11568
12047
|
let ssrResolveConditions;
|
|
11569
12048
|
let ssrTarget = "node";
|
|
12049
|
+
let inheritedEnvTarget;
|
|
11570
12050
|
const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
|
|
11571
12051
|
const getLoadHookExportConditions = (context, loadOptions) => {
|
|
11572
12052
|
const environment = context.environment;
|
|
@@ -11660,7 +12140,11 @@ function federation(mfUserOptions) {
|
|
|
11660
12140
|
const virtualModule = VirtualModule.findById(id);
|
|
11661
12141
|
if (!virtualModule) return;
|
|
11662
12142
|
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
11663
|
-
|
|
12143
|
+
const code = virtualModule.code;
|
|
12144
|
+
if (code && id.includes("__loadShare__")) {
|
|
12145
|
+
if (isServerContext(this, loadOptions?.ssr === true)) return prependWorkspaceSingletonSsrImport(code);
|
|
12146
|
+
}
|
|
12147
|
+
return code;
|
|
11664
12148
|
}
|
|
11665
12149
|
},
|
|
11666
12150
|
...options.experiments.externalRuntime ? [pluginExternalRuntimeCore()] : [],
|
|
@@ -11920,8 +12404,7 @@ function federation(mfUserOptions) {
|
|
|
11920
12404
|
const virtualModule = VirtualModule.findById(id);
|
|
11921
12405
|
if (!virtualModule?.code) return null;
|
|
11922
12406
|
let code = virtualModule.code;
|
|
11923
|
-
|
|
11924
|
-
if (consumerTarget === "server" || !consumerTarget && isSsrBuild) {
|
|
12407
|
+
if (isServerContext(this, isSsrBuild)) {
|
|
11925
12408
|
const withSsrImport = prependWorkspaceSingletonSsrImport(code);
|
|
11926
12409
|
if (withSsrImport !== code) {
|
|
11927
12410
|
const pkg = getCachedLoadSharePkg(id);
|
|
@@ -12041,11 +12524,13 @@ function federation(mfUserOptions) {
|
|
|
12041
12524
|
const isAstro = hasPackageDependency("astro");
|
|
12042
12525
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
|
12043
12526
|
if (!config.define) config.define = {};
|
|
12527
|
+
const userSetEnvTarget = "ENV_TARGET" in config.define;
|
|
12044
12528
|
applyBuildTimeRuntimeDefines(config.define, options, {
|
|
12045
12529
|
target: resolvedTarget,
|
|
12046
12530
|
isAstro,
|
|
12047
12531
|
defaultDisableSnapshot: resolvedTarget === "node" ? true : void 0
|
|
12048
12532
|
});
|
|
12533
|
+
inheritedEnvTarget = userSetEnvTarget ? void 0 : config.define.ENV_TARGET;
|
|
12049
12534
|
for (const warning of getRuntimeCapabilityConfigurationWarnings(options)) {
|
|
12050
12535
|
if (emittedRuntimeCapabilityWarnings.has(warning)) continue;
|
|
12051
12536
|
emittedRuntimeCapabilityWarnings.add(warning);
|
|
@@ -12061,6 +12546,7 @@ function federation(mfUserOptions) {
|
|
|
12061
12546
|
if (!isServerEnvironment(name, config)) return;
|
|
12062
12547
|
const isAstro = hasPackageDependency("astro");
|
|
12063
12548
|
config.define = { ...config.define ?? {} };
|
|
12549
|
+
if (inheritedEnvTarget !== void 0 && config.define.ENV_TARGET === inheritedEnvTarget) delete config.define.ENV_TARGET;
|
|
12064
12550
|
applyBuildTimeRuntimeDefines(config.define, options, {
|
|
12065
12551
|
target: options.target ?? "node",
|
|
12066
12552
|
isAstro,
|