@module-federation/vite 1.20.8 → 1.21.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 +19 -10
- package/lib/index.js +108 -45
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -351,20 +351,29 @@ federation({
|
|
|
351
351
|
`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. Using `provideExternalRuntime` together with `exposes` throws — only pure consumers may provide the runtime.
|
|
352
352
|
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.
|
|
353
353
|
|
|
354
|
-
## ⚠️ `codeSplitting`
|
|
354
|
+
## ⚠️ `codeSplitting` is managed by the plugin
|
|
355
355
|
|
|
356
|
-
Do not set
|
|
357
|
-
`build.rolldownOptions.output.codeSplitting` to `false`
|
|
356
|
+
Do not set `build.rollupOptions.output.codeSplitting` or
|
|
357
|
+
`build.rolldownOptions.output.codeSplitting` to `false` — it will be **ignored** (with a warning).
|
|
358
|
+
Module Federation requires chunk splitting so `loadShare` and `runtimeInitStatus` stay isolated for correct bootstrap order.
|
|
358
359
|
|
|
359
|
-
`codeSplitting.groups`
|
|
360
|
-
Module Federation needs `loadShare` and `runtimeInitStatus` isolated into separate chunks for correct bootstrap behavior.
|
|
360
|
+
### `codeSplitting.groups` (Vite 8+ / Rolldown)
|
|
361
361
|
|
|
362
|
-
|
|
362
|
+
User groups are now **preserved**. The plugin installs its own federation groups at the highest priority and appends your groups below them, so your groups can only claim modules the federation groups didn't.
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
`
|
|
366
|
-
|
|
367
|
-
|
|
364
|
+
- No warning is emitted just for keeping your groups.
|
|
365
|
+
- If one of your existing groups sets a `priority` high enough to outrank the federation groups, it is **clamped** below them and the plugin warns once. This prevents those groups from capturing a `runtimeInit`/`loadShare` wrapper or the preload helper.
|
|
366
|
+
|
|
367
|
+
## ⚠️ `manualChunks` behavior depends on your Vite version
|
|
368
|
+
|
|
369
|
+
| Setting | Vite 5–7 (Rollup) | Vite 8+ (Rolldown) |
|
|
370
|
+
| --- | --- | --- |
|
|
371
|
+
| `manualChunks` (function) | **Composed as a fallback** — federation modules are claimed first, everything else falls through to your function | **Ignored** (warns) — move grouping to `codeSplitting.groups` |
|
|
372
|
+
| `manualChunks` (object) | **Ignored** (warns) — use the function form to compose | **Ignored** (warns) — move grouping to `codeSplitting.groups` |
|
|
373
|
+
|
|
374
|
+
On Vite 5–7, Rollup doesn't support `codeSplitting`, so the plugin isolates `runtimeInitStatus`, `loadShare`, and the preload helper via `manualChunks`. A user-provided **function** is called for any module the plugin doesn't claim; the **object** form isn't composed by the plugin and is ignored.
|
|
375
|
+
|
|
376
|
+
On Vite 8+, chunking is managed through `codeSplitting.groups` (see above), so `manualChunks` is removed — express your grouping as `codeSplitting.groups` instead, where user groups are preserved below the federation groups.
|
|
368
377
|
|
|
369
378
|
### So far so good 🎉
|
|
370
379
|
|
package/lib/index.js
CHANGED
|
@@ -5378,7 +5378,7 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
5378
5378
|
}`;
|
|
5379
5379
|
const realRemoteInit = `__mfRemotePending = __mfStartRemoteLoad().then(__mfAssignRemoteModule);`;
|
|
5380
5380
|
const deferredClientInit = `exportModule = __mfCreateDeferredRemoteProxy();`;
|
|
5381
|
-
const eagerLoadClientRemote = shouldEagerLoadClientRemoteInDev(command, enableSsrInit);
|
|
5381
|
+
const eagerLoadClientRemote = id === remoteRegistration?.alias || shouldEagerLoadClientRemoteInDev(command, enableSsrInit);
|
|
5382
5382
|
const eagerClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
|
|
5383
5383
|
const loadedFirstClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
|
|
5384
5384
|
const environmentSplitInit = (clientInit, serverInit) => consumer === "client" ? clientInit : consumer === "server" ? serverInit : `if (${SERVER_ENV_GUARD}) {
|
|
@@ -5515,20 +5515,25 @@ function resolveDevHashEntryFileName$1(fileName) {
|
|
|
5515
5515
|
function getBuildInput(config) {
|
|
5516
5516
|
return config.build?.rollupOptions?.input ?? config.build?.rolldownOptions?.input;
|
|
5517
5517
|
}
|
|
5518
|
-
function patchHashEntryFileName(output, entryName, fileName) {
|
|
5519
|
-
const
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5518
|
+
function patchHashEntryFileName(output, entryName, fileName, defaultFileNames) {
|
|
5519
|
+
for (const option of ["entryFileNames", "chunkFileNames"]) {
|
|
5520
|
+
const originalFileNames = output[option];
|
|
5521
|
+
output[option] = (chunkInfo, ...args) => {
|
|
5522
|
+
if (chunkInfo?.name === entryName) return fileName;
|
|
5523
|
+
if (typeof originalFileNames === "function") return originalFileNames(chunkInfo, ...args);
|
|
5524
|
+
return originalFileNames || defaultFileNames;
|
|
5525
|
+
};
|
|
5526
|
+
}
|
|
5525
5527
|
}
|
|
5526
5528
|
function patchHashEntryFileNames(config, entryName, fileName) {
|
|
5527
5529
|
if (!fileName?.includes?.("[hash")) return;
|
|
5530
|
+
fileName = fileName.replace(/(\[hash(?::\d+)?\])$/, "$1.js");
|
|
5528
5531
|
config.build ??= {};
|
|
5529
5532
|
config.build.rollupOptions ??= {};
|
|
5530
5533
|
config.build.rolldownOptions ??= {};
|
|
5531
|
-
const
|
|
5534
|
+
const assetsDir = config.build.assetsDir ?? "assets";
|
|
5535
|
+
const defaultFileNames = `${assetsDir ? `${assetsDir}/` : ""}[name]-[hash].js`;
|
|
5536
|
+
const patchOutput = (output) => patchHashEntryFileName(output, entryName, fileName, defaultFileNames);
|
|
5532
5537
|
const patchBundlerOutput = (bundlerOptions) => {
|
|
5533
5538
|
const output = bundlerOptions.output;
|
|
5534
5539
|
if (Array.isArray(output)) {
|
|
@@ -5539,6 +5544,7 @@ function patchHashEntryFileNames(config, entryName, fileName) {
|
|
|
5539
5544
|
};
|
|
5540
5545
|
patchBundlerOutput(config.build.rollupOptions);
|
|
5541
5546
|
patchBundlerOutput(config.build.rolldownOptions);
|
|
5547
|
+
Object.values(config.environments ?? {}).forEach((environment) => patchHashEntryFileNames(environment, entryName, fileName));
|
|
5542
5548
|
}
|
|
5543
5549
|
const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClientInjected, skipTransformFor = [], federationOptions }) => {
|
|
5544
5550
|
const DEV_HTML_PROXY_PREFIX = "virtual:mf-html-entry-proxy?";
|
|
@@ -6099,6 +6105,7 @@ const REACT_REFRESH_PROXY_MODULE = [
|
|
|
6099
6105
|
`const __rt = await import(__target);`,
|
|
6100
6106
|
`export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;`,
|
|
6101
6107
|
`export const register = __rt.register;`,
|
|
6108
|
+
`export const getRefreshReg = __rt.getRefreshReg;`,
|
|
6102
6109
|
`export const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;`,
|
|
6103
6110
|
`export const registerExportsForReactRefresh = __rt.registerExportsForReactRefresh;`,
|
|
6104
6111
|
`export const validateRefreshBoundaryAndEnqueueUpdate = __rt.validateRefreshBoundaryAndEnqueueUpdate;`,
|
|
@@ -7742,12 +7749,18 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
7742
7749
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
7743
7750
|
}
|
|
7744
7751
|
function collectImportSources(code) {
|
|
7745
|
-
const sources = /* @__PURE__ */ new
|
|
7752
|
+
const sources = /* @__PURE__ */ new Map();
|
|
7746
7753
|
for (const match of code.matchAll(/(?:^|[;\n\r])\s*import\s+(?:[\s\S]*?\s+from\s+)?["']([^"']+)["']|import\(\s*["']([^"']+)["']\s*\)/g)) {
|
|
7747
7754
|
const source = match[1] || match[2];
|
|
7748
|
-
if (source)
|
|
7755
|
+
if (source) {
|
|
7756
|
+
const dynamic = !match[1];
|
|
7757
|
+
sources.set(source, (sources.get(source) ?? true) && dynamic);
|
|
7758
|
+
}
|
|
7749
7759
|
}
|
|
7750
|
-
return Array.from(sources)
|
|
7760
|
+
return Array.from(sources, ([source, dynamic]) => ({
|
|
7761
|
+
source,
|
|
7762
|
+
dynamic
|
|
7763
|
+
})).sort((a, b) => a.source.localeCompare(b.source));
|
|
7751
7764
|
}
|
|
7752
7765
|
function shouldScanResolvedImport(id) {
|
|
7753
7766
|
if (!id || id.includes("\0")) return false;
|
|
@@ -7764,9 +7777,9 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
7764
7777
|
return [];
|
|
7765
7778
|
}
|
|
7766
7779
|
const dependencies = /* @__PURE__ */ new Set();
|
|
7767
|
-
for (const source of collectImportSources(code)) {
|
|
7780
|
+
for (const { source, dynamic } of collectImportSources(code)) {
|
|
7768
7781
|
if (isRemoteImport(source)) {
|
|
7769
|
-
dependencies.add(source);
|
|
7782
|
+
if (!dynamic) dependencies.add(source);
|
|
7770
7783
|
continue;
|
|
7771
7784
|
}
|
|
7772
7785
|
const resolved = await ctx.resolve(source, id);
|
|
@@ -8430,8 +8443,10 @@ function applyRewrites(code, imports, id) {
|
|
|
8430
8443
|
importParts.push(`__mf_remote_pending as ${pendingId}`);
|
|
8431
8444
|
let rewrite = `import { ${importParts.join(", ")} } from ${src};`;
|
|
8432
8445
|
if (imp.named.length > 0) {
|
|
8433
|
-
const
|
|
8434
|
-
|
|
8446
|
+
const declarations = imp.named.map((s) => `let ${s.local};`).join("\n");
|
|
8447
|
+
const initializers = imp.named.map((s) => `if (${JSON.stringify(s.imported)} in ${nsId}) {\n${s.local} = ${nsId}[${JSON.stringify(s.imported)}];\n}`).join("\n");
|
|
8448
|
+
const assignments = imp.named.map((s) => `${s.local} = ${nsId}[${JSON.stringify(s.imported)}];`).join("\n");
|
|
8449
|
+
rewrite += `\n${declarations}\n${initializers}\n${pendingId}.then(() => {\n${assignments}\n});`;
|
|
8435
8450
|
}
|
|
8436
8451
|
ms.overwrite(imp.start, imp.end, rewrite);
|
|
8437
8452
|
}
|
|
@@ -8451,10 +8466,11 @@ function applyRewrites(code, imports, id) {
|
|
|
8451
8466
|
};
|
|
8452
8467
|
});
|
|
8453
8468
|
const importLine = `import { __moduleExports as ${nsId}, __mf_remote_pending as ${pendingId} } from ${src};`;
|
|
8454
|
-
const varLines = vars.map((v) => `let ${v.tmp}
|
|
8469
|
+
const varLines = vars.map((v) => `let ${v.tmp};`).join("\n");
|
|
8470
|
+
const initializers = vars.map((v) => `if (${JSON.stringify(v.local)} in ${nsId}) {\n${v.tmp} = ${nsId}[${JSON.stringify(v.local)}];\n}`).join("\n");
|
|
8455
8471
|
const syncLine = `${pendingId}.then(() => {\n${vars.map((v) => `${v.tmp} = ${nsId}[${JSON.stringify(v.local)}];`).join("\n")}\n});`;
|
|
8456
8472
|
const exportLine = `export { ${vars.map((v) => `${v.tmp} as ${v.exported}`).join(", ")} };`;
|
|
8457
|
-
ms.overwrite(imp.start, imp.end, `${importLine}\n${varLines}\n${syncLine}\n${exportLine}`);
|
|
8473
|
+
ms.overwrite(imp.start, imp.end, `${importLine}\n${varLines}\n${initializers}\n${syncLine}\n${exportLine}`);
|
|
8458
8474
|
changed = true;
|
|
8459
8475
|
break;
|
|
8460
8476
|
}
|
|
@@ -9264,8 +9280,11 @@ function getRuntimeCapabilityConfigurationWarnings(options) {
|
|
|
9264
9280
|
//#endregion
|
|
9265
9281
|
//#region src/index.ts
|
|
9266
9282
|
const patchedManualChunks = /* @__PURE__ */ new WeakSet();
|
|
9283
|
+
const federationGroups = /* @__PURE__ */ new WeakSet();
|
|
9267
9284
|
const PRELOAD_HELPER_CHUNK = "vite-preload-helper";
|
|
9268
9285
|
const PRELOAD_HELPER_TEST = /\0?vite\/preload-helper/;
|
|
9286
|
+
const MF_GROUP_PRIORITY = 1e6;
|
|
9287
|
+
const USER_GROUP_MAX_PRIORITY = MF_GROUP_PRIORITY - 1;
|
|
9269
9288
|
function normalizeVinextRscPreloadHints(code) {
|
|
9270
9289
|
return code.replace(/(:HL\[[^\]\n]*?,)"stylesheet"/g, "$1\"style\"").replace(/(:HL\[[^\]\n]*?,)\\"stylesheet\\"/g, "$1\\\"style\\\"");
|
|
9271
9290
|
}
|
|
@@ -9422,6 +9441,14 @@ function includeLinkedSharedEntries(optimizeDeps, shared, projectRoot, exposes,
|
|
|
9422
9441
|
]);
|
|
9423
9442
|
for (const [packageName, share] of Object.entries(shared ?? {})) {
|
|
9424
9443
|
if (share?.shareConfig?.import === false) continue;
|
|
9444
|
+
const configuredImport = share?.shareConfig?.import;
|
|
9445
|
+
if (typeof configuredImport === "string") {
|
|
9446
|
+
const entry = path$1.isAbsolute(configuredImport) ? configuredImport : path$1.resolve(projectRoot, configuredImport);
|
|
9447
|
+
if (existsSync(entry) && !entry.replaceAll("\\", "/").includes("/node_modules/")) {
|
|
9448
|
+
additions.add(entry);
|
|
9449
|
+
continue;
|
|
9450
|
+
}
|
|
9451
|
+
}
|
|
9425
9452
|
const installed = getInstalledPackageJson(packageName, { cwd: projectRoot });
|
|
9426
9453
|
if (!installed || installed.dir.replaceAll("\\", "/").includes("/node_modules/")) continue;
|
|
9427
9454
|
const entry = getInstalledPackageEntry(packageName, { cwd: projectRoot });
|
|
@@ -9604,9 +9631,20 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
9604
9631
|
if (args.kind === "entry-point") return;
|
|
9605
9632
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
9606
9633
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
9607
|
-
|
|
9634
|
+
const key = findSharedKey(args.path, shared);
|
|
9635
|
+
if (!key || isAssetLikeImport(args.path)) return;
|
|
9608
9636
|
if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path) && !isReactDomSelfReference(args.path, args.importer)) return;
|
|
9609
9637
|
addUsedShares(args.path, options);
|
|
9638
|
+
if (args.kind === "import-statement" || args.kind === "dynamic-import") {
|
|
9639
|
+
const shareItem = shared[key];
|
|
9640
|
+
const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
|
|
9641
|
+
writeLoadShareModule(args.path, shareItem, _command, isRolldown, options);
|
|
9642
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
|
|
9643
|
+
return {
|
|
9644
|
+
path: loadSharePath,
|
|
9645
|
+
external: true
|
|
9646
|
+
};
|
|
9647
|
+
}
|
|
9610
9648
|
return {
|
|
9611
9649
|
path: args.path,
|
|
9612
9650
|
namespace: "mf-shared"
|
|
@@ -9663,7 +9701,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
9663
9701
|
optimizeDeps.exclude ??= [];
|
|
9664
9702
|
const shouldBypassOptimizeDep = isLitShare(key) || !canResolveSharedSubpath(key, root);
|
|
9665
9703
|
if (optimizeDeps.include.includes(key)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== key);
|
|
9666
|
-
else if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
|
|
9704
|
+
else if (shouldBypassOptimizeDep || optimizeDeps.exclude.includes(key)) optimizeDeps.exclude.push(key);
|
|
9667
9705
|
else optimizeDeps.include.push(key);
|
|
9668
9706
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
9669
9707
|
const canResolveSubpath = canResolveSharedSubpath(subpath, root);
|
|
@@ -9990,33 +10028,33 @@ function federation(mfUserOptions) {
|
|
|
9990
10028
|
};
|
|
9991
10029
|
}
|
|
9992
10030
|
let warnedAboutCodeSplitting = false;
|
|
9993
|
-
let warnedAboutCodeSplittingGroups = false;
|
|
9994
10031
|
const ensureCodeSplitting = (output) => {
|
|
9995
|
-
if (output?.codeSplitting
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10032
|
+
if (output?.codeSplitting !== false) return;
|
|
10033
|
+
delete output.codeSplitting;
|
|
10034
|
+
if (warnedAboutCodeSplitting) return;
|
|
10035
|
+
warnedAboutCodeSplitting = true;
|
|
10036
|
+
mfWarn("Ignoring `output.codeSplitting = false` because module federation requires chunk splitting.");
|
|
10037
|
+
};
|
|
10038
|
+
const isFederationGroup = (group) => typeof group === "object" && group !== null && federationGroups.has(group);
|
|
10039
|
+
let warnedAboutGroupPriority = false;
|
|
10040
|
+
const clampUserGroup = (group) => {
|
|
10041
|
+
const candidate = group;
|
|
10042
|
+
if (typeof candidate?.priority !== "number") return group;
|
|
10043
|
+
if (candidate.priority <= USER_GROUP_MAX_PRIORITY) return group;
|
|
10044
|
+
if (!warnedAboutGroupPriority) {
|
|
10045
|
+
warnedAboutGroupPriority = true;
|
|
10046
|
+
mfWarn(`Clamping \`output.codeSplitting.groups\` priority to ${USER_GROUP_MAX_PRIORITY} — module federation groups must keep the highest priority so shared dependency init wrappers stay isolated in their own chunks.`);
|
|
10001
10047
|
}
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
delete output.codeSplitting.groups;
|
|
10007
|
-
if (Object.keys(output.codeSplitting).length === 0) delete output.codeSplitting;
|
|
10008
|
-
if (warnedAboutCodeSplittingGroups) return;
|
|
10009
|
-
warnedAboutCodeSplittingGroups = true;
|
|
10010
|
-
mfWarn("Ignoring `output.codeSplitting.groups` because it conflicts with module federation. Grouping shared dependency init wrappers with their dependent modules can break runtime init order and cause standalone remotes to fail before mount.");
|
|
10048
|
+
return {
|
|
10049
|
+
...candidate,
|
|
10050
|
+
priority: USER_GROUP_MAX_PRIORITY
|
|
10051
|
+
};
|
|
10011
10052
|
};
|
|
10012
10053
|
let warnedAboutManualChunks = false;
|
|
10054
|
+
let warnedAboutObjectManualChunks = false;
|
|
10013
10055
|
const applyManualChunks = (output, useCodeSplitting) => {
|
|
10014
10056
|
ensureCodeSplitting(output);
|
|
10015
10057
|
const isPatchedByPlugin = typeof output.manualChunks === "function" && patchedManualChunks.has(output.manualChunks);
|
|
10016
|
-
if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
|
|
10017
|
-
warnedAboutManualChunks = true;
|
|
10018
|
-
mfWarn("Ignoring `output.manualChunks` because it conflicts with module federation. Module federation transforms shared dependency imports with async init wrappers, and grouping these transformed modules into a single chunk creates circular async dependencies that cause the application to silently hang.");
|
|
10019
|
-
}
|
|
10020
10058
|
const mfChunkName = function(id) {
|
|
10021
10059
|
if (id.includes(runtimeInitId) || id.includes("__mf_v__runtimeInit__mf_v__")) return "runtimeInit";
|
|
10022
10060
|
if (id.includes("__loadShare__")) {
|
|
@@ -10027,19 +10065,44 @@ function federation(mfUserOptions) {
|
|
|
10027
10065
|
};
|
|
10028
10066
|
patchedManualChunks.add(mfChunkName);
|
|
10029
10067
|
if (!useCodeSplitting) {
|
|
10030
|
-
|
|
10068
|
+
if (isPatchedByPlugin) return;
|
|
10069
|
+
const userManualChunks = output.manualChunks;
|
|
10070
|
+
if (userManualChunks && typeof userManualChunks !== "function" && !warnedAboutObjectManualChunks) {
|
|
10071
|
+
warnedAboutObjectManualChunks = true;
|
|
10072
|
+
mfWarn("Ignoring the object form of `output.manualChunks` because module federation cannot safely compose with it. Use the function form instead: federation modules are claimed first and your function runs for everything else.");
|
|
10073
|
+
}
|
|
10074
|
+
const mfManualChunks = function(id, ...rest) {
|
|
10031
10075
|
if (PRELOAD_HELPER_TEST.test(id)) return PRELOAD_HELPER_CHUNK;
|
|
10032
|
-
|
|
10076
|
+
const mfChunk = mfChunkName(id);
|
|
10077
|
+
if (mfChunk) return mfChunk;
|
|
10078
|
+
if (typeof userManualChunks === "function") return userManualChunks(id, ...rest) ?? void 0;
|
|
10033
10079
|
};
|
|
10034
10080
|
patchedManualChunks.add(mfManualChunks);
|
|
10035
10081
|
output.manualChunks = mfManualChunks;
|
|
10036
10082
|
return;
|
|
10037
10083
|
}
|
|
10038
|
-
|
|
10084
|
+
if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
|
|
10085
|
+
warnedAboutManualChunks = true;
|
|
10086
|
+
mfWarn("Ignoring `output.manualChunks` for the Rolldown build because module federation manages chunking with `output.codeSplitting.groups`. Move your grouping there — user groups are kept below the federation groups.");
|
|
10087
|
+
}
|
|
10088
|
+
const existingGroups = output.codeSplitting && typeof output.codeSplitting === "object" ? output.codeSplitting.groups : void 0;
|
|
10089
|
+
const userGroups = Array.isArray(existingGroups) ? existingGroups.filter((group) => !isFederationGroup(group)).map(clampUserGroup) : [];
|
|
10090
|
+
const mfPreloadGroup = {
|
|
10039
10091
|
name: PRELOAD_HELPER_CHUNK,
|
|
10040
10092
|
test: PRELOAD_HELPER_TEST,
|
|
10041
|
-
priority:
|
|
10042
|
-
}
|
|
10093
|
+
priority: 1000001
|
|
10094
|
+
};
|
|
10095
|
+
const mfNameGroup = {
|
|
10096
|
+
name: mfChunkName,
|
|
10097
|
+
priority: MF_GROUP_PRIORITY
|
|
10098
|
+
};
|
|
10099
|
+
federationGroups.add(mfPreloadGroup);
|
|
10100
|
+
federationGroups.add(mfNameGroup);
|
|
10101
|
+
const groups = [
|
|
10102
|
+
mfPreloadGroup,
|
|
10103
|
+
mfNameGroup,
|
|
10104
|
+
...userGroups
|
|
10105
|
+
];
|
|
10043
10106
|
output.codeSplitting = {
|
|
10044
10107
|
...output.codeSplitting || {},
|
|
10045
10108
|
groups
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@module-federation/dts-plugin": "2.
|
|
81
|
-
"@module-federation/runtime": "2.
|
|
82
|
-
"@module-federation/sdk": "2.
|
|
80
|
+
"@module-federation/dts-plugin": "2.9.0",
|
|
81
|
+
"@module-federation/runtime": "2.9.0",
|
|
82
|
+
"@module-federation/sdk": "2.9.0"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@playwright/test": "1.62.0",
|
|
@@ -93,4 +93,4 @@
|
|
|
93
93
|
"vite": "8.2.0",
|
|
94
94
|
"vitest": "4.1.10"
|
|
95
95
|
}
|
|
96
|
-
}
|
|
96
|
+
}
|