@module-federation/vite 1.21.5 → 1.22.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 +25 -4
- package/lib/{buildPaths-BkaQHrd2.js → buildPaths-BoaQTkxt.js} +20 -1
- package/lib/{dtsConstants-BsaLBaaK.js → dtsConstants-BEGrtvcw.js} +21 -5
- package/lib/index.d.ts +25 -3
- package/lib/index.js +477 -213
- package/lib/{pluginDts-BhONN9dR.js → pluginDts-D7Faa4NJ.js} +9 -3
- package/lib/{ssrEntryLoader-CqtaiDUp.js → ssrEntryLoader-CMVCDSsG.js} +48 -13
- package/lib/{ssrVmStrategy-D4KB-y3H.js → ssrVmStrategy-Cx9WlTsx.js} +15 -3
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as normalizePathForImport } from "./buildPaths-
|
|
2
|
-
import { _ as mfError, g as createModuleFederationError, l as hasPackageDependency, p as resolveImportPath } from "./dtsConstants-
|
|
1
|
+
import { n as normalizePathForImport } from "./buildPaths-BoaQTkxt.js";
|
|
2
|
+
import { _ as mfError, g as createModuleFederationError, l as hasPackageDependency, p as resolveImportPath } from "./dtsConstants-BEGrtvcw.js";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
5
|
import os from "os";
|
|
@@ -34,6 +34,7 @@ const getIPv4 = () => {
|
|
|
34
34
|
return (getIpv4Interfaces()[0] || { address: localIpv4 }).address;
|
|
35
35
|
};
|
|
36
36
|
const DEV_TYPES_FOLDER = ".dev-server";
|
|
37
|
+
const UPDATE_DEBOUNCE_MS = 300;
|
|
37
38
|
const forkDevWorkerPath = (() => {
|
|
38
39
|
return resolveImportPath("@module-federation/dts-plugin/dist/fork-dev-worker.js");
|
|
39
40
|
})();
|
|
@@ -256,11 +257,16 @@ function pluginDts(options) {
|
|
|
256
257
|
disableLiveReload: devOptions.disableLiveReload,
|
|
257
258
|
disableHotTypesReload: devOptions.disableHotTypesReload
|
|
258
259
|
});
|
|
259
|
-
|
|
260
|
+
let updateTimer;
|
|
261
|
+
const update = () => {
|
|
262
|
+
clearTimeout(updateTimer);
|
|
263
|
+
updateTimer = setTimeout(() => devWorker?.update(), UPDATE_DEBOUNCE_MS);
|
|
264
|
+
};
|
|
260
265
|
server.watcher.on("change", update);
|
|
261
266
|
server.watcher.on("add", update);
|
|
262
267
|
server.watcher.on("unlink", update);
|
|
263
268
|
server.httpServer?.once("close", () => {
|
|
269
|
+
clearTimeout(updateTimer);
|
|
264
270
|
devWorker?.exit();
|
|
265
271
|
server.watcher.off("change", update);
|
|
266
272
|
server.watcher.off("add", update);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as EXTERNAL_URL_RE } from "./buildPaths-
|
|
1
|
+
import { t as EXTERNAL_URL_RE } from "./buildPaths-BoaQTkxt.js";
|
|
2
2
|
//#region src/utils/fetchWithTimeout.ts
|
|
3
3
|
const DEFAULT_SSR_FETCH_TIMEOUT_MS = 1e4;
|
|
4
4
|
const DEFAULT_SSR_FETCH_MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -188,7 +188,8 @@ async function resolveSharedExternal(id, resolvedShared) {
|
|
|
188
188
|
}
|
|
189
189
|
async function getOrCreateRunner(remoteOrigin, resolvedShared, fetchTimeoutMs, fetchMaxBytes) {
|
|
190
190
|
const cacheKey = getRunnerCacheKey(remoteOrigin, resolvedShared, fetchTimeoutMs, fetchMaxBytes);
|
|
191
|
-
|
|
191
|
+
const cached = runnerCache.get(cacheKey);
|
|
192
|
+
if (cached) return cached.promise;
|
|
192
193
|
const promise = (async () => {
|
|
193
194
|
const viteRunner = await getModuleRunnerModule();
|
|
194
195
|
if (!viteRunner) return null;
|
|
@@ -215,7 +216,10 @@ async function getOrCreateRunner(remoteOrigin, resolvedShared, fetchTimeoutMs, f
|
|
|
215
216
|
return null;
|
|
216
217
|
}
|
|
217
218
|
})();
|
|
218
|
-
runnerCache.set(cacheKey,
|
|
219
|
+
runnerCache.set(cacheKey, {
|
|
220
|
+
remoteOrigin,
|
|
221
|
+
promise
|
|
222
|
+
});
|
|
219
223
|
return promise;
|
|
220
224
|
}
|
|
221
225
|
const _path = () => nodeImport("path");
|
|
@@ -252,10 +256,19 @@ function parseRunnerInvokeResult(data) {
|
|
|
252
256
|
* Version key for a resolved SSR entry. Derived from the remote's manifest
|
|
253
257
|
* content so a redeploy at the same URL produces a different key, which in
|
|
254
258
|
* turn produces different temp-file names — busting both our caches and
|
|
255
|
-
* Node's ESM module cache. Convention-resolved entries (no manifest)
|
|
256
|
-
* stable placeholder key
|
|
259
|
+
* Node's ESM module cache. Convention-resolved entries (no manifest) use a
|
|
260
|
+
* stable placeholder key for ordinary loads; explicit `revalidate()` calls
|
|
261
|
+
* advance a process-local generation so the next import is fresh.
|
|
257
262
|
*/
|
|
258
263
|
const UNVERSIONED = "unversioned";
|
|
264
|
+
const unversionedGenerations = /* @__PURE__ */ new Map();
|
|
265
|
+
let unversionedGlobalGeneration = 0;
|
|
266
|
+
function getUnversionedVersionKey(remoteEntryUrl) {
|
|
267
|
+
return `${UNVERSIONED}-${unversionedGlobalGeneration}-${unversionedGenerations.get(remoteEntryUrl) ?? 0}`;
|
|
268
|
+
}
|
|
269
|
+
function bumpUnversionedGeneration(remoteEntryUrl) {
|
|
270
|
+
unversionedGenerations.set(remoteEntryUrl, (unversionedGenerations.get(remoteEntryUrl) ?? 0) + 1);
|
|
271
|
+
}
|
|
259
272
|
function hashString(value) {
|
|
260
273
|
let hash = 2166136261;
|
|
261
274
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -392,16 +405,16 @@ function buildSsrEntryCandidates(ctx, options = {}) {
|
|
|
392
405
|
if (!options.skipServerBuild) candidates.push({
|
|
393
406
|
url: `${remoteOrigin}/__mf_server__/${filename}.ssr.js`,
|
|
394
407
|
type: "module",
|
|
395
|
-
versionKey:
|
|
408
|
+
versionKey: getUnversionedVersionKey(ctx.entryUrl)
|
|
396
409
|
});
|
|
397
410
|
candidates.push({
|
|
398
411
|
url: `${base}.ssr.js`,
|
|
399
412
|
type: "module",
|
|
400
|
-
versionKey:
|
|
413
|
+
versionKey: getUnversionedVersionKey(ctx.entryUrl)
|
|
401
414
|
}, {
|
|
402
415
|
url: `${remoteOrigin}/__mf_ssr__/${filename}.ssr.js`,
|
|
403
416
|
type: "module",
|
|
404
|
-
versionKey:
|
|
417
|
+
versionKey: getUnversionedVersionKey(ctx.entryUrl)
|
|
405
418
|
});
|
|
406
419
|
return candidates;
|
|
407
420
|
}
|
|
@@ -416,14 +429,14 @@ async function resolveSSREntryImpl(remoteEntryUrl, fetchTimeoutMs, fetchMaxBytes
|
|
|
416
429
|
if (isSsrEntry(remoteEntryUrl)) return {
|
|
417
430
|
url: remoteEntryUrl,
|
|
418
431
|
type: "module",
|
|
419
|
-
versionKey:
|
|
432
|
+
versionKey: getUnversionedVersionKey(remoteEntryUrl)
|
|
420
433
|
};
|
|
421
434
|
if (!isManifestEntry(remoteEntryUrl)) {
|
|
422
435
|
const filename = getEntryFilename(remoteEntryUrl);
|
|
423
436
|
const fromServerBuild = await headCheckSsrEntry({
|
|
424
437
|
url: `${remoteEntryUrl.replace(/\/[^/]+$/, "")}/__mf_server__/${filename}.ssr.js`,
|
|
425
438
|
type: "module",
|
|
426
|
-
versionKey:
|
|
439
|
+
versionKey: getUnversionedVersionKey(remoteEntryUrl)
|
|
427
440
|
}, fetchTimeoutMs);
|
|
428
441
|
if (fromServerBuild) return fromServerBuild;
|
|
429
442
|
}
|
|
@@ -457,7 +470,10 @@ async function getSSREntry(remoteEntryUrl, maxAgeMs, fetchTimeoutMs, fetchMaxByt
|
|
|
457
470
|
manifestFetchCache.delete(makeUrlCacheKey(getManifestUrl(remoteEntryUrl), fetchTimeoutMs, fetchMaxBytes));
|
|
458
471
|
const record = setSsrEntryCache(remoteEntryUrl, fetchTimeoutMs, fetchMaxBytes);
|
|
459
472
|
const next = await record.promise.catch(() => null);
|
|
460
|
-
if (previous && next && previous.versionKey !== next.versionKey)
|
|
473
|
+
if (previous && next && previous.versionKey !== next.versionKey) {
|
|
474
|
+
dropRemoteCaches(remoteEntryUrl);
|
|
475
|
+
await clearRunnerCaches(remoteEntryUrl);
|
|
476
|
+
}
|
|
461
477
|
return record.promise;
|
|
462
478
|
}
|
|
463
479
|
/**
|
|
@@ -477,6 +493,19 @@ function dropRemoteCaches(remoteEntryUrl) {
|
|
|
477
493
|
tempFilePathCache.delete(key);
|
|
478
494
|
}
|
|
479
495
|
}
|
|
496
|
+
async function clearRunnerCaches(remoteEntryUrl) {
|
|
497
|
+
let remoteOrigin;
|
|
498
|
+
if (remoteEntryUrl) try {
|
|
499
|
+
remoteOrigin = new URL(remoteEntryUrl).origin;
|
|
500
|
+
} catch {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
await Promise.all([...runnerCache.values()].filter((cached) => !remoteOrigin || cached.remoteOrigin === remoteOrigin).map(async (cached) => {
|
|
504
|
+
try {
|
|
505
|
+
(await cached.promise)?.clearCache?.();
|
|
506
|
+
} catch {}
|
|
507
|
+
}));
|
|
508
|
+
}
|
|
480
509
|
/**
|
|
481
510
|
* Drop the loader's caches so the next `loadEntry` re-resolves and re-fetches
|
|
482
511
|
* remote SSR entries. Pass a remote entry URL to scope the invalidation to one
|
|
@@ -489,16 +518,19 @@ function dropRemoteCaches(remoteEntryUrl) {
|
|
|
489
518
|
*/
|
|
490
519
|
function revalidate(remoteEntryUrl) {
|
|
491
520
|
if (remoteEntryUrl) {
|
|
521
|
+
bumpUnversionedGeneration(remoteEntryUrl);
|
|
492
522
|
for (const key of ssrEntryCache.keys()) if (key.endsWith(`::${remoteEntryUrl}`)) ssrEntryCache.delete(key);
|
|
493
523
|
const manifestUrl = getManifestUrl(remoteEntryUrl);
|
|
494
524
|
for (const key of manifestFetchCache.keys()) if (key.endsWith(`::${manifestUrl}`)) manifestFetchCache.delete(key);
|
|
495
525
|
dropRemoteCaches(remoteEntryUrl);
|
|
496
526
|
} else {
|
|
527
|
+
unversionedGlobalGeneration += 1;
|
|
497
528
|
ssrEntryCache.clear();
|
|
498
529
|
manifestFetchCache.clear();
|
|
499
530
|
tempFileCache.clear();
|
|
500
531
|
tempFilePathCache.clear();
|
|
501
532
|
}
|
|
533
|
+
clearRunnerCaches(remoteEntryUrl);
|
|
502
534
|
const federation = globalThis.__FEDERATION__;
|
|
503
535
|
for (const instance of federation?.__INSTANCES__ ?? []) try {
|
|
504
536
|
instance?.moduleCache?.clear?.();
|
|
@@ -555,6 +587,9 @@ function transformSsrCode(code, base, sharedPkgMap) {
|
|
|
555
587
|
function isVitePreloadHelperSpecifier(specifier) {
|
|
556
588
|
return specifier.includes("preload-helper");
|
|
557
589
|
}
|
|
590
|
+
function getTempFileImportUrl(filePath, versionKey) {
|
|
591
|
+
return `file://${filePath}?v=${encodeURIComponent(versionKey)}`;
|
|
592
|
+
}
|
|
558
593
|
/**
|
|
559
594
|
* Fetch an HTTP ESM module, transform it, write it to a temp .js file and
|
|
560
595
|
* return the file path. Recursively does the same for HTTP transitive imports
|
|
@@ -601,7 +636,7 @@ async function fetchEsmToTempFile(url, tmpDir, visited, pending, sharedPkgMap, v
|
|
|
601
636
|
const subMap = /* @__PURE__ */ new Map();
|
|
602
637
|
await Promise.all([...new Set(relImports)].filter((u) => u.startsWith("http://") || u.startsWith("https://")).map(async (u) => {
|
|
603
638
|
const tmpPath = await fetchEsmToTempFile(u, tmpDir, visited, pending, sharedPkgMap, versionKey, fetchTimeoutMs, contextKey, fetchMaxBytes);
|
|
604
|
-
subMap.set(u,
|
|
639
|
+
subMap.set(u, getTempFileImportUrl(tmpPath, versionKey));
|
|
605
640
|
}));
|
|
606
641
|
code = transformSsrCode(code, base, sharedPkgMap);
|
|
607
642
|
for (const [httpUrl, fileUrl] of subMap) code = code.split(httpUrl).join(fileUrl);
|
|
@@ -631,7 +666,7 @@ async function importTempModule(filePath, versionKey) {
|
|
|
631
666
|
}
|
|
632
667
|
let warnedVmUnavailable = false;
|
|
633
668
|
async function tryVmStrategy(ssrEntry, options) {
|
|
634
|
-
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-
|
|
669
|
+
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-Cx9WlTsx.js");
|
|
635
670
|
if (!await isVmStrategyAvailable()) {
|
|
636
671
|
if (!warnedVmUnavailable) {
|
|
637
672
|
warnedVmUnavailable = true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as findSharedKey } from "./sharedKeyMatcher-DiUzRVH1.js";
|
|
2
|
-
import { c as readResponseTextBounded, n as neutralizeBrowserPreloadHelpers, s as fetchWithTimeout, t as SsrEntryHttpError } from "./ssrEntryLoader-
|
|
2
|
+
import { c as readResponseTextBounded, n as neutralizeBrowserPreloadHelpers, s as fetchWithTimeout, t as SsrEntryHttpError } from "./ssrEntryLoader-CMVCDSsG.js";
|
|
3
3
|
//#region src/utils/ssrVmStrategy.ts
|
|
4
4
|
/**
|
|
5
5
|
* vm.SourceTextModule strategy for loading remote SSR entries.
|
|
@@ -90,6 +90,7 @@ function createSyntheticModule(vm, specifier, namespace) {
|
|
|
90
90
|
}
|
|
91
91
|
const httpModuleCache = /* @__PURE__ */ new Map();
|
|
92
92
|
const namespaceCache = /* @__PURE__ */ new Map();
|
|
93
|
+
const linkQueues = /* @__PURE__ */ new WeakMap();
|
|
93
94
|
const contextIds = /* @__PURE__ */ new WeakMap();
|
|
94
95
|
let nextContextId = 1;
|
|
95
96
|
function getContextId(context) {
|
|
@@ -153,10 +154,21 @@ async function linkModule(vm, specifier, referencingModule, options) {
|
|
|
153
154
|
if (url) return getHttpModule(vm, url, options);
|
|
154
155
|
return createSyntheticModule(vm, specifier, await loadBareModule(specifier, options));
|
|
155
156
|
}
|
|
157
|
+
async function linkModuleGraph(module, linker, cacheContext) {
|
|
158
|
+
const current = (linkQueues.get(cacheContext) ?? Promise.resolve()).catch(() => {}).then(async () => {
|
|
159
|
+
if (module.status === "unlinked") await module.link(linker);
|
|
160
|
+
});
|
|
161
|
+
linkQueues.set(cacheContext, current);
|
|
162
|
+
try {
|
|
163
|
+
await current;
|
|
164
|
+
} finally {
|
|
165
|
+
if (linkQueues.get(cacheContext) === current) linkQueues.delete(cacheContext);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
156
168
|
async function importDynamically(vm, specifier, referencingModule, options) {
|
|
157
169
|
const linker = (spec, referencer) => linkModule(vm, spec, referencer, options);
|
|
158
170
|
const module = await linker(specifier, referencingModule);
|
|
159
|
-
|
|
171
|
+
await linkModuleGraph(module, linker, options.cacheContext);
|
|
160
172
|
if (module.status === "linked") await module.evaluate();
|
|
161
173
|
return module;
|
|
162
174
|
}
|
|
@@ -172,7 +184,7 @@ async function loadViaVmStrategy(entryUrl, options) {
|
|
|
172
184
|
if (!namespaceCache.has(cacheKey)) namespaceCache.set(cacheKey, (async () => {
|
|
173
185
|
const entryModule = await getHttpModule(vm, entryUrl, options);
|
|
174
186
|
const linker = (specifier, referencingModule) => linkModule(vm, specifier, referencingModule, options);
|
|
175
|
-
|
|
187
|
+
await linkModuleGraph(entryModule, linker, options.cacheContext);
|
|
176
188
|
if (entryModule.status === "linked") await entryModule.evaluate();
|
|
177
189
|
return entryModule.namespace;
|
|
178
190
|
})().catch((error) => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-
|
|
1
|
+
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-CMVCDSsG.js";
|
|
2
2
|
export { SsrEntryHttpError, ssrEntryLoaderPlugin as default, neutralizeBrowserPreloadHelpers, revalidate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -91,6 +91,6 @@
|
|
|
91
91
|
"tsdown": "0.22.14",
|
|
92
92
|
"typescript": "7.0.2",
|
|
93
93
|
"vite": "8.2.0",
|
|
94
|
-
"vitest": "4.1.
|
|
94
|
+
"vitest": "4.1.11"
|
|
95
95
|
}
|
|
96
96
|
}
|