@module-federation/vite 1.23.5 → 1.23.7
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 +22 -1
- package/lib/{dtsConstants-BQdFpgKb.js → dtsConstants-CDuC8Bb7.js} +84 -24
- package/lib/index.js +1464 -1240
- package/lib/{logger-DOwfTlw5.js → logger-D67aJYOe.js} +110 -16
- package/lib/{pluginDts-DShMdjzR.js → pluginDts-rZMRTCTz.js} +5 -9
- package/lib/{sharedKeyMatcher-CHp4QRNq.js → sharedKeyMatcher-C04bVN1q.js} +8 -1
- package/lib/{ssrEntryLoader-CHdWk8Yg.js → ssrEntryLoader-DKpOrW8D.js} +152 -31
- package/lib/{ssrVmStrategy-BkyvcG4s.js → ssrVmStrategy-D1cSKUV-.js} +5 -13
- package/lib/utils/ssrEntryLoader.d.ts +7 -1
- package/lib/utils/ssrEntryLoader.js +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<br />
|
|
10
10
|
|
|
11
11
|
<a href="https://github.com/sponsors/gioboa">
|
|
12
|
-
<img src="./docs/sponsors.png" alt="Sponsors" />
|
|
12
|
+
<img src="./docs/sponsors.png" alt="Sponsors" width="677" />
|
|
13
13
|
</a>
|
|
14
14
|
|
|
15
15
|
## Become a sponsor
|
|
@@ -253,10 +253,31 @@ export default defineConfig({
|
|
|
253
253
|
|
|
254
254
|
The host app configuration specifies its name, the filename of its exposed remote entry remoteEntry.js, and importantly, the configuration of the remote application to load.
|
|
255
255
|
Object remotes that omit `type` retain the legacy `"var"` default and emit a warning. Use `type: "module"` for Vite ESM remotes. Use `type: "var"` explicitly only for global-format remotes, such as Webpack/Rspack remotes or a Vite remote's `varFilename` output.
|
|
256
|
+
|
|
257
|
+
The optional `varFilename` wrapper registers the container on `globalThis[name]` and throws if that name already belongs to another global (e.g. `window`, `self`, `location`), even when its value is `0`, `false`, `""` or `null` (e.g. `length`). Use a distinct name or an ESM remote (`type: "module"`). Loading the wrapper again keeps the existing container.
|
|
256
258
|
You can specify the place the host initialization file is injected with the **hostInitInjectLocation** option, which is described in the example code above.
|
|
257
259
|
The **moduleParseTimeout** option allows you to configure the maximum time to wait for module parsing during the build process.
|
|
258
260
|
The **moduleParseIdleTimeout** option is an alternative that resets the timer on every parsed module. It only fires when there has been no module activity for the configured duration, making it suitable for large codebases where the total build time exceeds the fixed timeout.
|
|
259
261
|
|
|
262
|
+
## SSR runtime initialization
|
|
263
|
+
|
|
264
|
+
For applications with configured remotes, SSR entries and modules importing
|
|
265
|
+
`@module-federation/runtime` initialize the owning runtime before plain
|
|
266
|
+
`getInstance()` or `loadRemote()` calls run. Startup registers remotes and shares
|
|
267
|
+
without fetching remote entries or manifests, or requesting a root expose. Remote
|
|
268
|
+
loading stays lazy, including with `loaded-first`. Apps without remotes receive no
|
|
269
|
+
SSR host bootstrap. Cold development SSR follows the existing Vite 8+ support gate;
|
|
270
|
+
independent SSR builds are supported on Vite 5–8.
|
|
271
|
+
|
|
272
|
+
A remote the application registers at runtime with `init()` or `registerRemotes()`
|
|
273
|
+
under a configured remote's name or alias replaces that remote for `loadRemote()`
|
|
274
|
+
calls. Static `import "remote/expose"` statements keep using the configured entry.
|
|
275
|
+
|
|
276
|
+
Dependencies externalized by Vite keep Node's own runtime resolution. Their runtime
|
|
277
|
+
imports are not bound to the application's instance by this bootstrap.
|
|
278
|
+
Include runtime-consuming dependencies in Vite's `ssr.noExternal` when they need
|
|
279
|
+
to use the application's runtime instance.
|
|
280
|
+
|
|
260
281
|
## SSR entry loading strategy
|
|
261
282
|
|
|
262
283
|
SSR hosts can choose how HTTP ESM remote entries are evaluated during build and preview:
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as mfWarn, t as createModuleFederationError, u as normalizePathForImport } from "./logger-D67aJYOe.js";
|
|
2
|
+
import { d as getNodeModulesSuffix, r as getSharedRuntimeKey } from "./sharedKeyMatcher-C04bVN1q.js";
|
|
3
3
|
import { existsSync, readFileSync, readdirSync, realpathSync } from "fs";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
|
+
import { isIPv6 } from "node:net";
|
|
8
9
|
//#region src/utils/reactShares.ts
|
|
9
10
|
/** Property under which React 19 exposes its internals object. */
|
|
10
11
|
const REACT_CLIENT_INTERNALS_KEY = "__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE";
|
|
@@ -37,6 +38,7 @@ function getDependencyCacheKey(cwd, dependencyName) {
|
|
|
37
38
|
const installedPackageJsonCache = /* @__PURE__ */ new Map();
|
|
38
39
|
const dependentsLookupCache = /* @__PURE__ */ new Map();
|
|
39
40
|
const reachableDependencyNames = /* @__PURE__ */ new Map();
|
|
41
|
+
const pnpmStorePackageIndexCache = /* @__PURE__ */ new Map();
|
|
40
42
|
function setPackageDetectionCwd(cwd) {
|
|
41
43
|
packageDetectionCwd = cwd;
|
|
42
44
|
}
|
|
@@ -494,7 +496,6 @@ function getInstalledPackageJson(pkg, opts) {
|
|
|
494
496
|
return result;
|
|
495
497
|
}
|
|
496
498
|
function tryReadPackageJson(packageJsonPath, expectedName) {
|
|
497
|
-
if (!existsSync(packageJsonPath)) return void 0;
|
|
498
499
|
try {
|
|
499
500
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
500
501
|
if (expectedName !== void 0 && packageJson.name !== expectedName) return void 0;
|
|
@@ -508,19 +509,6 @@ function tryReadPackageJson(packageJsonPath, expectedName) {
|
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
|
|
511
|
-
const findPackageInPnpmStore = (startDir) => {
|
|
512
|
-
for (const dir of ancestorDirs(startDir)) {
|
|
513
|
-
const pnpmStoreDir = path$1.join(dir, "node_modules", ".pnpm");
|
|
514
|
-
if (!existsSync(pnpmStoreDir)) continue;
|
|
515
|
-
try {
|
|
516
|
-
for (const entry of readdirSync(pnpmStoreDir, { withFileTypes: true })) {
|
|
517
|
-
if (!entry.isDirectory()) continue;
|
|
518
|
-
const candidate = tryReadPackageJson(path$1.join(pnpmStoreDir, entry.name, "node_modules", packageName, "package.json"));
|
|
519
|
-
if (candidate?.packageJson.name === packageName) return candidate;
|
|
520
|
-
}
|
|
521
|
-
} catch {}
|
|
522
|
-
}
|
|
523
|
-
};
|
|
524
512
|
let resolvedPath;
|
|
525
513
|
try {
|
|
526
514
|
const rootPackageJson = path$1.join(cwd, "package.json");
|
|
@@ -542,7 +530,54 @@ function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
|
|
|
542
530
|
const directCandidate = tryReadPackageJson(path$1.join(dir, "node_modules", packageName, "package.json"), packageName);
|
|
543
531
|
if (directCandidate) return directCandidate;
|
|
544
532
|
}
|
|
545
|
-
return findPackageInDependents(packageName, cwd) ?? findPackageInPnpmStore(cwd);
|
|
533
|
+
return findPackageInDependents(packageName, cwd) ?? findPackageInPnpmStore(packageName, cwd);
|
|
534
|
+
}
|
|
535
|
+
function readDirEntries(dir) {
|
|
536
|
+
try {
|
|
537
|
+
return readdirSync(dir, { withFileTypes: true });
|
|
538
|
+
} catch {
|
|
539
|
+
return [];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
function isDirOrLink(entry) {
|
|
543
|
+
return entry.isDirectory() || entry.isSymbolicLink();
|
|
544
|
+
}
|
|
545
|
+
function getPnpmStorePackageIndex(startDir) {
|
|
546
|
+
const cached = pnpmStorePackageIndexCache.get(startDir);
|
|
547
|
+
if (cached) return cached;
|
|
548
|
+
const index = /* @__PURE__ */ new Map();
|
|
549
|
+
const add = (name, packageJsonPath) => {
|
|
550
|
+
const paths = index.get(name);
|
|
551
|
+
if (paths) paths.push(packageJsonPath);
|
|
552
|
+
else index.set(name, [packageJsonPath]);
|
|
553
|
+
};
|
|
554
|
+
for (const dir of ancestorDirs(startDir)) {
|
|
555
|
+
const pnpmStoreDir = path$1.join(dir, "node_modules", ".pnpm");
|
|
556
|
+
for (const entry of readDirEntries(pnpmStoreDir)) {
|
|
557
|
+
if (!entry.isDirectory()) continue;
|
|
558
|
+
const storeNodeModules = path$1.join(pnpmStoreDir, entry.name, "node_modules");
|
|
559
|
+
for (const packageEntry of readDirEntries(storeNodeModules)) {
|
|
560
|
+
if (!isDirOrLink(packageEntry)) continue;
|
|
561
|
+
const entryDir = path$1.join(storeNodeModules, packageEntry.name);
|
|
562
|
+
if (!packageEntry.name.startsWith("@")) {
|
|
563
|
+
add(packageEntry.name, path$1.join(entryDir, "package.json"));
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
for (const scopedEntry of readDirEntries(entryDir)) {
|
|
567
|
+
if (!isDirOrLink(scopedEntry)) continue;
|
|
568
|
+
add(`${packageEntry.name}/${scopedEntry.name}`, path$1.join(entryDir, scopedEntry.name, "package.json"));
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
pnpmStorePackageIndexCache.set(startDir, index);
|
|
574
|
+
return index;
|
|
575
|
+
}
|
|
576
|
+
function findPackageInPnpmStore(packageName, startDir) {
|
|
577
|
+
for (const packageJsonPath of getPnpmStorePackageIndex(startDir).get(packageName) ?? []) {
|
|
578
|
+
const candidate = tryReadPackageJson(packageJsonPath, packageName);
|
|
579
|
+
if (candidate) return candidate;
|
|
580
|
+
}
|
|
546
581
|
}
|
|
547
582
|
/**
|
|
548
583
|
* A package installed only under a dependent is invisible to the walks above.
|
|
@@ -609,12 +644,13 @@ function warnOnAmbiguousDependents(packageName, candidates) {
|
|
|
609
644
|
const versions = [...viaByVersion].map(([version, via]) => `${version} (via ${via})`);
|
|
610
645
|
mfWarn(`Shared package "${packageName}" is not a dependency of the project, and its closest dependents install different versions: ${versions.join(", ")}. The fallback uses ${versions[0]}. Add "${packageName}" to the project's dependencies or set its shared "import" to choose the version.`);
|
|
611
646
|
}
|
|
647
|
+
const realpath = process.platform === "win32" ? realpathSync : realpathSync.native;
|
|
612
648
|
/** The package Node's `node_modules` lookup finds from `fromDir`, read at its real path. */
|
|
613
649
|
function findPackageFrom(packageName, fromDir) {
|
|
614
650
|
const entry = findNodeModulesEntry(packageName, fromDir);
|
|
615
651
|
if (!entry) return void 0;
|
|
616
652
|
try {
|
|
617
|
-
return tryReadPackageJson(path$1.join(
|
|
653
|
+
return tryReadPackageJson(path$1.join(realpath(entry), "package.json"), packageName);
|
|
618
654
|
} catch {
|
|
619
655
|
return;
|
|
620
656
|
}
|
|
@@ -689,14 +725,11 @@ function getInstalledPackageEntry(pkg, opts) {
|
|
|
689
725
|
const explicitEntry = resolveExportsEntry(getPackageExportsTarget(pkg, packageName, packageJson.exports), opts?.conditions) || (typeof packageJson.module === "string" ? packageJson.module : void 0) || (typeof packageJson.main === "string" ? packageJson.main : void 0) || "index.js";
|
|
690
726
|
return path$1.join(installed.dir, explicitEntry);
|
|
691
727
|
}
|
|
692
|
-
/**
|
|
693
|
-
* Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
|
|
694
|
-
* on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
|
|
695
|
-
*/
|
|
728
|
+
/** Detect Vite 8+ (Rolldown) from the Vite version on the plugin hook context. */
|
|
696
729
|
function getIsRolldown(ctx) {
|
|
697
730
|
const viteVersion = ctx?.meta?.viteVersion;
|
|
698
731
|
const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
|
|
699
|
-
return Number.isFinite(viteMajor) && viteMajor >= 8
|
|
732
|
+
return Number.isFinite(viteMajor) && viteMajor >= 8;
|
|
700
733
|
}
|
|
701
734
|
/**
|
|
702
735
|
* Rolldown 1.2.10 added `codeSplitting.groups[].debugName` and warns when a group's
|
|
@@ -741,7 +774,34 @@ function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || proce
|
|
|
741
774
|
}
|
|
742
775
|
}
|
|
743
776
|
//#endregion
|
|
777
|
+
//#region src/utils/devServerHost.ts
|
|
778
|
+
const UNSPECIFIED_HOSTS = /* @__PURE__ */ new Set(["0.0.0.0", "::"]);
|
|
779
|
+
/**
|
|
780
|
+
* Hostname for client-facing HTTP/WS origins built from Vite `server.host`.
|
|
781
|
+
*
|
|
782
|
+
* Unspecified bind addresses (`0.0.0.0`, `::`) map to `localhost`, matching
|
|
783
|
+
* Vite's own printed local URL. IPv6 addresses are wrapped in brackets so
|
|
784
|
+
* `http://[::1]:5173` / `ws://[::1]:5173` parse as valid URLs.
|
|
785
|
+
*/
|
|
786
|
+
function formatDevServerHostForOrigin(host) {
|
|
787
|
+
if (typeof host !== "string" || UNSPECIFIED_HOSTS.has(host)) return "localhost";
|
|
788
|
+
if (host.startsWith("[") && host.endsWith("]")) return host;
|
|
789
|
+
return isIPv6(host) ? `[${host}]` : host;
|
|
790
|
+
}
|
|
791
|
+
const FILE_EVENTS = [
|
|
792
|
+
"change",
|
|
793
|
+
"add",
|
|
794
|
+
"unlink"
|
|
795
|
+
];
|
|
796
|
+
/** Runs `listener` on every file change, add, or unlink; returns a function that unsubscribes it. */
|
|
797
|
+
function watchFileEvents(watcher, listener) {
|
|
798
|
+
for (const event of FILE_EVENTS) watcher.on(event, listener);
|
|
799
|
+
return () => {
|
|
800
|
+
for (const event of FILE_EVENTS) watcher.off(event, listener);
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
//#endregion
|
|
744
804
|
//#region src/utils/dtsConstants.ts
|
|
745
805
|
const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
|
|
746
806
|
//#endregion
|
|
747
|
-
export {
|
|
807
|
+
export { supportsCodeSplittingGroupDebugName as C, isReactCoreShare as E, sharedCacheHelperCode as S, REACT_DOM_CLIENT_SHARE as T, packageNameDecode as _, getInstalledPackageEntry as a, resolveModulePath as b, getPackageDetectionCwd as c, getPackageNameFromNodeModulePath as d, getSharedCacheDescriptor as f, isPackageInstalled as g, isPackageExportAvailable as h, getDependencyNames as i, getPackageExportSpecifiersForFile as l, isNuxtProjectRoot as m, formatDevServerHostForOrigin as n, getInstalledPackageJson as o, hasPackageDependency as p, watchFileEvents as r, getIsRolldown as s, DEFAULT_PUBLIC_TYPES_FOLDER as t, getPackageName as u, packageNameEncode as v, REACT_CLIENT_INTERNALS_KEY as w, setPackageDetectionCwd as x, resolveImportPath as y };
|