@module-federation/vite 1.23.0 → 1.23.2
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 +36 -0
- package/lib/{dtsConstants-DEMpRfBz.js → dtsConstants-r5OfegUr.js} +2 -32
- package/lib/index.d.ts +17 -0
- package/lib/index.js +605 -414
- package/lib/logger-DOwfTlw5.js +366 -0
- package/lib/{pluginDts-VSLhAx6d.js → pluginDts-DnEX3cp_.js} +3 -3
- package/lib/{ssrEntryLoader-BvAkpCyi.js → ssrEntryLoader-DEH3eV1e.js} +238 -54
- package/lib/{ssrVmStrategy-CDbcwMnf.js → ssrVmStrategy-COMHOCN2.js} +69 -5
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +4 -4
- package/lib/buildPaths-BoaQTkxt.js +0 -66
package/README.md
CHANGED
|
@@ -402,6 +402,42 @@ federation({
|
|
|
402
402
|
`provideExternalRuntime` injects a local runtime plugin that publishes `runtime-core` on `globalThis._FEDERATION_RUNTIME_CORE`. `externalRuntime` rewrites imports of `@module-federation/runtime-core` to read that global. A container that also `exposes` (e.g. a host consumed by its own remotes) may provide the runtime too, as long as exactly one container on the page does and it is loaded before any `externalRuntime` remote evaluates (a second provider is ignored with a `Detect multiple module federation runtime!` warning; a remote evaluated before the provider throws `_FEDERATION_RUNTIME_CORE is missing`).
|
|
403
403
|
The `externalRuntime` rewrite applies to the browser remote graph; SSR remote entries continue to resolve `@module-federation/runtime-core` from Node so they do not depend on the browser global.
|
|
404
404
|
|
|
405
|
+
## Host provides all shared (`experiments.hostProvidesAllShared`)
|
|
406
|
+
|
|
407
|
+
For topologies where **one host provides every shared dependency** and remotes only consume them, shared dependencies can be resolved by a native browser [import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) instead of the Module Federation runtime. No `loadShare` / prebuild glue is generated and `eager` is not needed: shared modules are ordinary static ES imports, so code that reads a shared value at module-evaluation time (`class X extends SharedBase`, decorator metadata) just works.
|
|
408
|
+
|
|
409
|
+
**Remote** (a container with `exposes`):
|
|
410
|
+
|
|
411
|
+
```ts
|
|
412
|
+
federation({
|
|
413
|
+
name: "remote",
|
|
414
|
+
exposes: { "./Button": "./src/Button.tsx" },
|
|
415
|
+
shared: { react: {}, "react-dom": {}, "react/jsx-runtime": {} },
|
|
416
|
+
experiments: { hostProvidesAllShared: true },
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
The remote build emits one fixed-name entry per expose (`./Button` → `Button.js`), keeps every shared key as a bare external import and writes a standard `mf-manifest.json` next to the entries, with no `remoteEntry` since there is no runtime container. `metaData.publicPath` comes from Vite's `base` (or `publicPath`); `auto` is inferred from the manifest URL by the host.
|
|
421
|
+
|
|
422
|
+
**Host** (no `exposes`):
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
federation({
|
|
426
|
+
name: "host",
|
|
427
|
+
remotes: { remote: "https://cdn.example.com/remote/mf-manifest.json" },
|
|
428
|
+
shared: { react: {}, "react-dom": {}, "react/jsx-runtime": {} },
|
|
429
|
+
experiments: { hostProvidesAllShared: true },
|
|
430
|
+
});
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
The host emits one re-export chunk per shared key, which the bundler dedupes with the host's own imports, and injects a `<script type="importmap">` into `index.html` mapping each shared key to that chunk and each remote expose (`remote/Button`) to the entry listed in the manifest. A manifest may also be a path relative to the host root (for example `../remote/dist/mf-manifest.json`). A manifest that has a `remoteEntry` belongs to a Module Federation runtime remote and is rejected. The dev server serves the same map, pointing shared keys at virtual modules that resolve to the host's pre-bundled dependencies, so host and remotes share one instance in dev too.
|
|
434
|
+
|
|
435
|
+
A remote that imports an unshared subpath of a shared package (`rxjs/operators` with only `rxjs` shared) bundles a private copy of that package's internals; the remote build warns and names the key to add to `shared`.
|
|
436
|
+
|
|
437
|
+
`dts` keeps working through the manifest's `metaData.types`: a remote emits its types archive next to `mf-manifest.json` and a host referencing the manifest by URL consumes it from there.
|
|
438
|
+
|
|
439
|
+
Not supported in this mode, since the Module Federation runtime is not loaded: version negotiation and fallbacks, share aliasing (`request` / `shareKey`), `import: false`, runtime plugins, SSR, tree-shaking artifacts, `loadRemote` / runtime-registered remotes, and interop with webpack / rspack containers. Options that only the runtime or `remoteEntry.js` pipeline reads (for example `filename`, `shareStrategy`, `runtimePlugins`, `eager`, `requiredVersion`) are ignored; one warning names them. `singleton` needs no setting: every shared key has exactly one instance. The import map is fixed when the host is built, so a remote must keep its expose entry names stable across deploys. The inline import map changes with every host build; a strict CSP needs a nonce or hash for it.
|
|
440
|
+
|
|
405
441
|
## ⚠️ `codeSplitting` is managed by the plugin
|
|
406
442
|
|
|
407
443
|
Do not set `build.rollupOptions.output.codeSplitting` or
|
|
@@ -1,40 +1,10 @@
|
|
|
1
1
|
import { d as getNodeModulesSuffix, r as getSharedRuntimeKey } from "./sharedKeyMatcher-Od_nYxJA.js";
|
|
2
|
+
import { r as mfWarn, t as createModuleFederationError } from "./logger-DOwfTlw5.js";
|
|
2
3
|
import { existsSync, readFileSync, readdirSync, realpathSync } from "fs";
|
|
3
4
|
import { createRequire } from "module";
|
|
4
5
|
import * as path$1 from "node:path";
|
|
5
6
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
6
7
|
import { createHash } from "node:crypto";
|
|
7
|
-
//#region src/utils/logger.ts
|
|
8
|
-
const MODULE_FEDERATION_LOG_PREFIX = "[Module Federation]";
|
|
9
|
-
function formatModuleFederationMessage(message) {
|
|
10
|
-
return `${MODULE_FEDERATION_LOG_PREFIX} ${message}`;
|
|
11
|
-
}
|
|
12
|
-
function createModuleFederationError(message) {
|
|
13
|
-
return new Error(formatModuleFederationMessage(message));
|
|
14
|
-
}
|
|
15
|
-
function toConsoleArgs(message, rest = []) {
|
|
16
|
-
if (typeof message === "string") return [formatModuleFederationMessage(message), ...rest];
|
|
17
|
-
if (message === void 0) return [MODULE_FEDERATION_LOG_PREFIX, ...rest];
|
|
18
|
-
return [
|
|
19
|
-
MODULE_FEDERATION_LOG_PREFIX,
|
|
20
|
-
message,
|
|
21
|
-
...rest
|
|
22
|
-
];
|
|
23
|
-
}
|
|
24
|
-
const moduleFederationConsole = {
|
|
25
|
-
log(message, ...rest) {
|
|
26
|
-
console.log(...toConsoleArgs(message, rest));
|
|
27
|
-
},
|
|
28
|
-
warn(message, ...rest) {
|
|
29
|
-
console.warn(...toConsoleArgs(message, rest));
|
|
30
|
-
},
|
|
31
|
-
error(message, ...rest) {
|
|
32
|
-
console.error(...toConsoleArgs(message, rest));
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
const mfWarn = moduleFederationConsole.warn;
|
|
36
|
-
const mfError = moduleFederationConsole.error;
|
|
37
|
-
//#endregion
|
|
38
8
|
//#region src/utils/reactShares.ts
|
|
39
9
|
/** Property under which React 19 exposes its internals object. */
|
|
40
10
|
const REACT_CLIENT_INTERNALS_KEY = "__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE";
|
|
@@ -685,4 +655,4 @@ function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || proce
|
|
|
685
655
|
//#region src/utils/dtsConstants.ts
|
|
686
656
|
const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
|
|
687
657
|
//#endregion
|
|
688
|
-
export { isReactCoreShare as C,
|
|
658
|
+
export { isReactCoreShare as C, REACT_DOM_CLIENT_SHARE as S, resolveModulePath as _, getIsRolldown as a, supportsCodeSplittingGroupDebugName as b, getPackageNameFromNodeModulePath as c, isNuxtProjectRoot as d, isPackageExportAvailable as f, resolveImportPath as g, packageNameEncode as h, getInstalledPackageJson as i, getSharedCacheDescriptor as l, packageNameDecode as m, getDependencyNames as n, getPackageDetectionCwd as o, isPackageInstalled as p, getInstalledPackageEntry as r, getPackageName as s, DEFAULT_PUBLIC_TYPES_FOLDER as t, hasPackageDependency as u, setPackageDetectionCwd as v, REACT_CLIENT_INTERNALS_KEY as x, sharedCacheHelperCode as y };
|
package/lib/index.d.ts
CHANGED
|
@@ -167,6 +167,23 @@ interface PluginExperimentsOptions {
|
|
|
167
167
|
provideExternalRuntime?: boolean;
|
|
168
168
|
/** Generate the React SSR/hydration island capability for eligible exposes. */
|
|
169
169
|
ssrMode?: 'ISLAND';
|
|
170
|
+
/**
|
|
171
|
+
* The host provides every shared dependency; remotes bring none. Shared keys
|
|
172
|
+
* are resolved by a native browser import map instead of the Module
|
|
173
|
+
* Federation runtime: the host emits one entry chunk per shared key and
|
|
174
|
+
* injects `<script type="importmap">`, remotes keep shared imports as bare
|
|
175
|
+
* specifiers and emit one fixed-name entry per expose plus a standard
|
|
176
|
+
* `mf-manifest.json` (without `remoteEntry`) the host maps from.
|
|
177
|
+
*
|
|
178
|
+
* Shared modules become ordinary static ES imports, so there is no
|
|
179
|
+
* `loadShare` glue and no `eager` is needed for code that reads a shared
|
|
180
|
+
* value at module-evaluation time. There is no version negotiation and no
|
|
181
|
+
* runtime API: `requiredVersion`, `strictVersion`, `shareStrategy`,
|
|
182
|
+
* `runtimePlugins` and `manifest` are ignored.
|
|
183
|
+
*
|
|
184
|
+
* @see https://github.com/module-federation/vite/issues/1381
|
|
185
|
+
*/
|
|
186
|
+
hostProvidesAllShared?: boolean;
|
|
170
187
|
}
|
|
171
188
|
type SsrEntryLoaderStrategy = 'temp-file' | 'vm';
|
|
172
189
|
type SsrEntryLoaderConfig = {
|