@module-federation/vite 1.20.5 → 1.20.6

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/lib/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { n as normalizePathForImport, r as rebaseImport } from "./buildPaths-BkaQHrd2.js";
2
- import { a as getCommonSharedSubpaths, c as isNodeModulePath, d as normalizeNodeModulePath, f as resolvePublicPath, i as getCommonSharedSubpathFromNodeModulePath, l as isNuxtClientBase, n as filterId, o as getMatchingNodeModuleSubpath, r as getBasePath$2, s as isAssetLikeImport, t as ensureTrailingSlash, u as isViteOptimizableEntry } from "./pathNormalization-DvgU8LIp.js";
2
+ import { a as getPackageDetectionCwd, c as getSharedCacheDescriptor, d as packageNameDecode, f as packageNameEncode, g as createModuleFederationError, h as sharedCacheHelperCode, i as getIsRolldown, l as hasPackageDependency, m as setPackageDetectionCwd, n as getInstalledPackageEntry, o as getPackageName, p as resolveImportPath, r as getInstalledPackageJson, s as getPackageNameFromNodeModulePath, u as isNuxtProjectRoot, v as mfWarn } from "./dtsConstants-DyJrx8ah.js";
3
+ import { a as getCommonSharedSubpaths, c as isNodeModulePath, d as normalizeNodeModulePath, f as resolvePublicPath, i as getCommonSharedSubpathFromNodeModulePath, l as isNuxtClientBase, n as filterId, o as getMatchingNodeModuleSubpath, r as getBasePath$1, s as isAssetLikeImport, t as ensureTrailingSlash, u as isViteOptimizableEntry } from "./pathNormalization-DvgU8LIp.js";
3
4
  import { createRequire } from "node:module";
4
5
  import * as fs$2 from "fs";
5
- import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
6
+ import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
6
7
  import { createRequire as createRequire$1 } from "module";
7
8
  import * as path$1 from "node:path";
8
9
  import path, { basename } from "node:path";
@@ -12,21 +13,6 @@ import { createHash } from "node:crypto";
12
13
  import * as fs$1 from "node:fs";
13
14
  import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
14
15
  import { pathToFileURL as pathToFileURL$1 } from "node:url";
15
- import { normalizeOptions } from "@module-federation/sdk";
16
- import { consumeTypesAPI, generateTypesAPI, isTSProject, normalizeConsumeTypesOptions, normalizeDtsOptions, normalizeGenerateTypesOptions } from "@module-federation/dts-plugin";
17
- import { rpc } from "@module-federation/dts-plugin/core";
18
- //#region \0rolldown/runtime.js
19
- var __defProp = Object.defineProperty;
20
- var __exportAll = (all, no_symbols) => {
21
- let target = {};
22
- for (var name in all) __defProp(target, name, {
23
- get: all[name],
24
- enumerable: true
25
- });
26
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
27
- return target;
28
- };
29
- //#endregion
30
16
  //#region src/utils/codeRewriter.ts
31
17
  const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
32
18
  var CodeRewriter = class {
@@ -338,475 +324,6 @@ function injectEntryScript(html, initSrc) {
338
324
  return html.replace("<head>", `<head><script type="module" src=${JSON.stringify(src)}><\/script>`);
339
325
  }
340
326
  //#endregion
341
- //#region src/utils/logger.ts
342
- const MODULE_FEDERATION_LOG_PREFIX = "[Module Federation]";
343
- function formatModuleFederationMessage(message) {
344
- return `${MODULE_FEDERATION_LOG_PREFIX} ${message}`;
345
- }
346
- function createModuleFederationError(message) {
347
- return new Error(formatModuleFederationMessage(message));
348
- }
349
- function toConsoleArgs(message, rest = []) {
350
- if (typeof message === "string") return [formatModuleFederationMessage(message), ...rest];
351
- if (message === void 0) return [MODULE_FEDERATION_LOG_PREFIX, ...rest];
352
- return [
353
- MODULE_FEDERATION_LOG_PREFIX,
354
- message,
355
- ...rest
356
- ];
357
- }
358
- const moduleFederationConsole = {
359
- log(message, ...rest) {
360
- console.log(...toConsoleArgs(message, rest));
361
- },
362
- warn(message, ...rest) {
363
- console.warn(...toConsoleArgs(message, rest));
364
- },
365
- error(message, ...rest) {
366
- console.error(...toConsoleArgs(message, rest));
367
- }
368
- };
369
- moduleFederationConsole.log;
370
- const mfWarn = moduleFederationConsole.warn;
371
- const mfError = moduleFederationConsole.error;
372
- //#endregion
373
- //#region src/utils/packageUtils.ts
374
- const dependencyPresenceCache = /* @__PURE__ */ new Map();
375
- let packageDetectionCwd;
376
- function getDependencyCacheKey(cwd, dependencyName) {
377
- return `${cwd}:${dependencyName}`;
378
- }
379
- const installedPackageJsonCache = /* @__PURE__ */ new Map();
380
- function setPackageDetectionCwd(cwd) {
381
- packageDetectionCwd = cwd;
382
- }
383
- function getPackageDetectionCwd() {
384
- return packageDetectionCwd || process.cwd();
385
- }
386
- function resolveImportPath(specifier) {
387
- const resolved = import.meta.resolve(specifier);
388
- if (!resolved.startsWith("file:")) return resolved;
389
- const filePath = fileURLToPath(resolved);
390
- if (!existsSync(filePath)) {
391
- const error = /* @__PURE__ */ new Error(`Cannot find module '${specifier}'`);
392
- error.code = "MODULE_NOT_FOUND";
393
- throw error;
394
- }
395
- return filePath;
396
- }
397
- const DEFAULT_EXPORT_CONDITIONS = [
398
- "browser",
399
- "import",
400
- "module",
401
- "default"
402
- ];
403
- function resolveExportsEntry(exportsField, conditions = DEFAULT_EXPORT_CONDITIONS) {
404
- return resolveExportsEntryWithConditions(exportsField, new Set(conditions));
405
- }
406
- function resolveExportsEntryWithConditions(exportsField, conditions) {
407
- if (typeof exportsField === "string") return exportsField;
408
- if (!exportsField || typeof exportsField !== "object") return void 0;
409
- if (Array.isArray(exportsField)) {
410
- for (const target of exportsField) {
411
- const resolved = resolveExportsEntryWithConditions(target, conditions);
412
- if (resolved) return resolved;
413
- }
414
- return;
415
- }
416
- const record = exportsField;
417
- const rootExport = record["."];
418
- if (rootExport) return resolveExportsEntryWithConditions(rootExport, conditions);
419
- for (const [condition, value] of Object.entries(record)) {
420
- if (condition !== "default" && !conditions.has(condition)) continue;
421
- const target = resolveExportsEntryWithConditions(value, conditions);
422
- if (target) return target;
423
- }
424
- }
425
- function substituteExportsWildcard(target, patternMatch) {
426
- if (typeof target === "string") return target.split("*").join(patternMatch);
427
- if (Array.isArray(target)) return target.map((entry) => substituteExportsWildcard(entry, patternMatch));
428
- if (target && typeof target === "object") {
429
- const source = target;
430
- const out = {};
431
- for (const key of Object.keys(source)) out[key] = substituteExportsWildcard(source[key], patternMatch);
432
- return out;
433
- }
434
- return target;
435
- }
436
- function matchExportsSubpath(record, subpath) {
437
- if (subpath in record) return record[subpath];
438
- let bestKey;
439
- let bestBaseLength = -1;
440
- let bestKeyLength = -1;
441
- for (const key of Object.keys(record)) {
442
- const wildcardIndex = key.indexOf("*");
443
- if (wildcardIndex === -1) continue;
444
- const patternBase = key.slice(0, wildcardIndex);
445
- const patternTrailer = key.slice(wildcardIndex + 1);
446
- if (patternTrailer.includes("*")) continue;
447
- if (!subpath.startsWith(patternBase) || !subpath.endsWith(patternTrailer)) continue;
448
- if (subpath.length <= patternBase.length + patternTrailer.length) continue;
449
- if (patternBase.length > bestBaseLength || patternBase.length === bestBaseLength && key.length > bestKeyLength) {
450
- bestKey = key;
451
- bestBaseLength = patternBase.length;
452
- bestKeyLength = key.length;
453
- }
454
- }
455
- if (bestKey === void 0) return void 0;
456
- const patternTrailer = bestKey.slice(bestKey.indexOf("*") + 1);
457
- const patternMatch = subpath.slice(bestBaseLength, subpath.length - patternTrailer.length);
458
- return substituteExportsWildcard(record[bestKey], patternMatch);
459
- }
460
- function getPackageExportsTarget(pkg, packageName, exportsField) {
461
- if (typeof exportsField === "string") return pkg === packageName ? exportsField : void 0;
462
- if (!exportsField || typeof exportsField !== "object") return void 0;
463
- const record = exportsField;
464
- const subpath = pkg === packageName ? "." : `.${pkg.slice(packageName.length)}`;
465
- if (subpath !== ".") return matchExportsSubpath(record, subpath);
466
- return record["."] ?? (!Object.keys(record).some((key) => key.startsWith(".")) ? record : void 0);
467
- }
468
- /**
469
- * Escaping rules:
470
- * Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
471
- * @ => 1
472
- * / => 2
473
- * - => 3
474
- * . => 4
475
- */
476
- /**
477
- * Encodes a package name into a valid file name.
478
- * @param {string} name - The package name, e.g., "@scope/xx-xx.xx".
479
- * @returns {string} - The encoded file name.
480
- */
481
- function packageNameEncode(name) {
482
- if (typeof name !== "string") throw createModuleFederationError("A string package name is required");
483
- return name.replace(/@/g, "_mf_0_").replace(/\//g, "_mf_1_").replace(/-/g, "_mf_2_").replace(/\./g, "_mf_3_");
484
- }
485
- /**
486
- * Decodes an encoded file name back to the original package name.
487
- * @param {string} encoded - The encoded file name, e.g., "_mf_0_scope_mf_1_xx_mf_2_xx_mf_3_xx".
488
- * @returns {string} - The decoded package name.
489
- */
490
- function packageNameDecode(encoded) {
491
- if (typeof encoded !== "string") throw createModuleFederationError("A string encoded file name is required");
492
- return encoded.replace(/_mf_0_/g, "@").replace(/_mf_1_/g, "/").replace(/_mf_2_/g, "-").replace(/_mf_3_/g, ".");
493
- }
494
- /**
495
- * Removes any subpath from an npm package specifier and returns the package name only.
496
- * @param {string} packageString - The package specifier, e.g., "@scope/pkg/runtime" or "react/jsx-runtime".
497
- * @returns {string} - The base npm package name.
498
- */
499
- function getPackageName(packageString) {
500
- const match = packageString.match(/^(?:@[^/]+\/)?[^/]+/);
501
- return match ? match[0] : packageString;
502
- }
503
- function getPackageNameFromNodeModulePath(source) {
504
- const normalized = source.replace(/\\/g, "/");
505
- const nodeModulesIndex = normalized.lastIndexOf("/node_modules/");
506
- if (nodeModulesIndex < 0) return;
507
- const parts = normalized.slice(nodeModulesIndex + 14).split("/");
508
- if (!parts[0]) return;
509
- if (parts[0].startsWith("@")) return parts[1] ? `${parts[0]}/${parts[1]}` : void 0;
510
- return parts[0];
511
- }
512
- function getSharedCacheKeyParts(input) {
513
- const scope = (Array.isArray(input.scope) ? input.scope[0] : input.scope) || "default";
514
- const id = input.singleton || !input.version ? input.pkg : `${input.pkg}@${input.version}`;
515
- return {
516
- scope,
517
- id,
518
- key: `${scope}:${id}`
519
- };
520
- }
521
- function getSharedCacheDescriptor(pkg, shareItem) {
522
- const parts = getSharedCacheKeyParts({
523
- pkg,
524
- singleton: shareItem.shareConfig.singleton,
525
- version: shareItem.version,
526
- scope: shareItem.scope
527
- });
528
- return {
529
- canonical: parts.key,
530
- ...parts.scope === "default" ? { aliases: [parts.id] } : {}
531
- };
532
- }
533
- const sharedCacheHelperCode = `const __mfGetSharedCacheDescriptor = (pkg, singleton, version, scope) => {
534
- const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
535
- const scopeName = normalizedScope || "default";
536
- const id = singleton || !version ? pkg : pkg + "@" + version;
537
- const descriptor = { canonical: scopeName + ":" + id };
538
- if (scopeName === "default") descriptor.aliases = [id];
539
- return descriptor;
540
- };
541
- const __mfReadSharedCache = (cache, descriptor) => {
542
- const value = cache[descriptor.canonical];
543
- if (value !== undefined) return value;
544
- const aliases = descriptor.aliases || [];
545
- for (const alias of aliases) {
546
- if (!Object.prototype.hasOwnProperty.call(cache, alias)) continue;
547
- const aliasValue = cache[alias];
548
- if (aliasValue !== undefined) {
549
- cache[descriptor.canonical] = aliasValue;
550
- return aliasValue;
551
- }
552
- }
553
- return undefined;
554
- };
555
- const __mfSharedCacheListenersKey = Symbol.for("module-federation.shared-cache-listeners");
556
- const __mfGetSharedCacheListeners = (cache) => {
557
- let listeners = cache[__mfSharedCacheListenersKey];
558
- if (listeners === undefined) {
559
- listeners = Object.create(null);
560
- Object.defineProperty(cache, __mfSharedCacheListenersKey, {
561
- value: listeners,
562
- enumerable: false,
563
- configurable: false,
564
- writable: false
565
- });
566
- }
567
- return listeners;
568
- };
569
- const __mfSubscribeSharedCache = (cache, descriptor, listener) => {
570
- const listeners = __mfGetSharedCacheListeners(cache);
571
- (listeners[descriptor.canonical] ||= new Set()).add(listener);
572
- };
573
- const __mfSharedCacheOwnersKey = Symbol.for("module-federation.shared-cache-owners");
574
- const __mfGetSharedCacheOwners = (cache) => {
575
- let owners = cache[__mfSharedCacheOwnersKey];
576
- if (owners === undefined) {
577
- owners = Object.create(null);
578
- Object.defineProperty(cache, __mfSharedCacheOwnersKey, {
579
- value: owners,
580
- enumerable: false,
581
- configurable: false,
582
- writable: false
583
- });
584
- }
585
- return owners;
586
- };
587
- const __mfReadSharedCacheOwner = (cache, descriptor) =>
588
- cache[__mfSharedCacheOwnersKey]?.[descriptor.canonical];
589
- const __mfWriteSharedCache = (cache, descriptor, value, owner) => {
590
- cache[descriptor.canonical] = value;
591
- const aliases = descriptor.aliases || [];
592
- for (const alias of aliases) {
593
- Object.defineProperty(cache, alias, {
594
- value,
595
- enumerable: true,
596
- configurable: true,
597
- writable: true
598
- });
599
- }
600
- const owners = cache[__mfSharedCacheOwnersKey];
601
- if (owner === undefined) {
602
- if (owners) delete owners[descriptor.canonical];
603
- } else {
604
- __mfGetSharedCacheOwners(cache)[descriptor.canonical] = owner;
605
- }
606
- const listeners = cache[__mfSharedCacheListenersKey]?.[descriptor.canonical];
607
- if (listeners) {
608
- for (const listener of listeners) listener(value);
609
- }
610
- return value;
611
- };
612
- const __mfTreeShakingSharedCacheKey = Symbol.for("module-federation.tree-shaking-shared-cache");
613
- const __mfGetTreeShakingSharedCache = (cache) => {
614
- let metadata = cache[__mfTreeShakingSharedCacheKey];
615
- if (metadata === undefined) {
616
- metadata = Object.create(null);
617
- Object.defineProperty(cache, __mfTreeShakingSharedCacheKey, {
618
- value: metadata,
619
- enumerable: false,
620
- configurable: false,
621
- writable: false
622
- });
623
- }
624
- return metadata;
625
- };
626
- const __mfReadTreeShakingSharedCache = (cache, descriptor, requiredExports) => {
627
- const fullModule = __mfReadSharedCache(cache, descriptor);
628
- if (fullModule !== undefined) return fullModule;
629
- if (!Array.isArray(requiredExports)) return undefined;
630
- const metadata = cache[__mfTreeShakingSharedCacheKey];
631
- const entries = metadata?.[descriptor.canonical] || [];
632
- let compatibleEntry;
633
- for (const entry of entries) {
634
- if (!requiredExports.every((name) => entry.providedExports.includes(name))) continue;
635
- if (!compatibleEntry || entry.providedExports.length < compatibleEntry.providedExports.length) {
636
- compatibleEntry = entry;
637
- }
638
- }
639
- return compatibleEntry?.value;
640
- };
641
- const __mfWriteTreeShakingSharedCache = (cache, descriptor, providedExports, value) => {
642
- if (!Array.isArray(providedExports)) return value;
643
- const normalizedExports = [...new Set(providedExports)].sort();
644
- const metadata = __mfGetTreeShakingSharedCache(cache);
645
- const entries = (metadata[descriptor.canonical] ||= []);
646
- const existing = entries.find((entry) =>
647
- entry.providedExports.length === normalizedExports.length &&
648
- entry.providedExports.every((name, index) => name === normalizedExports[index])
649
- );
650
- if (existing) existing.value = value;
651
- else entries.push({ providedExports: normalizedExports, value });
652
- return value;
653
- };
654
- const __mfTreeShakingSelectionCacheKey = Symbol.for("module-federation.tree-shaking-shared-selection-cache");
655
- const __mfGetTreeShakingSelectionCache = (cache) => {
656
- let selections = cache[__mfTreeShakingSelectionCacheKey];
657
- if (selections === undefined) {
658
- selections = Object.create(null);
659
- Object.defineProperty(cache, __mfTreeShakingSelectionCacheKey, {
660
- value: selections,
661
- enumerable: false,
662
- configurable: false,
663
- writable: false
664
- });
665
- }
666
- return selections;
667
- };
668
- const __mfReadTreeShakingSharedSelection = (cache, descriptor, consumer) => {
669
- const fullModule = __mfReadSharedCache(cache, descriptor);
670
- if (fullModule !== undefined) return fullModule;
671
- return cache[__mfTreeShakingSelectionCacheKey]?.[descriptor.canonical]?.[consumer];
672
- };
673
- const __mfWriteTreeShakingSharedSelection = (cache, descriptor, consumer, value) => {
674
- const selections = __mfGetTreeShakingSelectionCache(cache);
675
- const byConsumer = (selections[descriptor.canonical] ||= Object.create(null));
676
- byConsumer[consumer] = value;
677
- return value;
678
- };`;
679
- function getInstalledPackageJson(pkg, opts) {
680
- const cwd = opts?.cwd || getPackageDetectionCwd();
681
- const packageName = opts?.packageName || getPackageName(pkg);
682
- const cacheKey = `${cwd}\0${pkg}\0${packageName}\0${opts?.fromResolvedEntry ?? ""}`;
683
- if (installedPackageJsonCache.has(cacheKey)) return installedPackageJsonCache.get(cacheKey);
684
- const result = resolveInstalledPackageJson(pkg, cwd, packageName, opts);
685
- installedPackageJsonCache.set(cacheKey, result);
686
- return result;
687
- }
688
- function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
689
- const tryReadPackageJson = (packageJsonPath) => {
690
- if (!existsSync(packageJsonPath)) return void 0;
691
- try {
692
- return {
693
- path: packageJsonPath,
694
- dir: path$1.dirname(packageJsonPath),
695
- packageJson: JSON.parse(readFileSync(packageJsonPath, "utf-8"))
696
- };
697
- } catch {
698
- return;
699
- }
700
- };
701
- const findPackageInPnpmStore = (startDir) => {
702
- let currentDir = startDir;
703
- const rootDir = path$1.parse(currentDir).root;
704
- while (true) {
705
- const pnpmStoreDir = path$1.join(currentDir, "node_modules", ".pnpm");
706
- if (existsSync(pnpmStoreDir)) try {
707
- for (const entry of readdirSync(pnpmStoreDir, { withFileTypes: true })) {
708
- if (!entry.isDirectory()) continue;
709
- const candidate = tryReadPackageJson(path$1.join(pnpmStoreDir, entry.name, "node_modules", packageName, "package.json"));
710
- if (candidate?.packageJson.name === packageName) return candidate;
711
- }
712
- } catch {}
713
- if (currentDir === rootDir) break;
714
- currentDir = path$1.dirname(currentDir);
715
- }
716
- };
717
- try {
718
- const projectRequire = createRequire$1(pathToFileURL(path$1.join(cwd, "package.json")));
719
- let resolvedPath;
720
- if (opts?.fromResolvedEntry) resolvedPath = opts.fromResolvedEntry;
721
- else try {
722
- resolvedPath = projectRequire.resolve(pkg);
723
- } catch {
724
- resolvedPath = projectRequire.resolve(packageName);
725
- }
726
- let currentDir = path$1.dirname(resolvedPath);
727
- const rootDir = path$1.parse(currentDir).root;
728
- while (true) {
729
- const packageJsonPath = path$1.join(currentDir, "package.json");
730
- if (existsSync(packageJsonPath)) {
731
- const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
732
- try {
733
- const packageJson = JSON.parse(packageJsonContent);
734
- if (packageJson.name === packageName) return {
735
- path: packageJsonPath,
736
- dir: currentDir,
737
- packageJson
738
- };
739
- } catch (error) {
740
- if (!(error instanceof SyntaxError)) throw error;
741
- }
742
- }
743
- if (currentDir === rootDir) break;
744
- currentDir = path$1.dirname(currentDir);
745
- }
746
- } catch {
747
- let currentDir = cwd;
748
- const rootDir = path$1.parse(currentDir).root;
749
- while (true) {
750
- const directCandidate = tryReadPackageJson(path$1.join(currentDir, "node_modules", packageName, "package.json"));
751
- if (directCandidate?.packageJson.name === packageName) return directCandidate;
752
- if (currentDir === rootDir) break;
753
- currentDir = path$1.dirname(currentDir);
754
- }
755
- return findPackageInPnpmStore(cwd);
756
- }
757
- }
758
- function getInstalledPackageEntry(pkg, opts) {
759
- const installed = getInstalledPackageJson(pkg, opts);
760
- if (!installed) return void 0;
761
- const cwd = opts?.cwd || getPackageDetectionCwd();
762
- const packageName = opts?.packageName || getPackageName(pkg);
763
- const packageJson = installed.packageJson;
764
- if (pkg !== packageName && (opts?.resolveSubpathWithRequire !== false || packageJson.exports === void 0)) try {
765
- return createRequire$1(pathToFileURL(path$1.join(cwd, "package.json"))).resolve(pkg);
766
- } catch {}
767
- 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";
768
- return path$1.join(installed.dir, explicitEntry);
769
- }
770
- /**
771
- * Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
772
- * on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
773
- */
774
- function getIsRolldown(ctx) {
775
- const viteVersion = ctx?.meta?.viteVersion;
776
- const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
777
- return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
778
- }
779
- /** Walk up from Vite `config.root` (Nuxt may point at `.nuxt` cache dirs). */
780
- function isNuxtProjectRoot(root) {
781
- let dir = root;
782
- for (let i = 0; i < 8; i++) {
783
- if (hasPackageDependency("nuxt", dir) || hasPackageDependency("nuxt-nightly", dir)) return true;
784
- const parent = path$1.dirname(dir);
785
- if (parent === dir) break;
786
- dir = parent;
787
- }
788
- return false;
789
- }
790
- function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
791
- const cacheKey = getDependencyCacheKey(cwd, dependencyName);
792
- const cached = dependencyPresenceCache.get(cacheKey);
793
- if (cached !== void 0) return cached;
794
- try {
795
- const packageJson = JSON.parse(readFileSync(path$1.join(cwd, "package.json"), "utf8"));
796
- const hasDependency = [
797
- packageJson.dependencies,
798
- packageJson.devDependencies,
799
- packageJson.peerDependencies,
800
- packageJson.optionalDependencies
801
- ].some((deps) => !!deps?.[dependencyName]);
802
- dependencyPresenceCache.set(cacheKey, hasDependency);
803
- return hasDependency;
804
- } catch {
805
- dependencyPresenceCache.set(cacheKey, false);
806
- return false;
807
- }
808
- }
809
- //#endregion
810
327
  //#region src/utils/normalizeModuleFederationOptions.ts
811
328
  const INTERNAL_NAME_PREFIX = "__mfe_internal__";
812
329
  function toInternalModuleFederationName(name) {
@@ -1148,6 +665,8 @@ var VirtualModule = class VirtualModule {
1148
665
  //#region src/utils/ssrCapabilities.ts
1149
666
  /** A browser-safe generated expression that is true only in Node.js. */
1150
667
  const SERVER_ENV_GUARD = "import.meta.env.SSR";
668
+ const SSR_ENTRY_LOADER_SPECIFIER = "@module-federation/vite/ssrEntryLoader";
669
+ const SSR_ONLY_RUNTIME_PLUGINS = /* @__PURE__ */ new Set([SSR_ENTRY_LOADER_SPECIFIER]);
1151
670
  /**
1152
671
  * Single source of truth for SSR-related feature gates.
1153
672
  *
@@ -1454,27 +973,40 @@ function loadReactIslandConsumerModule(id) {
1454
973
  if (clientRemoteId !== void 0) return generateReactIslandConsumerClient(clientRemoteId);
1455
974
  }
1456
975
  //#endregion
976
+ //#region src/virtualModules/virtualModuleScope.ts
977
+ function getVirtualModuleScopeKey(options) {
978
+ return `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
979
+ }
980
+ //#endregion
1457
981
  //#region src/virtualModules/virtualExposes.ts
1458
982
  const EXPOSES_CSS_MAP_PLACEHOLDER = "__MF_EXPOSES_CSS_MAP__";
1459
983
  function getExposesCssMapPlaceholder() {
1460
984
  return EXPOSES_CSS_MAP_PLACEHOLDER;
1461
985
  }
1462
986
  function getVirtualExposesId(options) {
1463
- return `virtual:mf-exposes:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
987
+ return `virtual:mf-exposes:${getVirtualModuleScopeKey(options)}`;
1464
988
  }
1465
989
  function generateExposes(options, remoteDependencyMap = {}, command = "build", reactIslandExposes = /* @__PURE__ */ new Set()) {
1466
990
  return `
1467
991
  const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
1468
992
  const injectedCssHrefs = new Set();
1469
- let exposeLoadQueue = Promise.resolve();
993
+ const exposeLoadPromises = new Map();
1470
994
 
1471
- async function importExposedModule(loader) {
1472
- const currentLoad = exposeLoadQueue.then(loader, loader);
1473
- exposeLoadQueue = currentLoad.then(
1474
- () => undefined,
1475
- () => undefined
1476
- );
1477
- return currentLoad;
995
+ // Shared and remote readiness is handled by explicit Promise barriers below
996
+ // and by remoteEntry's pendingShareLoads barrier. Keep this map scoped to a
997
+ // single expose: unrelated exposes must stay independent and load in parallel.
998
+ function loadExposedModule(exposeKey, loader) {
999
+ let load = exposeLoadPromises.get(exposeKey);
1000
+ if (!load) {
1001
+ load = Promise.resolve()
1002
+ .then(loader)
1003
+ .catch((error) => {
1004
+ exposeLoadPromises.delete(exposeKey);
1005
+ throw error;
1006
+ });
1007
+ exposeLoadPromises.set(exposeKey, load);
1008
+ }
1009
+ return load;
1478
1010
  }
1479
1011
 
1480
1012
  async function injectCssAssets(exposeKey) {
@@ -1529,7 +1061,8 @@ function generateExposes(options, remoteDependencyMap = {}, command = "build", r
1529
1061
  ${JSON.stringify(key)}: async () => {
1530
1062
  await injectCssAssets(${JSON.stringify(key)})
1531
1063
  await Promise.all([${remoteDependencyPreloads}])
1532
- const importModule = await importExposedModule(
1064
+ const importModule = await loadExposedModule(
1065
+ ${JSON.stringify(key)},
1533
1066
  () => import(${JSON.stringify(options.exposes[key].import)})
1534
1067
  )
1535
1068
  const dependencyPending = importModule && importModule.__mf_remote_dependency_pending;
@@ -2133,6 +1666,7 @@ function getPackageEsmEntryPath(pkg) {
2133
1666
  resolveSubpathWithRequire: false
2134
1667
  }) || resolvePackageEntryFromProjectRoot(pkg);
2135
1668
  }
1669
+ const packageNamedExportsCache = /* @__PURE__ */ new Map();
2136
1670
  const DEFAULT_SHARED_EXPORT_CONDITIONS = [
2137
1671
  "browser",
2138
1672
  "import",
@@ -2619,10 +2153,13 @@ function getPackageNamedExports(pkg, exportConditions = DEFAULT_SHARED_EXPORT_CO
2619
2153
  resolveSubpathWithRequire: false
2620
2154
  });
2621
2155
  if (esmEntryPath) {
2156
+ const cacheKey = !isWorkspaceFilePath(esmEntryPath) ? `${getPackageDetectionCwd()}\0${esmEntryPath}\0${exportConditions.join("\0")}` : void 0;
2157
+ const cached = cacheKey ? packageNamedExportsCache.get(cacheKey) : void 0;
2158
+ if (cached) return cached.value;
2622
2159
  const inspection = inspectSharedExportsFromFile(esmEntryPath, exportConditions);
2623
- if (!inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs") return getRequiredNamedExports(esmEntryPath);
2624
- if (inspection.namedExports !== void 0) return inspection.namedExports;
2625
- return;
2160
+ const value = !inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs" ? getRequiredNamedExports(esmEntryPath) : inspection.namedExports;
2161
+ if (cacheKey) packageNamedExportsCache.set(cacheKey, { value });
2162
+ return value;
2626
2163
  }
2627
2164
  return getRequiredNamedExports(pkg);
2628
2165
  }
@@ -2770,10 +2307,27 @@ function tryResolveImportFromPackageRoot(pkg, root) {
2770
2307
  return;
2771
2308
  }
2772
2309
  }
2310
+ /**
2311
+ * Resolution walks from the project root up to the filesystem root, probing
2312
+ * every level, and the shared-module resolver asks for the same few packages
2313
+ * tens of thousands of times on a cold dev start. The detection cwd is part of
2314
+ * the key because `setPackageDetectionCwd` can move it between config hooks.
2315
+ */
2316
+ const concreteSharedImportSourceCache = /* @__PURE__ */ new Map();
2317
+ function resetConcreteSharedImportSourceCache() {
2318
+ concreteSharedImportSourceCache.clear();
2319
+ }
2773
2320
  function getConcreteSharedImportSource(pkg, shareItem) {
2774
2321
  const configuredImport = shareItem?.shareConfig.import;
2775
2322
  if (typeof configuredImport === "string") return configuredImport;
2776
2323
  const projectRoot = getPackageDetectionCwd();
2324
+ const cacheKey = JSON.stringify([projectRoot, pkg]);
2325
+ if (concreteSharedImportSourceCache.has(cacheKey)) return concreteSharedImportSourceCache.get(cacheKey);
2326
+ const resolved = resolveConcreteSharedImportSource(pkg, projectRoot);
2327
+ concreteSharedImportSourceCache.set(cacheKey, resolved);
2328
+ return resolved;
2329
+ }
2330
+ function resolveConcreteSharedImportSource(pkg, projectRoot) {
2777
2331
  if (tryResolveImportFromPackageRoot(pkg, projectRoot)) return;
2778
2332
  let currentDir = path$1.dirname(projectRoot);
2779
2333
  while (currentDir !== path$1.dirname(currentDir)) {
@@ -3348,6 +2902,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
3348
2902
  //#region src/virtualModules/virtualRemoteEntry.ts
3349
2903
  let usedShares = /* @__PURE__ */ new Set();
3350
2904
  const usedSharesByOptions = /* @__PURE__ */ new WeakMap();
2905
+ const materializedSharesByOptions = /* @__PURE__ */ new WeakMap();
3351
2906
  function getScopedUsedShares(options) {
3352
2907
  let scoped = usedSharesByOptions.get(options);
3353
2908
  if (!scoped) {
@@ -3363,6 +2918,18 @@ function getUsedShares(options) {
3363
2918
  function addUsedShares(pkg, options) {
3364
2919
  usedShares.add(pkg);
3365
2920
  if (options) getScopedUsedShares(options).add(pkg);
2921
+ if (options) {
2922
+ let scoped = materializedSharesByOptions.get(options);
2923
+ if (!scoped) {
2924
+ scoped = /* @__PURE__ */ new Set();
2925
+ materializedSharesByOptions.set(options, scoped);
2926
+ }
2927
+ scoped.add(pkg);
2928
+ }
2929
+ }
2930
+ function addConfiguredShare(pkg, options) {
2931
+ usedShares.add(pkg);
2932
+ if (options) getScopedUsedShares(options).add(pkg);
3366
2933
  }
3367
2934
  const LOCAL_SHARED_IMPORT_MAP_ID = "virtual:mf-localSharedImportMap";
3368
2935
  const localOwnerIds = /* @__PURE__ */ new WeakMap();
@@ -3409,6 +2976,7 @@ function generateLocalSharedImportMap(options) {
3409
2976
  const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
3410
2977
  const useDirectReactImport = shouldUseDirectReactImport();
3411
2978
  const orderedShares = getOrderedUsedShares(options);
2979
+ const sharesToMaterialize = new Set(getMaterializedShares(options));
3412
2980
  return `
3413
2981
  import {loadShare} from "@module-federation/runtime";
3414
2982
  ${orderedShares.map((pkg, index) => {
@@ -3429,7 +2997,7 @@ function generateLocalSharedImportMap(options) {
3429
2997
  }).join(",")}
3430
2998
  }
3431
2999
  const usedShared = {
3432
- ${getOrderedUsedShares(options).map((key) => {
3000
+ ${orderedShares.map((key) => {
3433
3001
  const shareItem = getNormalizeShareItem(key, resolvedOptions);
3434
3002
  if (!shareItem) return null;
3435
3003
  const detectedNamedExports = getSharedNamedExports(key, shareItem);
@@ -3447,6 +3015,7 @@ function generateLocalSharedImportMap(options) {
3447
3015
  version: ${JSON.stringify(shareItem.version)},
3448
3016
  scope: [${JSON.stringify(shareItem.scope)}],
3449
3017
  loaded: false,
3018
+ materialize: ${sharesToMaterialize.has(key)},
3450
3019
  eager: ${Boolean(shareItem.shareConfig.eager)},
3451
3020
  from: ${JSON.stringify(resolvedOptions.name)},
3452
3021
  canLiveRebind: ${canLiveRebind},
@@ -3517,7 +3086,7 @@ function generateLocalSharedImportMap(options) {
3517
3086
  function getOrderedUsedShares(options) {
3518
3087
  const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
3519
3088
  const shares = new Set(getUsedShares(options));
3520
- Object.keys(resolvedOptions.shared).forEach((pkg) => {
3089
+ Object.keys(resolvedOptions.shared ?? {}).forEach((pkg) => {
3521
3090
  if (!pkg.endsWith("/")) shares.add(pkg);
3522
3091
  });
3523
3092
  return orderSharedDependenciesFirst(Array.from(shares).sort((a, b) => {
@@ -3525,6 +3094,69 @@ function getOrderedUsedShares(options) {
3525
3094
  return priority(a) - priority(b) || a.localeCompare(b);
3526
3095
  }));
3527
3096
  }
3097
+ function getMaterializedShares(options) {
3098
+ const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
3099
+ const scopedRegistrations = options ? usedSharesByOptions.get(options) : void 0;
3100
+ const shares = new Set(options && scopedRegistrations?.size ? materializedSharesByOptions.get(options) ?? [] : usedShares);
3101
+ for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (!pkg.endsWith("/") && share.shareConfig?.eager) shares.add(pkg);
3102
+ const configured = /* @__PURE__ */ new Map();
3103
+ for (const pkg of getOrderedUsedShares(options)) {
3104
+ const packageName = getPackageName(pkg);
3105
+ if (!configured.has(packageName) || pkg === packageName) configured.set(packageName, pkg);
3106
+ }
3107
+ const pending = [...shares];
3108
+ while (pending.length) {
3109
+ const pkg = pending.pop();
3110
+ const packageName = getPackageName(pkg);
3111
+ const packageJson = getInstalledPackageJson(pkg)?.packageJson ?? (pkg !== packageName ? getInstalledPackageJson(packageName)?.packageJson : void 0);
3112
+ const dependencies = {
3113
+ ...packageJson?.dependencies || {},
3114
+ ...packageJson?.peerDependencies || {},
3115
+ ...packageJson?.optionalDependencies || {}
3116
+ };
3117
+ for (const dependency of Object.keys(dependencies)) {
3118
+ const sharedDependency = configured.get(dependency);
3119
+ if (sharedDependency && !shares.has(sharedDependency)) {
3120
+ shares.add(sharedDependency);
3121
+ pending.push(sharedDependency);
3122
+ }
3123
+ }
3124
+ }
3125
+ if (hasPackageDependency("vinext")) shares.delete("react");
3126
+ return orderSharedDependenciesFirst([...shares].sort((a, b) => {
3127
+ const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
3128
+ return priority(a) - priority(b) || a.localeCompare(b);
3129
+ }));
3130
+ }
3131
+ function getShareBatches(options, materializedOnly = true) {
3132
+ const ordered = materializedOnly ? getMaterializedShares(options) : getOrderedUsedShares(options);
3133
+ const levels = /* @__PURE__ */ new Map();
3134
+ const roots = /* @__PURE__ */ new Map();
3135
+ const subpaths = /* @__PURE__ */ new Map();
3136
+ for (const pkg of ordered) {
3137
+ const packageName = getPackageName(pkg);
3138
+ if (pkg === packageName) roots.set(packageName, pkg);
3139
+ else subpaths.set(packageName, [...subpaths.get(packageName) ?? [], pkg]);
3140
+ }
3141
+ for (const pkg of ordered) {
3142
+ const packageName = getPackageName(pkg);
3143
+ const packageJson = getInstalledPackageJson(pkg)?.packageJson ?? (pkg !== packageName ? getInstalledPackageJson(packageName)?.packageJson : void 0);
3144
+ const dependencies = {
3145
+ ...packageJson?.dependencies || {},
3146
+ ...packageJson?.peerDependencies || {},
3147
+ ...packageJson?.optionalDependencies || {}
3148
+ };
3149
+ const prerequisites = Object.keys(dependencies).map((dependency) => roots.get(dependency)).filter((dependency) => Boolean(dependency));
3150
+ if (pkg !== packageName && (packageName === "react" || packageName === "react-dom")) {
3151
+ const root = roots.get(packageName);
3152
+ if (root) prerequisites.push(root);
3153
+ } else if (pkg === packageName && packageName !== "react" && packageName !== "react-dom") prerequisites.push(...subpaths.get(packageName) ?? []);
3154
+ levels.set(pkg, prerequisites.reduce((level, dependency) => Math.max(level, (levels.get(dependency) ?? 0) + 1), 0));
3155
+ }
3156
+ const batches = [];
3157
+ for (const pkg of ordered) (batches[levels.get(pkg) ?? 0] ??= []).push(pkg);
3158
+ return batches.filter(Boolean);
3159
+ }
3528
3160
  function orderSharedDependenciesFirst(sharedPackages) {
3529
3161
  const sharedKeyByPackageName = /* @__PURE__ */ new Map();
3530
3162
  const subpathKeysByPackageName = /* @__PURE__ */ new Map();
@@ -3575,7 +3207,7 @@ function orderSharedDependenciesFirst(sharedPackages) {
3575
3207
  }
3576
3208
  function getShareItemForPreload(pkg, options = getNormalizeModuleFederationOptions()) {
3577
3209
  const shared = options.shared;
3578
- const wildcardKey = `${pkg.startsWith("@") ? pkg.split("/").slice(0, 2).join("/") : pkg.split("/")[0]}/`;
3210
+ const wildcardKey = `${getPackageName(pkg)}/`;
3579
3211
  if (isExplicitSharedKey(pkg, options)) return shared[pkg];
3580
3212
  if (isExplicitSharedKey(wildcardKey, options)) return shared[wildcardKey];
3581
3213
  }
@@ -3750,34 +3382,24 @@ const externalSharedProviderSelectionHelperCode = `const __mfSelectExternalShare
3750
3382
  ) return undefined;
3751
3383
  return { provider, scopeRootProvider };
3752
3384
  };`;
3753
- function generateRuntimeSharedCacheSeedCode(shareStrategy) {
3754
- const seedOrder = getOrderedUsedShares();
3385
+ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
3386
+ const seedBatches = getShareBatches(options, false);
3755
3387
  return `
3756
- const __mfSeedOrder = ${JSON.stringify(seedOrder)};
3757
- const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] !== undefined);
3758
- const __mfSeedPackageName = (pkg) => pkg.startsWith('@')
3759
- ? pkg.split('/').slice(0, 2).join('/')
3760
- : pkg.split('/')[0];
3761
- for (const pkg of Object.keys(usedShared)) {
3762
- if (__mfSeedKeys.includes(pkg)) continue;
3763
- const packageName = __mfSeedPackageName(pkg);
3764
- const rootIndex = __mfSeedKeys.indexOf(packageName);
3765
- if (rootIndex === -1) {
3766
- __mfSeedKeys.push(pkg);
3767
- continue;
3768
- }
3769
- let insertIndex = rootIndex;
3770
- while (
3771
- insertIndex > 0 &&
3772
- __mfSeedPackageName(__mfSeedKeys[insertIndex - 1]) === packageName &&
3773
- __mfSeedKeys[insertIndex - 1] !== packageName
3774
- ) {
3775
- insertIndex--;
3776
- }
3777
- __mfSeedKeys.splice(insertIndex, 0, pkg);
3778
- }
3388
+ const __mfSeedOrder = ${JSON.stringify(seedBatches.flat())};
3389
+ const __mfSeedBatches = ${JSON.stringify(seedBatches)};
3390
+ const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] && usedShared[pkg].materialize !== false);
3391
+ __mfModuleCache.providerInit ||= new Map();
3392
+ const __mfInitializeProviderOnce = (key, initialize) => {
3393
+ const existing = __mfModuleCache.providerInit.get(key);
3394
+ if (existing) return existing;
3395
+ const pending = Promise.resolve().then(initialize);
3396
+ __mfModuleCache.providerInit.set(key, pending);
3397
+ pending.catch(() => __mfModuleCache.providerInit.delete(key));
3398
+ return pending;
3399
+ };
3779
3400
  var __mfSeedLocalShared = async (seedKeys) => {
3780
- for (const pkg of seedKeys) {
3401
+ const requested = new Set(seedKeys);
3402
+ for (const batch of __mfSeedBatches) await Promise.all(batch.filter((pkg) => requested.has(pkg)).map(async (pkg) => {
3781
3403
  const share = usedShared[pkg];
3782
3404
  const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
3783
3405
  if (
@@ -3785,7 +3407,7 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy) {
3785
3407
  Boolean(share.treeShaking) ||
3786
3408
  __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined
3787
3409
  ) {
3788
- continue;
3410
+ return;
3789
3411
  }
3790
3412
  const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
3791
3413
  const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
@@ -3796,11 +3418,20 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy) {
3796
3418
  singletonModule,
3797
3419
  __mfReadSharedCacheOwner(__mfModuleCache.share, singletonCacheDescriptor)
3798
3420
  );
3799
- continue;
3421
+ return;
3800
3422
  }
3801
- const factory = await share.get();
3802
- const mod = typeof factory === "function" ? factory() : factory;
3803
- const resolved = await Promise.resolve(mod);
3423
+ const pendingExternalProvider = typeof __mfGetPendingExternalSharedProvider === 'function'
3424
+ ? __mfGetPendingExternalSharedProvider(pkg, share)
3425
+ : undefined;
3426
+ if (pendingExternalProvider && !pendingExternalProvider.lib && !pendingExternalProvider.loaded) {
3427
+ return;
3428
+ }
3429
+ const providerKey = cacheDescriptor.canonical;
3430
+ const resolved = await __mfInitializeProviderOnce(providerKey, async () => {
3431
+ const factory = await share.get();
3432
+ const mod = typeof factory === "function" ? factory() : factory;
3433
+ return Promise.resolve(mod);
3434
+ });
3804
3435
  ${normalizeRuntimeShareCode}
3805
3436
  const normalizedModule = __mfNormalizeRuntimeShare(resolved);
3806
3437
  const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
@@ -3809,7 +3440,7 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy) {
3809
3440
  enumerable: false
3810
3441
  });
3811
3442
  __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, exportModule, mfName);
3812
- }
3443
+ }));
3813
3444
  };
3814
3445
  const __mfIsRuntimeOnlySharePending = (pkg) => {
3815
3446
  const share = usedShared[pkg];
@@ -3875,7 +3506,7 @@ function getBrowserImportPath(importPath) {
3875
3506
  }
3876
3507
  function getHostAutoInitSharedSeedItems(options) {
3877
3508
  const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
3878
- return getOrderedUsedShares(options).map((pkg) => ({
3509
+ return getMaterializedShares(options).map((pkg) => ({
3879
3510
  pkg,
3880
3511
  shareItem: getShareItemForPreload(pkg, resolvedOptions)
3881
3512
  })).filter(({ shareItem }) => shareItem?.shareConfig?.import === false).sort((a, b) => {
@@ -3895,12 +3526,10 @@ function generateHostAutoInitSharedCacheSeedCode(command = "build", options) {
3895
3526
  }
3896
3527
  const REMOTE_ENTRY_ID = "virtual:mf-REMOTE_ENTRY_ID";
3897
3528
  function getRemoteEntryId(options) {
3898
- const scopedKey = `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
3899
- return `${REMOTE_ENTRY_ID}:${scopedKey}`;
3529
+ return `${REMOTE_ENTRY_ID}:${getVirtualModuleScopeKey(options)}`;
3900
3530
  }
3901
- const SSR_ONLY_PLUGIN_SPECIFIERS = /* @__PURE__ */ new Set(["@module-federation/vite/ssrEntryLoader"]);
3902
- const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
3903
- const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
3531
+ const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_RUNTIME_PLUGINS].some((s) => importStatement.includes(s));
3532
+ const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_RUNTIME_PLUGINS].find((s) => importStatement.includes(s));
3904
3533
  function generateTreeShakingSharedResolutionCode(enabled) {
3905
3534
  if (!enabled) return "const __mfResolveTreeShakingShared = async () => {};";
3906
3535
  return `
@@ -4064,6 +3693,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4064
3693
  const needsSharedProviderSelectionHelper = Object.keys(options.shared ?? {}).length > 0;
4065
3694
  const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
4066
3695
  const hasMultipleShareScopes = Array.isArray(options.shareScope);
3696
+ const materializedShareBatches = JSON.stringify(getShareBatches(options, false));
4067
3697
  const runtimeImports = [
4068
3698
  "init as runtimeInit",
4069
3699
  "loadRemote",
@@ -4117,14 +3747,16 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4117
3747
  import {${runtimeImports}} from "@module-federation/runtime";
4118
3748
  ${runtimeHelperImports.length ? `import {${runtimeHelperImports.join(", ")}} from "@module-federation/runtime/helpers";` : ""}
4119
3749
  ${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => item[1]).join("\n")}
4120
- ${command === "build" ? getRuntimeInitResolveBootstrapCode(false, options ? getRuntimeInitStatusImportId(options) : void 0) : getRuntimeInitBootstrapCode(false, options ? getRuntimeInitStatusImportId(options) : void 0) + "\n const { initResolve } = globalThis[globalKey];"}
3750
+ ${command === "build" ? getRuntimeInitResolveBootstrapCode(false, getRuntimeInitStatusImportId(options)) : getRuntimeInitBootstrapCode(false, getRuntimeInitStatusImportId(options)) + "\n const { initResolve } = globalThis[globalKey];"}
4121
3751
  ${getRuntimeModuleCacheBootstrapCode()}
4122
3752
  const initTokens = {}
4123
3753
  const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)}) ? ${JSON.stringify(options.shareScope)} : [${JSON.stringify(options.shareScope)}]
4124
3754
  const shareScopeName = ${JSON.stringify(hasMultipleShareScopes ? options.shareScope[0] : options.shareScope)}
4125
3755
  const mfName = ${JSON.stringify(options.name)}
3756
+ const __mfMaterializedShareBatches = ${materializedShareBatches}
4126
3757
  let localSharedImportMapPromise
4127
3758
  let exposesMapPromise
3759
+ let __mfLateBridgeShared
4128
3760
  const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
4129
3761
  const message = String((error && error.message) || error || '');
4130
3762
  return message.includes('Importing a module script failed') ||
@@ -4195,6 +3827,40 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4195
3827
  instance?.options?.name !== mfName &&
4196
3828
  ${hasMultipleShareScopes ? "shareScopeNames.some((scopeName) => instance?.shareScopeMap?.[scopeName] === getShareScope(scopeName))" : `instance?.shareScopeMap?.['${options.shareScope}'] === shared`}
4197
3829
  );
3830
+ const __mfRuntimeShareScopes = Object.create(null);
3831
+ const __mfCloneShareScope = (hostScope) => {
3832
+ const runtimeScope = Object.create(null);
3833
+ for (const [pkg, versions] of Object.entries(hostScope || {})) {
3834
+ runtimeScope[pkg] = Object.assign(Object.create(null), versions);
3835
+ }
3836
+ return runtimeScope;
3837
+ };
3838
+ const __mfGetRuntimeShareScope = (scopeName, hostScope) => {
3839
+ const isWebpackScope = !scopeRoot && Object.values(hostScope || {}).some((versions) =>
3840
+ Object.values(versions || {}).some(isWebpackProvider)
3841
+ );
3842
+ const runtimeScope = isWebpackScope ? __mfCloneShareScope(hostScope) : hostScope;
3843
+ __mfRuntimeShareScopes[scopeName] = {
3844
+ host: hostScope,
3845
+ runtime: runtimeScope,
3846
+ isWebpackScope
3847
+ };
3848
+ return runtimeScope;
3849
+ };
3850
+ const __mfRestoreForeignSharedProviders = () => {
3851
+ const webpackScopes = Object.values(__mfRuntimeShareScopes).filter(
3852
+ ({ isWebpackScope }) => isWebpackScope
3853
+ );
3854
+ if (webpackScopes.length === 0) return;
3855
+ for (const { host, runtime } of webpackScopes) {
3856
+ for (const [pkg, versions] of Object.entries(host || {})) {
3857
+ const runtimeVersions = runtime[pkg] ||= Object.create(null);
3858
+ for (const [version, provider] of Object.entries(versions || {})) {
3859
+ runtimeVersions[version] = provider;
3860
+ }
3861
+ }
3862
+ }
3863
+ };
4198
3864
  const initialShared = Object.create(null);
4199
3865
  ${hasMultipleShareScopes ? `for (const scopeName of shareScopeNames) {
4200
3866
  for (const [pkg, versions] of Object.entries(getShareScope(scopeName))) {
@@ -4213,6 +3879,41 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4213
3879
  }
4214
3880
  }`}
4215
3881
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
3882
+ function isWebpackProvider(provider) {
3883
+ if (typeof provider?.get !== 'function') return false;
3884
+ const source = Function.prototype.toString.call(provider.get);
3885
+ return source.includes('__webpack_require__');
3886
+ }
3887
+ const __mfUsesWebpackShareScope = Object.values(initialShared).some((versions) =>
3888
+ Object.values(versions || {}).some(isWebpackProvider)
3889
+ );
3890
+ const __mfGetSharePackageName = (pkg) => {
3891
+ const parts = pkg.split('/');
3892
+ return pkg.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];
3893
+ };
3894
+ const __mfGetPendingExternalSharedProvider = (pkg, share, versionMap) => {
3895
+ if (typeof __mfSelectExternalSharedProvider !== 'function') return undefined;
3896
+ const packageName = __mfGetSharePackageName(pkg);
3897
+ const candidates = packageName === pkg
3898
+ ? [[pkg, share]]
3899
+ : [[pkg, share], [packageName, usedShared[packageName]]];
3900
+ for (const [candidatePkg, candidateShare] of candidates) {
3901
+ if (!candidateShare) continue;
3902
+ const candidateVersionMap = versionMap
3903
+ ? (candidatePkg === pkg ? versionMap : initialShared[candidatePkg])
3904
+ : ${hasMultipleShareScopes ? "getShareVersions(candidatePkg, candidateShare)" : "shared[candidatePkg]"};
3905
+ const provider = __mfSelectExternalSharedProvider(
3906
+ candidateVersionMap,
3907
+ candidatePkg,
3908
+ candidateShare,
3909
+ '${options.shareStrategy}'
3910
+ );
3911
+ if (provider && isWebpackProvider(provider) && !provider.lib && !provider.loaded) {
3912
+ return provider;
3913
+ }
3914
+ }
3915
+ return undefined;
3916
+ };
4216
3917
  // handling circular init calls before an external provider can re-enter this container
4217
3918
  ${hasMultipleShareScopes ? `const shareScopeNamesToInitialize = [];
4218
3919
  for (const shareScopeName of shareScopeNames) {
@@ -4249,8 +3950,14 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4249
3950
  });
4250
3951
  ${hasMultipleShareScopes ? `for (const shareScopeName of shareScopeNamesToInitialize) {
4251
3952
  const scopeShare = getShareScope(shareScopeName);
4252
- initRes.initShareScopeMap(shareScopeName, scopeShare);
4253
- }` : `initRes.initShareScopeMap('${options.shareScope}', shared);`}
3953
+ initRes.initShareScopeMap(
3954
+ shareScopeName,
3955
+ __mfGetRuntimeShareScope(shareScopeName, scopeShare)
3956
+ );
3957
+ }` : `initRes.initShareScopeMap(
3958
+ '${options.shareScope}',
3959
+ __mfGetRuntimeShareScope('${options.shareScope}', shared)
3960
+ );`}
4254
3961
  function __mfSharePinLifecyclePlugin() {
4255
3962
  return {
4256
3963
  name: "vite-share-pin-lifecycle-plugin",
@@ -4522,6 +4229,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4522
4229
  // this container's outer initScope. Materialized providers are already active,
4523
4230
  // so resolve them directly and keep remote initialization on the guarded path.
4524
4231
  let directFactory = provider.lib;
4232
+ if (!directFactory && isWebpackProvider(provider)) return;
4525
4233
  if (!directFactory && provider.loading) directFactory = await provider.loading;
4526
4234
  if (!directFactory && provider.loaded && typeof provider.get === 'function') {
4527
4235
  directFactory = await provider.get();
@@ -4546,13 +4254,10 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4546
4254
  const resolved = loadedShare?.resolved;
4547
4255
  if (resolved === undefined) return;
4548
4256
  if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) !== undefined) return;
4549
- ${options.shareStrategy === "loaded-first" ? `if (
4550
- actualSelection.registered &&
4551
- liveVersionMap?.[actualSelection.version] !== actualProvider
4552
- ) return;` : `if (
4257
+ if (
4553
4258
  actualSelection.registered &&
4554
4259
  liveVersionMap?.[actualSelection.version] !== actualProvider
4555
- ) return;`}
4260
+ ) return;
4556
4261
  __mfWriteSharedCache(
4557
4262
  __mfModuleCache.share,
4558
4263
  usedCacheDescriptor,
@@ -4572,6 +4277,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4572
4277
  expectedSelection
4573
4278
  ) => {
4574
4279
  try {
4280
+ if (__mfGetPendingExternalSharedProvider(pkg, usedShare)) return;
4575
4281
  const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
4576
4282
  const cachedShare = __mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor);
4577
4283
  const cachedShareOwner = __mfReadSharedCacheOwner(__mfModuleCache.share, usedCacheDescriptor);
@@ -4619,6 +4325,12 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4619
4325
  !scopeRootProvider &&
4620
4326
  !__mfMatchesSharedProvider(liveProvider, provider)
4621
4327
  ) return;
4328
+ if (
4329
+ !selectedLocalProvider &&
4330
+ isWebpackProvider(provider) &&
4331
+ !provider.lib &&
4332
+ !provider.loaded
4333
+ ) return;
4622
4334
  const loadedShare = await __mfLoadPinnedRuntimeShare(
4623
4335
  pkg,
4624
4336
  usedShare.shareConfig,
@@ -4666,10 +4378,11 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4666
4378
  console.error('[Module Federation] Failed to bridge external shared module "' + pkg + '"', e)
4667
4379
  }
4668
4380
  };
4669
- for (const [pkg, usedShare] of Object.entries(usedShared)) {
4670
- if (usedShare.treeShaking) continue;
4381
+ for (const batch of __mfMaterializedShareBatches) await Promise.all(batch.map(async (pkg) => {
4382
+ const usedShare = usedShared[pkg];
4383
+ if (!usedShare || usedShare.materialize === false || usedShare.treeShaking) return;
4671
4384
  await __mfBridgeMaterializedProvider(pkg, usedShare, initialShared[pkg]);
4672
- }
4385
+ }));
4673
4386
  for (const [pkg, share] of Object.entries(usedShared)) {
4674
4387
  if (share.treeShaking) continue;
4675
4388
  const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
@@ -4685,19 +4398,27 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4685
4398
  );
4686
4399
  }
4687
4400
  }
4688
- ${generateRuntimeSharedCacheSeedCode(options.shareStrategy)}
4401
+ ${generateRuntimeSharedCacheSeedCode(options.shareStrategy, options)}
4689
4402
  ${initializeSharingCode}
4403
+ __mfRestoreForeignSharedProviders();
4690
4404
  // Calling provider.get() marks a provider as loaded. Wait until the Runtime has
4691
4405
  // finalized normal same-version precedence before materializing an external share.
4692
- for (const [pkg, usedShare] of Object.entries(usedShared)) {
4693
- if (usedShare.treeShaking) continue;
4694
- await __mfBridgeExternalSharedProvider(
4695
- pkg,
4696
- usedShare,
4697
- ${hasMultipleShareScopes ? "getShareVersions(pkg, usedShare)" : "shared[pkg]"},
4698
- initialShared[pkg],
4699
- undefined
4700
- );
4406
+ const __mfBridgeSharedProviders = async () => {
4407
+ for (const batch of __mfMaterializedShareBatches) await Promise.all(batch.map(async (pkg) => {
4408
+ const usedShare = usedShared[pkg];
4409
+ if (!usedShare || usedShare.materialize === false || usedShare.treeShaking) return;
4410
+ await __mfBridgeExternalSharedProvider(
4411
+ pkg,
4412
+ usedShare,
4413
+ ${hasMultipleShareScopes ? "getShareVersions(pkg, usedShare)" : "shared[pkg]"},
4414
+ initialShared[pkg],
4415
+ undefined
4416
+ );
4417
+ }));
4418
+ };
4419
+ await __mfBridgeSharedProviders();
4420
+ if (__mfUsesWebpackShareScope) {
4421
+ __mfLateBridgeShared = __mfBridgeSharedProviders;
4701
4422
  }
4702
4423
  try {
4703
4424
  const allInstances = globalThis.__FEDERATION__?.__SHARE__;
@@ -4732,7 +4453,9 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4732
4453
  }
4733
4454
  }
4734
4455
  }
4735
- for (const [pkg, versionMap] of Object.entries(globalVersionsByPackage)) {
4456
+ for (const batch of __mfMaterializedShareBatches) await Promise.all(batch.map(async (pkg) => {
4457
+ const versionMap = globalVersionsByPackage[pkg];
4458
+ if (!versionMap) return;
4736
4459
  await __mfBridgeExternalSharedProvider(
4737
4460
  pkg,
4738
4461
  usedShared[pkg],
@@ -4740,7 +4463,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4740
4463
  initialShared[pkg],
4741
4464
  bridgeSelections.get(pkg)
4742
4465
  );
4743
- }
4466
+ }));
4744
4467
  } catch (e) {
4745
4468
  console.error('[Module Federation] Failed to bridge external shared modules', e)
4746
4469
  }
@@ -4751,6 +4474,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4751
4474
  ? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
4752
4475
  : __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
4753
4476
  if (share.shareConfig?.import !== false || cachedShare !== undefined) return;
4477
+ if (__mfGetPendingExternalSharedProvider(pkg, share, initialShared[pkg])) return;
4754
4478
  ${normalizeRuntimeShareCode}
4755
4479
  const versionMap = ${hasMultipleShareScopes ? "getShareVersions(pkg, share)" : "shared?.[pkg]"};
4756
4480
  const provider = __mfSelectSharedProvider(
@@ -4813,18 +4537,30 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4813
4537
  // Resolve runtime-only dependencies and seed local fallbacks in dependency
4814
4538
  // order. Stop at an unresolved provider so its consumers cannot capture an
4815
4539
  // undefined or provisional singleton.
4540
+ const __mfReadyDeferredSeedKeys = [];
4816
4541
  for (const pkg of __mfDeferredSeedKeys) {
4817
4542
  const share = usedShared[pkg];
4818
4543
  if (__mfIsRuntimeOnlySharePending(pkg)) {
4819
- if (share.treeShaking) {
4820
- await __mfResolveTreeShakingShared(pkg, share);
4821
- } else if (share.shareConfig?.import === false) {
4822
- await __mfResolveImportFalseShared(pkg, share);
4544
+ try {
4545
+ if (share.treeShaking) {
4546
+ await __mfResolveTreeShakingShared(pkg, share);
4547
+ } else if (share.shareConfig?.import === false) {
4548
+ await __mfResolveImportFalseShared(pkg, share);
4549
+ }
4550
+ } catch (err) {
4551
+ // A rejected provider is an unresolved provider: stop here as the comment above
4552
+ // prescribes, instead of escalating to a container-wide init() failure.
4553
+ console.error(
4554
+ \`[Module Federation] Failed to resolve runtime-only shared module "\${pkg}"\`,
4555
+ err
4556
+ );
4557
+ break;
4823
4558
  }
4824
4559
  }
4825
4560
  if (__mfIsRuntimeOnlySharePending(pkg)) break;
4826
- await __mfSeedLocalShared([pkg]);
4561
+ __mfReadyDeferredSeedKeys.push(pkg);
4827
4562
  }
4563
+ await __mfSeedLocalShared(__mfReadyDeferredSeedKeys);
4828
4564
  initResolve(initRes)
4829
4565
  return initRes
4830
4566
  }
@@ -4832,6 +4568,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
4832
4568
  async function getExposes(moduleName) {
4833
4569
  const exposesMap = await getExposesMap()
4834
4570
  if (!(moduleName in exposesMap)) throw new Error(\`[Module Federation] Module \${moduleName} does not exist in container.\`)
4571
+ if (__mfLateBridgeShared) await __mfLateBridgeShared()
4835
4572
  if (__mfModuleCache.pendingShareLoads) {
4836
4573
  await Promise.all(__mfModuleCache.pendingShareLoads)
4837
4574
  }
@@ -4886,11 +4623,10 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
4886
4623
  const {usedShared} = await import("${getLocalSharedImportMapPath(options)}");
4887
4624
  ${normalizeRuntimeShareCode}
4888
4625
  ${shouldPreloadShares ? `
4889
- const __mfHostInitShareOrder = ${hostInitShareOrder}
4890
- .concat(Object.keys(usedShared).filter((pkg) => !${hostInitShareOrder}.includes(pkg)));
4626
+ const __mfHostInitShareOrder = ${hostInitShareOrder};
4891
4627
  for (const pkg of __mfHostInitShareOrder) {
4892
4628
  const share = usedShared[pkg];
4893
- if (!share) continue;
4629
+ if (!share || share.materialize === false) continue;
4894
4630
  // remoteEntry.init resolves tree-enabled shares into the
4895
4631
  // coverage-aware cache. Never republish that selected partial under
4896
4632
  // a generic full-module key here.
@@ -4914,8 +4650,6 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
4914
4650
  });
4915
4651
  }
4916
4652
  ` : ""}
4917
- const __mfRemotePreloads = [];
4918
- await Promise.all(__mfRemotePreloads);
4919
4653
  return runtime;
4920
4654
  })();
4921
4655
  }
@@ -4937,9 +4671,6 @@ function refreshHostAutoInit(options) {
4937
4671
  writeHostAutoInit(state.remoteEntryId, state.command, options);
4938
4672
  } catch {}
4939
4673
  }
4940
- function getHostAutoInitImportId(options) {
4941
- return getHostAutoInitState(options).module.getImportId();
4942
- }
4943
4674
  function getHostAutoInitPath(options) {
4944
4675
  return getHostAutoInitState(options).module.getImportId();
4945
4676
  }
@@ -5493,6 +5224,10 @@ const __mfCurrentScript = document.currentScript;
5493
5224
  function normalizeModuleId(id) {
5494
5225
  return normalizePathForImport(id.split("?")[0]);
5495
5226
  }
5227
+ function isReactRouterClientEntry(id) {
5228
+ const normalized = normalizeModuleId(decodeViteId(id).replace(/^\0+/, ""));
5229
+ return /(?:^|\/)entry\.client\.(?:[cm]?[jt]sx?)$/.test(normalized);
5230
+ }
5496
5231
  function resolveProjectId(id) {
5497
5232
  if (id.startsWith("\0") || id.startsWith("virtual:")) return normalizeModuleId(id);
5498
5233
  return normalizeModuleId(path$1.isAbsolute(id) ? id : path$1.resolve(viteConfig.root, id));
@@ -5753,10 +5488,11 @@ const __mfCurrentScript = document.currentScript;
5753
5488
  const injection = `await import(${JSON.stringify(getEntryPath())}).then(({ initHost }) => initHost());\n `;
5754
5489
  return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
5755
5490
  }
5756
- const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !isFederationInternalVirtualId(id) && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && (/hydrateRoot|createRoot|ReactDOM\.render/.test(code) || /\.mount\s*\(\s*['"#]/.test(code) || /\.mount\s*\(/.test(code) && /createSSRApp|createApp/.test(code));
5491
+ const isReactRouterEntry = isReactRouterClientEntry(id);
5492
+ const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !isFederationInternalVirtualId(id) && !id.includes("node_modules") && (!code.includes("HydratedRouter") || isReactRouterEntry) && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && (/hydrateRoot|createRoot|ReactDOM\.render/.test(code) || /\.mount\s*\(\s*['"#]/.test(code) || /\.mount\s*\(/.test(code) && /createSSRApp|createApp/.test(code));
5757
5493
  const isNuxtEntryAsyncModule = /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
5758
5494
  const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && isNuxtEntryAsyncModule && !entryFiles.some((file) => projectId === file);
5759
- if (!(_command === "serve" && isNuxtEntryAsyncModule) && (injectedTransformIds.has(projectId) || injectEntry() && entryFiles.some((file) => projectId === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !skipHtmlDevFallback && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback)) {
5495
+ if (!(_command === "serve" && isNuxtEntryAsyncModule) && (injectedTransformIds.has(projectId) || injectEntry() && entryFiles.some((file) => projectId === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !skipHtmlDevFallback && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || inject === "entry" && waitsForInit && isReactRouterEntry || isNuxtClientEntryFallback)) {
5760
5496
  clientInjected = true;
5761
5497
  injectedTransformIds.add(projectId);
5762
5498
  if (!waitsForInit) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
@@ -5892,10 +5628,12 @@ const reactAdapter = {
5892
5628
  * host components lives in the orphaned first runtime, but `reload(hmrId, ...)`
5893
5629
  * goes through the second runtime — the lookup misses and HMR stops working.
5894
5630
  *
5895
- * This guard pins `__VUE_HMR_RUNTIME__` to the first writer (the host's Vue)
5631
+ * This guard pins `__VUE_HMR_RUNTIME__` to the first application Vue runtime
5896
5632
  * via a property trap on `globalThis`. Subsequent writes from remote-side Vue
5897
- * copies are silently dropped. Must execute before any Vue module loads —
5898
- * injected as a plain (non-module) script at `head-prepend`.
5633
+ * copies are silently dropped. vite-plugin-checker bundles its own Vue runtime
5634
+ * and evaluates it before the application, so writes from its virtual runtime
5635
+ * are ignored explicitly. Must execute before any Vue module loads — injected
5636
+ * as a plain (non-module) script at `head-prepend`.
5899
5637
  *
5900
5638
  * `singleton: true` in `shared` is not sufficient: in dev mode MF's share-scope
5901
5639
  * does not actually dedupe Vue across dev servers, so without this guard the
@@ -5906,7 +5644,11 @@ const VUE_HMR_RUNTIME_GUARD_SCRIPT = `
5906
5644
  var h = null;
5907
5645
  Object.defineProperty(globalThis, '__VUE_HMR_RUNTIME__', {
5908
5646
  get: function () { return h; },
5909
- set: function (v) { if (h === null) h = v; },
5647
+ set: function (v) {
5648
+ var stack = new Error().stack || '';
5649
+ if (stack.indexOf('@vite-plugin-checker-runtime') !== -1) return;
5650
+ if (h === null) h = v;
5651
+ },
5910
5652
  configurable: true,
5911
5653
  enumerable: true,
5912
5654
  });
@@ -5973,7 +5715,7 @@ const REMOTE_HMR_ENDPOINT = "__mf_hmr";
5973
5715
  const REMOTE_HMR_EVENT = "mf:remote-update";
5974
5716
  const REMOTE_HMR_CONNECT_RETRY_DELAY_MS = 1e3;
5975
5717
  const REMOTE_HMR_CONNECT_MAX_RETRIES = 10;
5976
- function getBasePath$1(base) {
5718
+ function getBasePath(base) {
5977
5719
  if (!base) return "/";
5978
5720
  if (base.startsWith("http://") || base.startsWith("https://")) try {
5979
5721
  return new URL(base).pathname || "/";
@@ -5983,11 +5725,11 @@ function getBasePath$1(base) {
5983
5725
  return base;
5984
5726
  }
5985
5727
  function getRemoteHmrPath(base) {
5986
- return `${getBasePath$1(base).replace(/\/?$/, "/")}${REMOTE_HMR_ENDPOINT}`.replace(/\/{2,}/g, "/");
5728
+ return `${getBasePath(base).replace(/\/?$/, "/")}${REMOTE_HMR_ENDPOINT}`.replace(/\/{2,}/g, "/");
5987
5729
  }
5988
5730
  function getHmrWsPath(base, hmrPath) {
5989
- const normalizedBase = getBasePath$1(base);
5990
- const normalizedPath = getBasePath$1(hmrPath || "");
5731
+ const normalizedBase = getBasePath(base);
5732
+ const normalizedPath = getBasePath(hmrPath || "");
5991
5733
  if (!normalizedPath || normalizedPath === "/") return normalizedBase;
5992
5734
  return `${normalizedBase.endsWith("/") ? normalizedBase.slice(0, -1) : normalizedBase}/${normalizedPath.startsWith("/") ? normalizedPath.slice(1) : normalizedPath}`;
5993
5735
  }
@@ -6872,7 +6614,7 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn, options) => {
6872
6614
  * and shared packages are imported as bare specifiers (externals in the SSR build).
6873
6615
  */
6874
6616
  function getVirtualExposesSSRId(options) {
6875
- return `virtual:mf-exposes-ssr:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
6617
+ return `virtual:mf-exposes-ssr:${getVirtualModuleScopeKey(options)}`;
6876
6618
  }
6877
6619
  /**
6878
6620
  * Generates the SSR exposes map module.
@@ -6908,8 +6650,7 @@ function generateExposesSSR(options, reactIslandExposes = /* @__PURE__ */ new Se
6908
6650
  //#region src/virtualModules/virtualRemoteEntrySSR.ts
6909
6651
  const REMOTE_ENTRY_SSR_ID = "virtual:mf-REMOTE_ENTRY_SSR_ID";
6910
6652
  function getRemoteEntrySSRId(options) {
6911
- const scopedKey = `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
6912
- return `${REMOTE_ENTRY_SSR_ID}:${scopedKey}`;
6653
+ return `${REMOTE_ENTRY_SSR_ID}:${getVirtualModuleScopeKey(options)}`;
6913
6654
  }
6914
6655
  function getSsrRemoteEntryFileName(browserFilename) {
6915
6656
  const ext = browserFilename.match(/\.[^.]+$/)?.[0] || ".js";
@@ -6927,11 +6668,24 @@ function getSsrRemoteEntryFileName(browserFilename) {
6927
6668
  */
6928
6669
  function generateRemoteEntrySSR(options) {
6929
6670
  const virtualExposesSSRId = getVirtualExposesSSRId(options);
6671
+ const sharedSingletons = Object.fromEntries(Object.entries(options.shared).filter(([, share]) => share.shareConfig.singleton));
6930
6672
  return `
6931
6673
  import { init as runtimeInit } from "@module-federation/runtime";
6932
6674
 
6675
+ const sharedSingletons = ${JSON.stringify(sharedSingletons)};
6933
6676
  let exposesMapPromise;
6934
6677
 
6678
+ function createShareInitError(errors) {
6679
+ const details = errors.map(({ scopeName, pkg, error }) => {
6680
+ const target = pkg
6681
+ ? \`scope "\${scopeName}" package "\${pkg}"\`
6682
+ : \`scope "\${scopeName}"\`;
6683
+ return \`\${target}: \${error instanceof Error ? error.message : String(error)}\`;
6684
+ });
6685
+ const message = \`[Module Federation SSR] Shared initialization failed: \${details.join('; ')}\`;
6686
+ return new AggregateError(errors.map(({ error }) => error), message);
6687
+ }
6688
+
6935
6689
  async function getExposesMap() {
6936
6690
  exposesMapPromise ??= import(${JSON.stringify(virtualExposesSSRId)}).then((mod) => mod.default ?? mod);
6937
6691
  return exposesMapPromise;
@@ -6954,24 +6708,54 @@ function generateRemoteEntrySSR(options) {
6954
6708
  const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)})
6955
6709
  ? ${JSON.stringify(options.shareScope)}
6956
6710
  : [${JSON.stringify(options.shareScope)}];
6957
- try {
6958
- for (const scopeName of shareScopeNames) {
6711
+ const shareInitErrors = [];
6712
+ const cacheEntries = [];
6713
+ for (const scopeName of shareScopeNames) {
6714
+ let scopeShare;
6715
+ try {
6716
+ scopeShare = Array.isArray(${JSON.stringify(options.shareScope)})
6717
+ ? shared?.[scopeName] || {}
6718
+ : shared || {};
6719
+ initRes.initShareScopeMap(scopeName, scopeShare);
6720
+ await Promise.all(
6721
+ await initRes.initializeSharing(scopeName, {
6722
+ strategy: ${JSON.stringify(options.shareStrategy ?? "version-first")},
6723
+ from: 'build',
6724
+ initScope,
6725
+ })
6726
+ );
6727
+ } catch (e) {
6728
+ shareInitErrors.push({ scopeName, pkg: undefined, error: e });
6729
+ continue;
6730
+ }
6731
+
6732
+ for (const [pkg, shareInfo] of Object.entries(sharedSingletons)) {
6959
6733
  try {
6960
- const scopeShare = Array.isArray(${JSON.stringify(options.shareScope)}) ? (shared?.[scopeName] || {}) : shared;
6961
- initRes.initShareScopeMap(scopeName, scopeShare);
6962
- await Promise.all(
6963
- await initRes.initializeSharing(scopeName, {
6964
- strategy: ${JSON.stringify(options.shareStrategy ?? "version-first")},
6965
- from: 'build',
6966
- initScope,
6967
- })
6968
- );
6734
+ if (shareInfo.scope !== scopeName) continue;
6735
+ if (!scopeShare[pkg]) continue;
6736
+ const factory = await initRes.loadShare(pkg, {
6737
+ customShareInfo: { ...shareInfo, scope: [scopeName] },
6738
+ });
6739
+ if (typeof factory !== 'function') {
6740
+ throw new Error('No compatible host provider was selected');
6741
+ }
6742
+ const module = await factory();
6743
+ cacheEntries.push({ scopeName, pkg, module });
6969
6744
  } catch (e) {
6970
- console.error('[Module Federation SSR]', e);
6745
+ shareInitErrors.push({ scopeName, pkg, error: e });
6971
6746
  }
6972
6747
  }
6973
- } catch (e) {
6974
- console.error('[Module Federation SSR]', e);
6748
+ }
6749
+ if (shareInitErrors.length > 0) {
6750
+ throw createShareInitError(shareInitErrors);
6751
+ }
6752
+ if (cacheEntries.length > 0) {
6753
+ const moduleCache = (globalThis.__mf_module_cache__ ||= { share: {}, remote: {} });
6754
+ const cache = (moduleCache.share ||= {});
6755
+ for (const { scopeName, pkg, module } of cacheEntries) {
6756
+ cache[scopeName + ':' + pkg] ??= module;
6757
+ if (scopeName === 'default') cache[pkg] ??= module;
6758
+ }
6975
6759
  }
6976
6760
  return initRes;
6977
6761
  }
@@ -6987,318 +6771,6 @@ function generateRemoteEntrySSR(options) {
6987
6771
  `;
6988
6772
  }
6989
6773
  //#endregion
6990
- //#region src/plugins/pluginDts.ts
6991
- var pluginDts_exports = /* @__PURE__ */ __exportAll({
6992
- DEFAULT_PUBLIC_TYPES_FOLDER: () => DEFAULT_PUBLIC_TYPES_FOLDER,
6993
- createDevDtsAssetMiddleware: () => createDevDtsAssetMiddleware,
6994
- default: () => pluginDts,
6995
- getDevDtsAssetPaths: () => getDevDtsAssetPaths,
6996
- resolveDtsPluginOptions: () => resolveDtsPluginOptions
6997
- });
6998
- const DEFAULT_DEV_OPTIONS = {
6999
- disableLiveReload: true,
7000
- disableHotTypesReload: false,
7001
- disableDynamicRemoteTypeHints: false
7002
- };
7003
- const DYNAMIC_HINTS_PLUGIN = "@module-federation/dts-plugin/dynamic-remote-type-hints-plugin";
7004
- const getIPv4 = () => process.env["FEDERATION_IPV4"] || "127.0.0.1";
7005
- const DEV_TYPES_FOLDER = ".dev-server";
7006
- const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
7007
- const forkDevWorkerPath = (() => {
7008
- return resolveImportPath("@module-federation/dts-plugin/dist/fork-dev-worker.js");
7009
- })();
7010
- var DevWorker = class {
7011
- worker = rpc.createRpcWorker(forkDevWorkerPath, {}, void 0, false);
7012
- constructor(options) {
7013
- this.worker.connect(options);
7014
- }
7015
- update() {
7016
- this.worker.process?.send?.({
7017
- type: rpc.RpcGMCallTypes.CALL,
7018
- id: this.worker.id,
7019
- args: [void 0, "update"]
7020
- });
7021
- }
7022
- exit() {
7023
- this.worker.terminate();
7024
- }
7025
- };
7026
- const normalizeDevOptions = (dev) => {
7027
- if (dev === false) return false;
7028
- if (dev === true || typeof dev === "undefined") return { ...DEFAULT_DEV_OPTIONS };
7029
- return {
7030
- ...DEFAULT_DEV_OPTIONS,
7031
- ...dev
7032
- };
7033
- };
7034
- const buildDtsModuleFederationConfig = (options) => {
7035
- const exposes = {};
7036
- Object.entries(options.exposes).forEach(([key, value]) => {
7037
- if (value.import) exposes[key] = value.import;
7038
- });
7039
- const remotes = {};
7040
- Object.entries(options.remotes).forEach(([key, remote]) => {
7041
- if (!remote.entry) return;
7042
- const entryGlobalName = remote.entryGlobalName?.startsWith("http") || remote.entryGlobalName?.includes(".json") ? remote.name || key : remote.entryGlobalName || remote.name || key;
7043
- remotes[key] = `${entryGlobalName}@${remote.entry}`;
7044
- });
7045
- return {
7046
- ...options,
7047
- exposes,
7048
- remotes
7049
- };
7050
- };
7051
- const resolveOutputDir = (config) => {
7052
- const { outDir } = config.build;
7053
- if (path$1.isAbsolute(outDir)) return normalizePathForImport(path$1.relative(config.root, outDir));
7054
- return outDir;
7055
- };
7056
- const ensureRuntimePlugin = (options, pluginId) => {
7057
- if (!options.runtimePlugins.some((plugin) => {
7058
- if (typeof plugin === "string") return plugin === pluginId;
7059
- return plugin[0] === pluginId;
7060
- })) options.runtimePlugins.push(pluginId);
7061
- };
7062
- const getExposeImportPaths = (options) => {
7063
- return Object.values(options.exposes).map((value) => {
7064
- return value.import;
7065
- }).filter((value) => Boolean(value));
7066
- };
7067
- const usesVueSfcExposes = (options) => {
7068
- return getExposeImportPaths(options).some((value) => value.endsWith(".vue"));
7069
- };
7070
- const resolveDtsPluginOptions = (dts, options, context) => {
7071
- if (dts === false) return false;
7072
- const inferredGenerateTypesDefaults = { generateAPITypes: true };
7073
- if (usesVueSfcExposes(options) && hasPackageDependency("vue-tsc", context)) inferredGenerateTypesDefaults.compilerInstance = "vue-tsc";
7074
- if (dts === true || typeof dts === "undefined") return { generateTypes: inferredGenerateTypesDefaults };
7075
- const generateTypes = dts.generateTypes;
7076
- return {
7077
- ...dts,
7078
- generateTypes: generateTypes === false ? false : {
7079
- ...inferredGenerateTypesDefaults,
7080
- ...generateTypes === true || typeof generateTypes === "undefined" ? {} : generateTypes
7081
- }
7082
- };
7083
- };
7084
- const getBasePath = (base) => {
7085
- if (base.startsWith("http://") || base.startsWith("https://")) return new URL(base).pathname.replace(/\/$/, "") || "/";
7086
- return base.replace(/\/$/, "") || "/";
7087
- };
7088
- const joinBaseAndAsset = (base, assetFileName) => {
7089
- const basePath = getBasePath(base);
7090
- return `${basePath === "/" ? "" : basePath}/${assetFileName}`.replace(/\/{2,}/g, "/");
7091
- };
7092
- const getDevDtsAssetPaths = (options) => {
7093
- const { outputDir, publicTypesFolder, root, base } = options;
7094
- return {
7095
- apiFilePath: path$1.resolve(root, outputDir, `${DEV_TYPES_FOLDER}.d.ts`),
7096
- apiRequestPath: joinBaseAndAsset(base, `${publicTypesFolder}.d.ts`),
7097
- zipFilePath: path$1.resolve(root, outputDir, `${DEV_TYPES_FOLDER}.zip`),
7098
- zipRequestPath: joinBaseAndAsset(base, `${publicTypesFolder}.zip`)
7099
- };
7100
- };
7101
- const createDevDtsAssetMiddleware = (assetPaths) => {
7102
- return (req, res, next) => {
7103
- const requestPath = req.url?.split("?")[0];
7104
- const isZipRequest = requestPath === assetPaths.zipRequestPath;
7105
- const isApiRequest = requestPath === assetPaths.apiRequestPath;
7106
- if (!isZipRequest && !isApiRequest) {
7107
- next();
7108
- return;
7109
- }
7110
- const filePath = isZipRequest ? assetPaths.zipFilePath : assetPaths.apiFilePath;
7111
- if (!fs.existsSync(filePath)) {
7112
- res.statusCode = 404;
7113
- res.end();
7114
- return;
7115
- }
7116
- res.statusCode = 200;
7117
- res.setHeader("Content-Type", isZipRequest ? "application/x-gzip" : "application/typescript");
7118
- if (req.method === "HEAD") {
7119
- res.end();
7120
- return;
7121
- }
7122
- const stream = fs.createReadStream(filePath);
7123
- stream.on("error", () => {
7124
- if (!res.headersSent) res.statusCode = 500;
7125
- res.end();
7126
- });
7127
- res.on("close", () => {
7128
- stream.destroy();
7129
- });
7130
- stream.pipe(res);
7131
- };
7132
- };
7133
- const normalizeDevDtsOptions = (dts, context) => {
7134
- return normalizeOptions(isTSProject(dts, context), {
7135
- generateTypes: { compileInChildProcess: true },
7136
- consumeTypes: { consumeAPITypes: true },
7137
- extraOptions: {},
7138
- displayErrorInTerminal: typeof dts === "object" && dts ? dts.displayErrorInTerminal : void 0
7139
- }, "mfOptions.dts")(dts);
7140
- };
7141
- const logDtsError = (error, dtsOptions) => {
7142
- if (dtsOptions === false) return;
7143
- if (typeof dtsOptions === "object" && dtsOptions && dtsOptions.displayErrorInTerminal === false) return;
7144
- mfError(error);
7145
- };
7146
- function pluginDts(options) {
7147
- if (options.dts === false) return [];
7148
- const baseDtsModuleFederationConfig = buildDtsModuleFederationConfig(options);
7149
- const getDtsModuleFederationConfig = (context) => ({
7150
- ...baseDtsModuleFederationConfig,
7151
- dts: resolveDtsPluginOptions(options.dts, options, context)
7152
- });
7153
- let resolvedConfig;
7154
- let devWorker;
7155
- let normalizedDevOptions;
7156
- let hasGeneratedBundle = false;
7157
- return [{
7158
- name: "module-federation-dts-dev",
7159
- apply: "serve",
7160
- config(config) {
7161
- normalizedDevOptions = normalizeDevOptions(options.dev);
7162
- if (!normalizedDevOptions) return;
7163
- if (normalizedDevOptions.disableDynamicRemoteTypeHints) return;
7164
- ensureRuntimePlugin(options, DYNAMIC_HINTS_PLUGIN);
7165
- const define = config.define ? { ...config.define } : {};
7166
- if (!("FEDERATION_IPV4" in define)) define.FEDERATION_IPV4 = JSON.stringify(getIPv4());
7167
- config.define = define;
7168
- },
7169
- configResolved(config) {
7170
- resolvedConfig = config;
7171
- },
7172
- configureServer(server) {
7173
- if (!normalizedDevOptions || !resolvedConfig) return;
7174
- const devOptions = normalizedDevOptions;
7175
- if (devOptions.disableDynamicRemoteTypeHints && devOptions.disableHotTypesReload && devOptions.disableLiveReload) return;
7176
- if (!options.name) throw createModuleFederationError("name is required if you want to enable dev server!");
7177
- const outputDir = resolveOutputDir(resolvedConfig);
7178
- const dtsModuleFederationConfig = getDtsModuleFederationConfig(resolvedConfig.root);
7179
- const normalizedDtsOptions = normalizeDevDtsOptions(dtsModuleFederationConfig.dts, resolvedConfig.root);
7180
- if (typeof normalizedDtsOptions !== "object") return;
7181
- const normalizedGenerateTypes = normalizeOptions(Boolean(normalizedDtsOptions), { compileInChildProcess: true }, "mfOptions.dts.generateTypes")(normalizedDtsOptions.generateTypes);
7182
- const remote = normalizedGenerateTypes === false ? void 0 : {
7183
- implementation: normalizedDtsOptions.implementation,
7184
- context: resolvedConfig.root,
7185
- outputDir,
7186
- moduleFederationConfig: { ...dtsModuleFederationConfig },
7187
- hostRemoteTypesFolder: normalizedGenerateTypes.typesFolder || "@mf-types",
7188
- ...normalizedGenerateTypes,
7189
- typesFolder: DEV_TYPES_FOLDER
7190
- };
7191
- if (remote) server.middlewares.use(createDevDtsAssetMiddleware(getDevDtsAssetPaths({
7192
- outputDir,
7193
- publicTypesFolder: remote.hostRemoteTypesFolder || "@mf-types",
7194
- root: resolvedConfig.root,
7195
- base: resolvedConfig.base
7196
- })));
7197
- if (remote && !remote.tsConfigPath && normalizedDtsOptions.tsConfigPath) remote.tsConfigPath = normalizedDtsOptions.tsConfigPath;
7198
- const normalizedConsumeTypes = normalizeOptions(Boolean(normalizedDtsOptions), { consumeAPITypes: true }, "mfOptions.dts.consumeTypes")(normalizedDtsOptions.consumeTypes);
7199
- const host = normalizedConsumeTypes === false ? void 0 : {
7200
- implementation: normalizedDtsOptions.implementation,
7201
- context: resolvedConfig.root,
7202
- moduleFederationConfig: dtsModuleFederationConfig,
7203
- typesFolder: normalizedConsumeTypes.typesFolder || "@mf-types",
7204
- abortOnError: false,
7205
- ...normalizedConsumeTypes
7206
- };
7207
- const extraOptions = normalizedDtsOptions.extraOptions || {};
7208
- if (!remote && !host && devOptions.disableLiveReload) return;
7209
- const startDevWorker = async () => {
7210
- let remoteTypeUrls;
7211
- if (host) remoteTypeUrls = await new Promise((resolve) => {
7212
- consumeTypesAPI({
7213
- host,
7214
- extraOptions,
7215
- displayErrorInTerminal: normalizedDtsOptions.displayErrorInTerminal
7216
- }, resolve);
7217
- });
7218
- devWorker = new DevWorker({
7219
- name: options.name,
7220
- remote,
7221
- host: host ? {
7222
- ...host,
7223
- remoteTypeUrls
7224
- } : void 0,
7225
- extraOptions,
7226
- disableLiveReload: devOptions.disableLiveReload,
7227
- disableHotTypesReload: devOptions.disableHotTypesReload
7228
- });
7229
- const update = () => devWorker?.update();
7230
- server.watcher.on("change", update);
7231
- server.watcher.on("add", update);
7232
- server.watcher.on("unlink", update);
7233
- server.httpServer?.once("close", () => {
7234
- devWorker?.exit();
7235
- server.watcher.off("change", update);
7236
- server.watcher.off("add", update);
7237
- server.watcher.off("unlink", update);
7238
- });
7239
- };
7240
- startDevWorker().catch((error) => {
7241
- logDtsError(error, normalizedDtsOptions);
7242
- });
7243
- }
7244
- }, {
7245
- name: "module-federation-dts-build",
7246
- apply: "build",
7247
- configResolved(config) {
7248
- resolvedConfig = config;
7249
- },
7250
- async generateBundle() {
7251
- if (hasGeneratedBundle) return;
7252
- hasGeneratedBundle = true;
7253
- if (!resolvedConfig) return;
7254
- let normalizedDtsOptions;
7255
- try {
7256
- normalizedDtsOptions = normalizeDtsOptions(getDtsModuleFederationConfig(resolvedConfig.root), resolvedConfig.root);
7257
- } catch (error) {
7258
- logDtsError(error, options.dts);
7259
- return;
7260
- }
7261
- if (typeof normalizedDtsOptions !== "object") return;
7262
- const context = resolvedConfig.root;
7263
- const outputDir = resolveOutputDir(resolvedConfig);
7264
- let consumeOptions;
7265
- try {
7266
- consumeOptions = normalizeConsumeTypesOptions({
7267
- context,
7268
- dtsOptions: normalizedDtsOptions,
7269
- pluginOptions: getDtsModuleFederationConfig(resolvedConfig.root)
7270
- });
7271
- } catch (error) {
7272
- logDtsError(error, normalizedDtsOptions);
7273
- return;
7274
- }
7275
- if (consumeOptions?.host?.typesOnBuild) try {
7276
- await consumeTypesAPI(consumeOptions);
7277
- } catch (error) {
7278
- logDtsError(error, normalizedDtsOptions);
7279
- }
7280
- let generateOptions;
7281
- try {
7282
- generateOptions = normalizeGenerateTypesOptions({
7283
- context,
7284
- outputDir,
7285
- dtsOptions: normalizedDtsOptions,
7286
- pluginOptions: getDtsModuleFederationConfig(resolvedConfig.root)
7287
- });
7288
- } catch (error) {
7289
- logDtsError(error, normalizedDtsOptions);
7290
- return;
7291
- }
7292
- if (!generateOptions) return;
7293
- try {
7294
- await generateTypesAPI({ dtsManagerOptions: generateOptions });
7295
- } catch (error) {
7296
- logDtsError(error, normalizedDtsOptions);
7297
- }
7298
- }
7299
- }];
7300
- }
7301
- //#endregion
7302
6774
  //#region src/plugins/pluginMFManifest.ts
7303
6775
  /**
7304
6776
  * Resolves the build version for the module federation manifest.
@@ -8225,12 +7697,15 @@ function getSharedKeyMatcher(shared) {
8225
7697
  let vueKey;
8226
7698
  for (const key of keys) {
8227
7699
  const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
7700
+ const shareItem = shared[key];
8228
7701
  if (!vueKey && keyBase === "vue") vueKey = key;
8229
7702
  if (key.endsWith("/")) wildcardKeys.push({
8230
7703
  key,
8231
7704
  base: keyBase
8232
7705
  });
8233
- for (const subpath of getCommonSharedSubpaths(keyBase)) if (!commonSubpathKeys.has(subpath)) commonSubpathKeys.set(subpath, key);
7706
+ if (shareItem.shareConfig?.import !== false) {
7707
+ for (const subpath of getCommonSharedSubpaths(keyBase)) if (!commonSubpathKeys.has(subpath)) commonSubpathKeys.set(subpath, key);
7708
+ }
8234
7709
  }
8235
7710
  const sourceCache = /* @__PURE__ */ new Map();
8236
7711
  const matcher = { find(source) {
@@ -8386,15 +7861,16 @@ function proxySharedModule(options) {
8386
7861
  configResolved(config) {
8387
7862
  _config = config;
8388
7863
  const isRolldown = getIsRolldown(this);
7864
+ const registerConfiguredShare = _command === "serve" ? addConfiguredShare : addUsedShares;
8389
7865
  Object.keys(shared).forEach((key) => {
8390
7866
  if (key.endsWith("/")) return;
8391
7867
  if (useDirectReactImport && key === "react") {
8392
- addUsedShares(key, federationOptions);
7868
+ registerConfiguredShare(key, federationOptions);
8393
7869
  return;
8394
7870
  }
8395
7871
  writeLoadShareModule(key, shared[key], _command, isRolldown, federationOptions);
8396
7872
  if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key], federationOptions);
8397
- addUsedShares(key, federationOptions);
7873
+ registerConfiguredShare(key, federationOptions);
8398
7874
  });
8399
7875
  writeLocalSharedImportMap(federationOptions);
8400
7876
  refreshHostAutoInit(federationOptions);
@@ -8841,7 +8317,7 @@ function getRealPathIfExists(filePath) {
8841
8317
  return;
8842
8318
  }
8843
8319
  }
8844
- function isPathWithinDirectory(filePath, directory) {
8320
+ function isCanonicalPathWithinDirectory(filePath, directory) {
8845
8321
  const realFilePath = getRealPathIfExists(filePath) ?? path$1.resolve(filePath);
8846
8322
  const realDirectory = getRealPathIfExists(directory) ?? path$1.resolve(directory);
8847
8323
  const relative = path$1.relative(realDirectory, realFilePath);
@@ -8851,7 +8327,7 @@ function getRunnerAllowedDirectories(config) {
8851
8327
  return [config.root, ...config.server?.fs?.allow ?? []].map((directory) => path$1.resolve(directory));
8852
8328
  }
8853
8329
  function isPathWithinAllowedDirectories(filePath, allowedDirectories) {
8854
- return allowedDirectories.some((directory) => isPathWithinDirectory(filePath, directory));
8330
+ return allowedDirectories.some((directory) => isCanonicalPathWithinDirectory(filePath, directory));
8855
8331
  }
8856
8332
  function isSafeRunnerFetchModuleId(id, config) {
8857
8333
  if (typeof id !== "string" || !id) return false;
@@ -9006,7 +8482,7 @@ function pluginSSRRemoteEntry(options) {
9006
8482
  },
9007
8483
  configureServer(server) {
9008
8484
  const base = "/__mf_ssr__";
9009
- const basePath = getBasePath$2(viteConfig?.base);
8485
+ const basePath = getBasePath$1(viteConfig?.base);
9010
8486
  const ssrEntryFileName = getSsrRemoteEntryFileName(options.filename);
9011
8487
  if (isNuxtProject || isNuxtClientBase(basePath)) server.middlewares.use((req, _res, next) => {
9012
8488
  if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
@@ -9061,7 +8537,7 @@ function pluginSSRRemoteEntry(options) {
9061
8537
  const ssrPath = `${base}/${ssrEntryFileName}`;
9062
8538
  server.middlewares.use(ssrPath, (_req, res) => {
9063
8539
  const exposesUrl = `${base}/${options.filename.replace(/\.[^.]+$/, "")}.exposes.js`;
9064
- const code = generateRemoteEntrySSR(options).replace(JSON.stringify(virtualExposesSSRId), JSON.stringify(exposesUrl));
8540
+ const code = getSsrRemoteEntrySource().replace(JSON.stringify(virtualExposesSSRId), JSON.stringify(exposesUrl));
9065
8541
  res.setHeader("Content-Type", "application/javascript");
9066
8542
  res.setHeader("Access-Control-Allow-Origin", "*");
9067
8543
  res.end(code);
@@ -9080,7 +8556,7 @@ function pluginSSRRemoteEntry(options) {
9080
8556
  if (id === `/__mf_ssr__/${options.filename.replace(/\.[^.]+$/, "")}.exposes.js`) return virtualExposesSSRId;
9081
8557
  },
9082
8558
  load(id) {
9083
- if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return generateRemoteEntrySSR(options);
8559
+ if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return getSsrRemoteEntrySource();
9084
8560
  if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return generateExposesSSR(options, reactIslandExposes);
9085
8561
  },
9086
8562
  buildStart() {
@@ -9112,9 +8588,6 @@ function pluginSSRRemoteEntry(options) {
9112
8588
  });
9113
8589
  }
9114
8590
  if (this.environment?.name === "ssr") ssrOutputFiles = collectEntryOutputFiles(bundle, ssrOutputFilename);
9115
- if (!isRolldown) return;
9116
- const chunk = bundle[ssrOutputFilename];
9117
- if (!chunk || chunk.type !== "chunk") return;
9118
8591
  }
9119
8592
  },
9120
8593
  writeBundle(outputOptions) {
@@ -9134,7 +8607,7 @@ function pluginSSRRemoteEntry(options) {
9134
8607
  for (const fileName of ssrOutputFiles) {
9135
8608
  const source = path$1.resolve(ssrDir, fileName);
9136
8609
  const destination = path$1.resolve(clientDir, fileName);
9137
- if (!isWithinDirectory(source, ssrDir) || !isWithinDirectory(destination, clientDir)) continue;
8610
+ if (!isResolvedPathWithinDirectory(source, ssrDir) || !isResolvedPathWithinDirectory(destination, clientDir)) continue;
9138
8611
  if (!fs$1.existsSync(source) || fs$1.existsSync(destination)) continue;
9139
8612
  fs$1.mkdirSync(path$1.dirname(destination), { recursive: true });
9140
8613
  fs$1.copyFileSync(source, destination);
@@ -9165,7 +8638,7 @@ function collectEntryOutputFiles(bundle, entryFileName) {
9165
8638
  visit(entryFileName);
9166
8639
  return files;
9167
8640
  }
9168
- function isWithinDirectory(filePath, directory) {
8641
+ function isResolvedPathWithinDirectory(filePath, directory) {
9169
8642
  const relative = path$1.relative(directory, filePath);
9170
8643
  return relative !== "" && !relative.startsWith(`..${path$1.sep}`) && relative !== "..";
9171
8644
  }
@@ -9625,6 +9098,74 @@ function includeLinkedSharedEntries(optimizeDeps, shared, projectRoot, exposes,
9625
9098
  for (const entry of additions) entries.add(entry);
9626
9099
  optimizeDeps.entries = [...entries];
9627
9100
  }
9101
+ function stabilizeOptimizeDeps(optimizeDeps) {
9102
+ optimizeDeps.include = [...new Set(optimizeDeps.include ?? [])].sort();
9103
+ optimizeDeps.exclude = [...new Set(optimizeDeps.exclude ?? [])].sort();
9104
+ }
9105
+ function isFile(candidate) {
9106
+ try {
9107
+ return statSync(candidate).isFile();
9108
+ } catch {
9109
+ return false;
9110
+ }
9111
+ }
9112
+ function registerEntryImports(options, projectRoot) {
9113
+ const staticImport = /\b(?:import|export)\s+(?:type\s+)?(?:[^'";]*?\s+from\s*)?(['"])([^'"]+)\1/g;
9114
+ const dynamicImport = /\b(?:import|require)\s*\(\s*(['"])([^'"]+)\1/g;
9115
+ const sourceExtensions = [
9116
+ ".mjs",
9117
+ ".js",
9118
+ ".mts",
9119
+ ".ts",
9120
+ ".jsx",
9121
+ ".tsx",
9122
+ ".vue",
9123
+ ".svelte"
9124
+ ];
9125
+ const root = path$1.resolve(projectRoot);
9126
+ const pending = [];
9127
+ const visited = /* @__PURE__ */ new Map();
9128
+ const enqueue = (request, importer = path$1.join(root, "index.html"), preloadRemotes = false) => {
9129
+ const cleanRequest = request.replace(/[?#].*$/, "");
9130
+ if (!cleanRequest.startsWith(".") && !cleanRequest.startsWith("/") && !path$1.isAbsolute(cleanRequest)) return;
9131
+ const base = cleanRequest.startsWith("/") ? path$1.resolve(root, `.${cleanRequest}`) : path$1.resolve(path$1.dirname(importer), cleanRequest);
9132
+ const relative = path$1.relative(root, base);
9133
+ if (relative.startsWith(`..${path$1.sep}`) || path$1.isAbsolute(relative)) return;
9134
+ const file = [
9135
+ base,
9136
+ ...sourceExtensions.map((extension) => `${base}${extension}`),
9137
+ ...sourceExtensions.map((extension) => path$1.join(base, `index${extension}`))
9138
+ ].find(isFile);
9139
+ if (file && (!visited.has(file) || preloadRemotes && !visited.get(file))) pending.push({
9140
+ file,
9141
+ preloadRemotes
9142
+ });
9143
+ };
9144
+ const htmlEntry = path$1.join(root, "index.html");
9145
+ if (existsSync(htmlEntry)) {
9146
+ const html = readFileSync(htmlEntry, "utf8");
9147
+ for (const match of html.matchAll(/<script\b[^>]*\bsrc=(['"])([^'"]+)\1[^>]*>/gi)) enqueue(match[2], htmlEntry, true);
9148
+ }
9149
+ for (const expose of Object.values(options.exposes ?? {})) enqueue(expose.import);
9150
+ while (pending.length) {
9151
+ const { file, preloadRemotes } = pending.pop();
9152
+ if (visited.get(file) || visited.has(file) && !preloadRemotes) continue;
9153
+ visited.set(file, preloadRemotes);
9154
+ const code = readFileSync(file, "utf8");
9155
+ for (const pattern of [staticImport, dynamicImport]) {
9156
+ const isStatic = pattern === staticImport;
9157
+ pattern.lastIndex = 0;
9158
+ for (const match of code.matchAll(pattern)) {
9159
+ const request = match[2];
9160
+ const remoteKey = preloadRemotes && isStatic && request ? Object.keys(options.remotes).find((name) => request === name || request.startsWith(`${name}/`)) : void 0;
9161
+ const sharedKey = request && findSharedKey(request, options.shared);
9162
+ if (remoteKey) addUsedRemote(remoteKey, request, options);
9163
+ else if (sharedKey) addUsedShares(request, options);
9164
+ else if (request) enqueue(request, file, preloadRemotes && isStatic);
9165
+ }
9166
+ }
9167
+ }
9168
+ }
9628
9169
  /**
9629
9170
  * Plugin that runs FIRST to register generated virtual modules in the config hook.
9630
9171
  * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
@@ -9639,6 +9180,7 @@ function createEarlyVirtualModulesPlugin(options) {
9639
9180
  config(config, { command: _command }) {
9640
9181
  if (_command === "serve") ignoreFederationGeneratedFiles(config, options);
9641
9182
  const root = config.root || process.cwd();
9183
+ resetConcreteSharedImportSourceCache();
9642
9184
  setPackageDetectionCwd(root);
9643
9185
  const isVinext = hasPackageDependency("vinext");
9644
9186
  initVirtualModules(_command, getRemoteEntryId(options), false, options);
@@ -9652,8 +9194,10 @@ function createEarlyVirtualModulesPlugin(options) {
9652
9194
  config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
9653
9195
  }
9654
9196
  }
9197
+ if (_command === "serve" && (Object.keys(shared ?? {}).length > 0 || Object.keys(remotes ?? {}).length > 0)) registerEntryImports(options, root);
9655
9198
  if (shared && Object.keys(shared).length > 0) {
9656
9199
  if (_command === "serve") {
9200
+ excludeSharedSubDependencies(shared);
9657
9201
  config.optimizeDeps = config.optimizeDeps || {};
9658
9202
  config.optimizeDeps.include = config.optimizeDeps.include || [];
9659
9203
  const optimizeDeps = config.optimizeDeps;
@@ -9685,16 +9229,15 @@ function createEarlyVirtualModulesPlugin(options) {
9685
9229
  const isReactDomRequire = resolveOptions?.kind?.startsWith("require") && isReactDomSelfReference(source, importer);
9686
9230
  if (resolveOptions?.kind?.startsWith("require") && !isReactRequire && !isReactDomRequire) return;
9687
9231
  if (isCommonJsImporter(importer) && !isReactSingleton && !isReactDomRequire) return;
9232
+ if (resolveOptions?.kind !== "entry-point") addUsedShares(source, options);
9688
9233
  if (isReactRequire || isReactDomRequire) {
9689
9234
  writeLoadShareModule(source, shareItem, _command, isRolldown, options);
9690
9235
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
9691
- addUsedShares(source, options);
9692
9236
  return { id: `module-federation:optimized-require-${source}` };
9693
9237
  }
9694
9238
  const loadSharePath = getLoadShareModulePath(source, isRolldown, options);
9695
9239
  writeLoadShareModule(source, shareItem, _command, isRolldown, options);
9696
9240
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
9697
- addUsedShares(source, options);
9698
9241
  return {
9699
9242
  id: loadSharePath,
9700
9243
  external: true
@@ -9717,6 +9260,7 @@ function createEarlyVirtualModulesPlugin(options) {
9717
9260
  if (isSharedResolverInternalImporter(args.importer)) return;
9718
9261
  if (!findSharedKey(args.path, shared) || isAssetLikeImport(args.path)) return;
9719
9262
  if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path) && !isReactDomSelfReference(args.path, args.importer)) return;
9263
+ addUsedShares(args.path, options);
9720
9264
  return {
9721
9265
  path: args.path,
9722
9266
  namespace: "mf-shared"
@@ -9732,7 +9276,6 @@ function createEarlyVirtualModulesPlugin(options) {
9732
9276
  const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
9733
9277
  writeLoadShareModule(args.path, shareItem, _command, isRolldown, options);
9734
9278
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
9735
- addUsedShares(args.path, options);
9736
9279
  return {
9737
9280
  loader: "js",
9738
9281
  resolveDir: root,
@@ -9761,13 +9304,13 @@ export default __mfShared.default ?? __mfShared;`
9761
9304
  continue;
9762
9305
  }
9763
9306
  if (isVinext && key === "react") {
9764
- addUsedShares(key, options);
9307
+ addConfiguredShare(key, options);
9765
9308
  continue;
9766
9309
  }
9767
9310
  getLoadShareModulePath(key, isRolldown, options);
9768
9311
  writeLoadShareModule(key, shareItem, _command, isRolldown, options);
9769
9312
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(key, shareItem, options);
9770
- addUsedShares(key, options);
9313
+ addConfiguredShare(key, options);
9771
9314
  if (_command === "serve" && shareItem.shareConfig?.import !== false) {
9772
9315
  const optimizeDeps = config.optimizeDeps ??= {};
9773
9316
  optimizeDeps.include ??= [];
@@ -9785,7 +9328,7 @@ export default __mfShared.default ?? __mfShared;`
9785
9328
  getLoadShareModulePath(subpath, isRolldown, options);
9786
9329
  writeLoadShareModule(subpath, shareItem, _command, isRolldown, options);
9787
9330
  writePreBuildLibPath(subpath, shareItem, options);
9788
- addUsedShares(subpath, options);
9331
+ addConfiguredShare(subpath, options);
9789
9332
  if (canResolveSubpath) {
9790
9333
  optimizeDeps.include.push(subpath);
9791
9334
  if (key === "react-dom") optimizeDeps.include.push(`${key} > ${subpath}`);
@@ -9798,6 +9341,7 @@ export default __mfShared.default ?? __mfShared;`
9798
9341
  if (_command === "serve") {
9799
9342
  config.optimizeDeps ??= {};
9800
9343
  includeLinkedSharedEntries(config.optimizeDeps, shared, root, options.exposes, config.build?.outDir ?? "dist");
9344
+ stabilizeOptimizeDeps(config.optimizeDeps);
9801
9345
  }
9802
9346
  },
9803
9347
  configResolved(config) {
@@ -9827,7 +9371,7 @@ export default __mfShared.default ?? __mfShared;`
9827
9371
  resolvedShared[pkg] = resolveImportPath(pkg);
9828
9372
  } catch {}
9829
9373
  }
9830
- const ssrEntryLoaderSpecifier = "@module-federation/vite/ssrEntryLoader";
9374
+ const ssrEntryLoaderSpecifier = SSR_ENTRY_LOADER_SPECIFIER;
9831
9375
  try {
9832
9376
  resolveImportPath(ssrEntryLoaderSpecifier);
9833
9377
  options.runtimePlugins.push([ssrEntryLoaderSpecifier, { resolvedShared }]);
@@ -9835,7 +9379,6 @@ export default __mfShared.default ?? __mfShared;`
9835
9379
  }
9836
9380
  };
9837
9381
  }
9838
- const SSR_ONLY_PLUGINS = /* @__PURE__ */ new Set(["@module-federation/vite/ssrEntryLoader"]);
9839
9382
  function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaultDisableSnapshot }) {
9840
9383
  const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(target);
9841
9384
  if (!("ENV_TARGET" in define)) define.ENV_TARGET = envTargetDefineValue;
@@ -9847,7 +9390,7 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
9847
9390
  }
9848
9391
  function loadPluginDts(options) {
9849
9392
  if (options.dts === false) return [];
9850
- return [Promise.resolve().then(() => pluginDts_exports).then(({ default: pluginDts }) => pluginDts(options))];
9393
+ return [import("./pluginDts-BNCg4Gri.js").then(({ default: pluginDts }) => pluginDts(options))];
9851
9394
  }
9852
9395
  const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
9853
9396
  function isInjectExternalRuntimeCorePlugin(specifier) {
@@ -9888,7 +9431,7 @@ function federation(mfUserOptions) {
9888
9431
  const virtualExposesId = getVirtualExposesId(options);
9889
9432
  const moduleParseController = createModuleParseController();
9890
9433
  const moduleParsePlugins = pluginModuleParseEnd_default((id) => {
9891
- return id.includes(getHostAutoInitImportId(options)) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes("virtual:mf-localSharedImportMap") || id.includes("__loadShare__") || id.includes("__prebuild__") || id.includes("__treeShakingProvider__") || id.includes("__mf_tree_shaking_graph__");
9434
+ return id.includes(getHostAutoInitPath(options)) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes("virtual:mf-localSharedImportMap") || id.includes("__loadShare__") || id.includes("__prebuild__") || id.includes("__treeShakingProvider__") || id.includes("__mf_tree_shaking_graph__");
9892
9435
  }, {
9893
9436
  moduleParseTimeout: options.moduleParseTimeout,
9894
9437
  moduleParseIdleTimeout: options.moduleParseIdleTimeout,
@@ -10288,7 +9831,7 @@ function federation(mfUserOptions) {
10288
9831
  if (needsRuntimeHelpers) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
10289
9832
  options.runtimePlugins.forEach((p) => {
10290
9833
  const pluginPath = typeof p === "string" ? p : p[0];
10291
- if (SSR_ONLY_PLUGINS.has(pluginPath)) return;
9834
+ if (SSR_ONLY_RUNTIME_PLUGINS.has(pluginPath)) return;
10292
9835
  if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) {
10293
9836
  let optimizeDep = pluginPath;
10294
9837
  if (pluginPath === "@module-federation/dts-plugin/dynamic-remote-type-hints-plugin") try {