@module-federation/vite 1.21.1 → 1.21.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/lib/{dtsConstants-DyJrx8ah.js → dtsConstants-CScOzmdO.js} +11 -5
- package/lib/index.js +347 -76
- package/lib/{pathNormalization-DvgU8LIp.js → pathNormalization-CHct3UwV.js} +1 -5
- package/lib/{pluginDts-sJeW2nss.js → pluginDts-C2bUY8h9.js} +1 -1
- package/lib/{ssrEntryLoader-0NnTjWR1.js → ssrEntryLoader-BMtjS_Vl.js} +1 -1
- package/lib/{ssrVmStrategy-B0fCaHs5.js → ssrVmStrategy-tpI6we9Q.js} +2 -2
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ export default defineConfig({
|
|
|
167
167
|
name: "host",
|
|
168
168
|
remotes: {
|
|
169
169
|
remote: {
|
|
170
|
-
type: "module", // type "var"
|
|
170
|
+
type: "module", // omitted object type defaults to "var" with a warning
|
|
171
171
|
name: "remote",
|
|
172
172
|
entry: "https://[...]/remoteEntry.js",
|
|
173
173
|
entryGlobalName: "remote",
|
|
@@ -237,6 +237,7 @@ export default defineConfig({
|
|
|
237
237
|
```
|
|
238
238
|
|
|
239
239
|
The host app configuration specifies its name, the filename of its exposed remote entry remoteEntry.js, and importantly, the configuration of the remote application to load.
|
|
240
|
+
Object remotes that omit `type` retain the legacy `"var"` default and emit a warning. Use `type: "module"` for Vite ESM remotes. Use `type: "var"` explicitly only for global-format remotes, such as Webpack/Rspack remotes or a Vite remote's `varFilename` output.
|
|
240
241
|
You can specify the place the host initialization file is injected with the **hostInitInjectLocation** option, which is described in the example code above.
|
|
241
242
|
The **moduleParseTimeout** option allows you to configure the maximum time to wait for module parsing during the build process.
|
|
242
243
|
The **moduleParseIdleTimeout** option is an alternative that resets the timer on every parsed module. It only fires when there has been no module activity for the configured duration, making it suitable for large codebases where the total build time exceeds the fixed timeout.
|
|
@@ -303,6 +304,18 @@ federation({
|
|
|
303
304
|
|
|
304
305
|
`runtime-infer` is useful for local development and falls back to the full dependency when the required exports are not available. `server-calc` is recommended for deployments because it can use aggregated export metadata from all consumers.
|
|
305
306
|
|
|
307
|
+
Use `eager: true` when a shared dependency must provide exports during module evaluation. For example, icon libraries may call `jsx()` at module scope before deferred singleton initialization completes. Configure the remote's React share as follows; discovered React subpaths such as `react/jsx-runtime` inherit this setting:
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
federation({
|
|
311
|
+
shared: {
|
|
312
|
+
react: { singleton: true, eager: true },
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
This bundles the local fallback into the initial entry, so enable it only when synchronous evaluation requires it.
|
|
318
|
+
|
|
306
319
|
Do not combine `eager: true` with `treeShaking`; eager shared dependencies are bundled into the initial entry and cannot use the on-demand tree-shaking path. Choose eager loading for small dependencies, or tree shaking for larger dependencies such as component libraries.
|
|
307
320
|
|
|
308
321
|
With `server-calc`, the Vite build records the exports used by each application in its generated Module Federation metadata. A deployment service must then collect that metadata for all applications that share the same dependency and version, merge their `usedExports` lists, and use the resulting union to create one optimized secondary shared artifact. For example, if one application uses `Button` and another uses `Input`, the secondary artifact must contain both exports.
|
|
@@ -388,17 +388,22 @@ function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
|
|
|
388
388
|
}
|
|
389
389
|
let currentDir = path$1.dirname(resolvedPath);
|
|
390
390
|
const rootDir = path$1.parse(currentDir).root;
|
|
391
|
+
let matchingPackage;
|
|
391
392
|
while (true) {
|
|
392
393
|
const packageJsonPath = path$1.join(currentDir, "package.json");
|
|
393
394
|
if (existsSync(packageJsonPath)) {
|
|
394
395
|
const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
|
|
395
396
|
try {
|
|
396
397
|
const packageJson = JSON.parse(packageJsonContent);
|
|
397
|
-
if (packageJson.name === packageName)
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
398
|
+
if (packageJson.name === packageName) {
|
|
399
|
+
const packageInfo = {
|
|
400
|
+
path: packageJsonPath,
|
|
401
|
+
dir: currentDir,
|
|
402
|
+
packageJson
|
|
403
|
+
};
|
|
404
|
+
if (currentDir.endsWith(path$1.join("node_modules", packageName))) return packageInfo;
|
|
405
|
+
matchingPackage ??= packageInfo;
|
|
406
|
+
}
|
|
402
407
|
} catch (error) {
|
|
403
408
|
if (!(error instanceof SyntaxError)) throw error;
|
|
404
409
|
}
|
|
@@ -406,6 +411,7 @@ function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
|
|
|
406
411
|
if (currentDir === rootDir) break;
|
|
407
412
|
currentDir = path$1.dirname(currentDir);
|
|
408
413
|
}
|
|
414
|
+
return matchingPackage;
|
|
409
415
|
} catch {
|
|
410
416
|
let currentDir = cwd;
|
|
411
417
|
const rootDir = path$1.parse(currentDir).root;
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as normalizePathForImport, r as rebaseImport } from "./buildPaths-BkaQHrd2.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-
|
|
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-
|
|
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-CScOzmdO.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-CHct3UwV.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as fs$2 from "fs";
|
|
6
6
|
import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -502,64 +502,119 @@ function createCodePositionMap(code) {
|
|
|
502
502
|
}
|
|
503
503
|
//#endregion
|
|
504
504
|
//#region src/utils/htmlEntryUtils.ts
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
505
|
+
const IDENTIFIER = String.raw`[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*`;
|
|
506
|
+
const NAMED_SPECIFIERS = String.raw`\{[^{}]*\}`;
|
|
507
|
+
const NAMESPACE_SPECIFIER = String.raw`\*\s*as\s+${IDENTIFIER}`;
|
|
508
|
+
const IMPORT_CLAUSE = String.raw`(?:(?<importType>type)\s+)?(?<importClause>${NAMESPACE_SPECIFIER}|${NAMED_SPECIFIERS}|${IDENTIFIER}(?:\s*,\s*(?:${NAMESPACE_SPECIFIER}|${NAMED_SPECIFIERS}))?)`;
|
|
509
|
+
const EXPORT_CLAUSE = String.raw`(?:(?<exportType>type)\s+)?(?<exportClause>\*(?:\s*as\s+(?:${IDENTIFIER}|"[^"]*"|'[^']*'))?|${NAMED_SPECIFIERS})`;
|
|
510
|
+
const SPECIFIER = String.raw`(?<quote>["'])(?<source>[^"'\r\n]*)\k<quote>`;
|
|
511
|
+
const KEYWORD_BOUNDARY = String.raw`(?<![.$\w])`;
|
|
512
|
+
const KEYWORD_GAP = String.raw`(?:\s+|(?=[{*]))`;
|
|
513
|
+
const STATIC_PATTERN = new RegExp(String.raw`${KEYWORD_BOUNDARY}(?:import${KEYWORD_GAP}${IMPORT_CLAUSE}|export${KEYWORD_GAP}${EXPORT_CLAUSE})\s*from\s*${SPECIFIER}`, "gud");
|
|
514
|
+
const DYNAMIC_PATTERN = new RegExp(String.raw`${KEYWORD_BOUNDARY}import\s*\(\s*${SPECIFIER}`, "gud");
|
|
515
|
+
const REQUIRE_PATTERN = new RegExp(String.raw`${KEYWORD_BOUNDARY}require\s*\(\s*${SPECIFIER}\s*\)`, "gud");
|
|
516
|
+
const SIDE_EFFECT_PATTERN = new RegExp(String.raw`${KEYWORD_BOUNDARY}import\s*${SPECIFIER}`, "gud");
|
|
517
|
+
/**
|
|
518
|
+
* Returns `code` with every non-code region blanked out to spaces so that
|
|
519
|
+
* regexes can run against real syntax only. String literals keep their
|
|
520
|
+
* delimiters (with a blank interior) so import specifiers stay locatable;
|
|
521
|
+
* comments, template literals, and regular expressions vanish entirely.
|
|
522
|
+
* The result has the same length as `code`, so match indices map back 1:1.
|
|
523
|
+
*/
|
|
524
|
+
function blankNonCode(code) {
|
|
525
|
+
const codePositions = createCodePositionMap(code);
|
|
526
|
+
const chars = code.split("");
|
|
527
|
+
let index = 0;
|
|
528
|
+
while (index < code.length) {
|
|
529
|
+
if (codePositions[index]) {
|
|
530
|
+
index++;
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const start = index;
|
|
534
|
+
while (index < code.length && !codePositions[index]) index++;
|
|
535
|
+
const quote = code[start];
|
|
536
|
+
const isString = (quote === "\"" || quote === "'") && index - start >= 2 && code[index - 1] === quote;
|
|
537
|
+
for (let position = start; position < index; position++) chars[position] = isString && (position === start || position === index - 1) ? quote : code[position] === "\n" ? "\n" : " ";
|
|
538
|
+
}
|
|
539
|
+
return chars.join("");
|
|
540
|
+
}
|
|
541
|
+
function isTypeOnlyNamedClause(clause) {
|
|
542
|
+
const namedSpecifiers = clause.trim().match(/^\{([\s\S]*)\}$/)?.[1];
|
|
543
|
+
if (namedSpecifiers === void 0) return false;
|
|
510
544
|
const specifiers = namedSpecifiers.split(",").map((specifier) => specifier.trim()).filter(Boolean);
|
|
511
|
-
return specifiers.length > 0 && specifiers.every((specifier) => /^type\s
|
|
545
|
+
return specifiers.length > 0 && specifiers.every((specifier) => /^type\s+(?!as(?:\s|$))\S/.test(specifier));
|
|
546
|
+
}
|
|
547
|
+
function readSource(code, match) {
|
|
548
|
+
const range = match.indices?.groups?.source;
|
|
549
|
+
if (!range) return void 0;
|
|
550
|
+
const source = code.slice(range[0], range[1]);
|
|
551
|
+
return source.length > 0 ? source : void 0;
|
|
512
552
|
}
|
|
513
553
|
/**
|
|
514
554
|
* Finds module imports while ignoring comments, strings, and regular expressions.
|
|
515
555
|
* The descriptor keeps enough information for callers to distinguish runtime
|
|
516
556
|
* static imports from type-only imports without introducing a parser dependency.
|
|
557
|
+
*
|
|
558
|
+
* Matching runs against a blanked copy of the code (see `blankNonCode`), so an
|
|
559
|
+
* `import` inside a comment or string can never match, comments inside a
|
|
560
|
+
* statement never change its classification, and a clause can never span
|
|
561
|
+
* multiple statements.
|
|
517
562
|
*/
|
|
518
563
|
function findModuleImportDescriptors(code) {
|
|
519
|
-
const
|
|
564
|
+
const blanked = blankNonCode(code);
|
|
520
565
|
const descriptors = [];
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if (!codePositions[match.index]) continue;
|
|
566
|
+
for (const match of blanked.matchAll(STATIC_PATTERN)) {
|
|
567
|
+
const source = readSource(code, match);
|
|
568
|
+
if (!source) continue;
|
|
569
|
+
const groups = match.groups;
|
|
570
|
+
const typeOnly = groups.importType !== void 0 || groups.exportType !== void 0 || isTypeOnlyNamedClause(groups.importClause ?? groups.exportClause ?? "");
|
|
527
571
|
descriptors.push({
|
|
528
572
|
kind: "static",
|
|
529
573
|
syntax: "import",
|
|
530
|
-
source
|
|
531
|
-
typeOnly
|
|
574
|
+
source,
|
|
575
|
+
typeOnly
|
|
532
576
|
});
|
|
533
577
|
}
|
|
534
|
-
for (const match of
|
|
535
|
-
|
|
536
|
-
descriptors.push({
|
|
578
|
+
for (const match of blanked.matchAll(DYNAMIC_PATTERN)) {
|
|
579
|
+
const source = readSource(code, match);
|
|
580
|
+
if (source) descriptors.push({
|
|
537
581
|
kind: "dynamic",
|
|
538
582
|
syntax: "import",
|
|
539
|
-
source
|
|
583
|
+
source,
|
|
540
584
|
typeOnly: false
|
|
541
585
|
});
|
|
542
586
|
}
|
|
543
|
-
for (const match of
|
|
544
|
-
|
|
545
|
-
descriptors.push({
|
|
587
|
+
for (const match of blanked.matchAll(REQUIRE_PATTERN)) {
|
|
588
|
+
const source = readSource(code, match);
|
|
589
|
+
if (source) descriptors.push({
|
|
546
590
|
kind: "dynamic",
|
|
547
591
|
syntax: "require",
|
|
548
|
-
source
|
|
592
|
+
source,
|
|
549
593
|
typeOnly: false
|
|
550
594
|
});
|
|
551
595
|
}
|
|
552
|
-
for (const match of
|
|
553
|
-
|
|
554
|
-
descriptors.push({
|
|
596
|
+
for (const match of blanked.matchAll(SIDE_EFFECT_PATTERN)) {
|
|
597
|
+
const source = readSource(code, match);
|
|
598
|
+
if (source) descriptors.push({
|
|
555
599
|
kind: "static",
|
|
556
600
|
syntax: "import",
|
|
557
|
-
source
|
|
601
|
+
source,
|
|
558
602
|
typeOnly: false
|
|
559
603
|
});
|
|
560
604
|
}
|
|
561
605
|
return descriptors;
|
|
562
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* Returns the JavaScript/TypeScript portion of a module for import scanning.
|
|
609
|
+
* Vue and Svelte single-file components only contribute their `<script>`
|
|
610
|
+
* blocks so template markup and styles are never misread as code.
|
|
611
|
+
*/
|
|
612
|
+
function getScannableModuleSource(id, code) {
|
|
613
|
+
if (!/\.(?:vue|svelte)(?:\?|$)/.test(id)) return code;
|
|
614
|
+
const blocks = [];
|
|
615
|
+
for (const match of code.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script(?:\s[^>]*)?>/gi)) blocks.push(match[1]);
|
|
616
|
+
return blocks.join("\n");
|
|
617
|
+
}
|
|
563
618
|
function findModuleImportSources(code) {
|
|
564
619
|
return Array.from(new Set(findModuleImportDescriptors(code).filter(({ syntax, typeOnly }) => syntax === "import" && !typeOnly).map(({ source }) => source)));
|
|
565
620
|
}
|
|
@@ -573,6 +628,7 @@ function sanitizeDevEntryPath(devEntryPath) {
|
|
|
573
628
|
*/
|
|
574
629
|
function rewriteEntryScripts(html, createProxySrc) {
|
|
575
630
|
return html.replace(/<script\b(?=[^>]*\btype=["']module["'])(?=[^>]*\bsrc=["'][^"']+["'])([^>]*)>/gi, (match, attrs) => {
|
|
631
|
+
if (/\svite-ignore(?:\s|=|\/|$)/i.test(attrs)) return match;
|
|
576
632
|
const srcMatch = attrs.match(/\bsrc=["']([^"']+)["']/i);
|
|
577
633
|
if (!srcMatch) return match;
|
|
578
634
|
const originalSrc = srcMatch[1];
|
|
@@ -617,6 +673,9 @@ function normalizeRemotes(remotes) {
|
|
|
617
673
|
});
|
|
618
674
|
return result;
|
|
619
675
|
}
|
|
676
|
+
function warnOmittedObjectRemoteType(remoteKey) {
|
|
677
|
+
mfWarn(`Remote "${remoteKey}" omits type and defaults to 'var'. Set type: 'module' for Vite ESM remotes, or type: 'var' explicitly to silence this warning.`);
|
|
678
|
+
}
|
|
620
679
|
function normalizeRemoteItem(key, remote) {
|
|
621
680
|
warnOnReservedInternalNamePrefix(key, "remoteAlias");
|
|
622
681
|
if (typeof remote === "string") {
|
|
@@ -639,6 +698,8 @@ function normalizeRemoteItem(key, remote) {
|
|
|
639
698
|
shareScope: "default"
|
|
640
699
|
};
|
|
641
700
|
}
|
|
701
|
+
const typeOmitted = remote.type === void 0 || remote.type === null || remote.type === "";
|
|
702
|
+
if (typeOmitted) warnOmittedObjectRemoteType(key);
|
|
642
703
|
return Object.assign({
|
|
643
704
|
type: "var",
|
|
644
705
|
name: key,
|
|
@@ -647,6 +708,7 @@ function normalizeRemoteItem(key, remote) {
|
|
|
647
708
|
entryGlobalName: key
|
|
648
709
|
}, {
|
|
649
710
|
...remote,
|
|
711
|
+
type: typeOmitted ? "var" : remote.type,
|
|
650
712
|
internalName: toInternalModuleFederationName(remote.name || key)
|
|
651
713
|
});
|
|
652
714
|
}
|
|
@@ -662,7 +724,35 @@ function searchPackageVersion(sharedName) {
|
|
|
662
724
|
}
|
|
663
725
|
function inferVersionFromRequiredVersion(requiredVersion) {
|
|
664
726
|
if (typeof requiredVersion !== "string") return void 0;
|
|
665
|
-
|
|
727
|
+
const isDigit = (char) => char !== void 0 && char >= "0" && char <= "9";
|
|
728
|
+
const isSuffixChar = (char) => char !== void 0 && (char >= "0" && char <= "9" || char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char === "." || char === "-");
|
|
729
|
+
let index = 0;
|
|
730
|
+
while (index < requiredVersion.length) {
|
|
731
|
+
if (!isDigit(requiredVersion[index])) {
|
|
732
|
+
index += 1;
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
const start = index;
|
|
736
|
+
while (isDigit(requiredVersion[index])) index += 1;
|
|
737
|
+
if (requiredVersion[index] !== ".") continue;
|
|
738
|
+
index += 1;
|
|
739
|
+
if (!isDigit(requiredVersion[index])) continue;
|
|
740
|
+
while (isDigit(requiredVersion[index])) index += 1;
|
|
741
|
+
if (requiredVersion[index] !== ".") continue;
|
|
742
|
+
index += 1;
|
|
743
|
+
if (!isDigit(requiredVersion[index])) continue;
|
|
744
|
+
while (isDigit(requiredVersion[index])) index += 1;
|
|
745
|
+
if ((requiredVersion[index] === "-" || requiredVersion[index] === "+") && isSuffixChar(requiredVersion[index + 1])) {
|
|
746
|
+
index += 1;
|
|
747
|
+
while (isSuffixChar(requiredVersion[index])) index += 1;
|
|
748
|
+
}
|
|
749
|
+
return requiredVersion.slice(start, index);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
/** URI-style package specifiers are not semver ranges for runtime satisfy(). */
|
|
753
|
+
const PACKAGE_SPECIFIER_PROTOCOL_RE = /^[a-z][a-z\d+.-]*:/i;
|
|
754
|
+
function isProtocolRequiredVersion(requiredVersion) {
|
|
755
|
+
return PACKAGE_SPECIFIER_PROTOCOL_RE.test(requiredVersion.trim());
|
|
666
756
|
}
|
|
667
757
|
function getLitExportSubpathShares(sharedName) {
|
|
668
758
|
if (sharedName !== "lit") return [];
|
|
@@ -691,6 +781,8 @@ function normalizeShareItem(key, shareItem) {
|
|
|
691
781
|
requiredVersion: version ? `^${version}` : "*"
|
|
692
782
|
}
|
|
693
783
|
};
|
|
784
|
+
const userRequiredVersion = shareItem.requiredVersion;
|
|
785
|
+
const keepUserRequiredVersion = userRequiredVersion === false || typeof userRequiredVersion === "string" && userRequiredVersion.trim() !== "" && !isProtocolRequiredVersion(userRequiredVersion);
|
|
694
786
|
return {
|
|
695
787
|
name: key,
|
|
696
788
|
from: "",
|
|
@@ -700,7 +792,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
700
792
|
import: shareItem.import,
|
|
701
793
|
singleton: shareItem.singleton || false,
|
|
702
794
|
eager: shareItem.eager || false,
|
|
703
|
-
requiredVersion:
|
|
795
|
+
requiredVersion: keepUserRequiredVersion ? userRequiredVersion : isImportFalse || shareItem.version ? "*" : version ? `^${version}` : "*",
|
|
704
796
|
strictVersion: !!shareItem.strictVersion,
|
|
705
797
|
...shareItem.suppressMissingImportWarning ? { suppressMissingImportWarning: true } : {},
|
|
706
798
|
...treeShaking ? { treeShaking: { ...treeShaking } } : {}
|
|
@@ -719,9 +811,9 @@ function normalizeShareItem(key, shareItem) {
|
|
|
719
811
|
* a prefix; concrete subpaths materialize on import via the generic matcher.
|
|
720
812
|
*
|
|
721
813
|
* `react-dom/` must keep collapsing. A browser-wide `react-dom/` prefix would
|
|
722
|
-
* also capture `react-dom/server
|
|
723
|
-
*
|
|
724
|
-
*
|
|
814
|
+
* also capture `react-dom/server*`. Browser-safe entries (`react-dom/client`,
|
|
815
|
+
* `react-dom/profiling`) stay via COMMON_SHARED_SUBPATHS (local provider) or
|
|
816
|
+
* an exact shared key; SSR server* entries need an explicit shared key.
|
|
725
817
|
*/
|
|
726
818
|
function normalizeSharedKey(key) {
|
|
727
819
|
if (!key.endsWith("/")) return key;
|
|
@@ -1265,6 +1357,49 @@ function loadReactIslandConsumerModule(id) {
|
|
|
1265
1357
|
function getVirtualModuleScopeKey(options) {
|
|
1266
1358
|
return `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1267
1359
|
}
|
|
1360
|
+
function compareConfigValues(a, b) {
|
|
1361
|
+
const serializedA = JSON.stringify(a);
|
|
1362
|
+
const serializedB = JSON.stringify(b);
|
|
1363
|
+
return serializedA < serializedB ? -1 : serializedA > serializedB ? 1 : 0;
|
|
1364
|
+
}
|
|
1365
|
+
function stableConfigValue(value, ancestors = /* @__PURE__ */ new WeakSet()) {
|
|
1366
|
+
if (typeof value === "function") return value.toString();
|
|
1367
|
+
if (!value || typeof value !== "object") return value;
|
|
1368
|
+
if (value instanceof Date) return {
|
|
1369
|
+
type: "Date",
|
|
1370
|
+
value: value.toISOString()
|
|
1371
|
+
};
|
|
1372
|
+
if (value instanceof RegExp) return {
|
|
1373
|
+
type: "RegExp",
|
|
1374
|
+
source: value.source,
|
|
1375
|
+
flags: value.flags
|
|
1376
|
+
};
|
|
1377
|
+
if (ancestors.has(value)) return "__circular__";
|
|
1378
|
+
ancestors.add(value);
|
|
1379
|
+
let result;
|
|
1380
|
+
if (value instanceof Map) {
|
|
1381
|
+
const entries = [...value.entries()].map(([key, item]) => [stableConfigValue(key, ancestors), stableConfigValue(item, ancestors)]);
|
|
1382
|
+
entries.sort(compareConfigValues);
|
|
1383
|
+
result = {
|
|
1384
|
+
type: "Map",
|
|
1385
|
+
entries
|
|
1386
|
+
};
|
|
1387
|
+
} else if (value instanceof Set) {
|
|
1388
|
+
const values = [...value].map((item) => stableConfigValue(item, ancestors));
|
|
1389
|
+
values.sort(compareConfigValues);
|
|
1390
|
+
result = {
|
|
1391
|
+
type: "Set",
|
|
1392
|
+
values
|
|
1393
|
+
};
|
|
1394
|
+
} else result = Array.isArray(value) ? value.map((item) => stableConfigValue(item, ancestors)) : Object.fromEntries(Object.entries(value).filter(([key]) => key !== "implementation").sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => [key, stableConfigValue(item, ancestors)]));
|
|
1395
|
+
ancestors.delete(value);
|
|
1396
|
+
return result;
|
|
1397
|
+
}
|
|
1398
|
+
function getFederationScopeKey(options) {
|
|
1399
|
+
const identity = JSON.stringify(stableConfigValue(options));
|
|
1400
|
+
const ownerId = BigInt(`0x${createHash("sha256").update(identity).digest("hex").slice(0, 12)}`);
|
|
1401
|
+
return `${options.internalName}${MF_OWNER_INFIX}${ownerId}`;
|
|
1402
|
+
}
|
|
1268
1403
|
//#endregion
|
|
1269
1404
|
//#region src/virtualModules/virtualExposes.ts
|
|
1270
1405
|
const EXPOSES_CSS_MAP_PLACEHOLDER = "__MF_EXPOSES_CSS_MAP__";
|
|
@@ -1414,28 +1549,17 @@ function isReactServerConditions(conditions) {
|
|
|
1414
1549
|
//#region src/virtualModules/virtualRuntimeInitStatus.ts
|
|
1415
1550
|
const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
|
|
1416
1551
|
const runtimeInitModules = /* @__PURE__ */ new WeakMap();
|
|
1417
|
-
const runtimeInitOwnerIds = /* @__PURE__ */ new WeakMap();
|
|
1418
|
-
let nextRuntimeInitOwnerId = 1;
|
|
1419
1552
|
const MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache__";
|
|
1420
1553
|
const REACT_SERVER_MODULE_CACHE_GLOBAL_KEY = "__mf_module_cache_react_server__";
|
|
1421
1554
|
const MODULE_CACHE_SHARE_SCOPE_KEY = "module-federation.vite-module-cache";
|
|
1422
1555
|
function getModuleCacheGlobalKey(exportConditions) {
|
|
1423
1556
|
return isReactServerConditions(exportConditions) ? REACT_SERVER_MODULE_CACHE_GLOBAL_KEY : MODULE_CACHE_GLOBAL_KEY;
|
|
1424
1557
|
}
|
|
1425
|
-
function getRuntimeInitOwnerId(options) {
|
|
1426
|
-
let ownerId = runtimeInitOwnerIds.get(options);
|
|
1427
|
-
if (!ownerId) {
|
|
1428
|
-
ownerId = nextRuntimeInitOwnerId++;
|
|
1429
|
-
runtimeInitOwnerIds.set(options, ownerId);
|
|
1430
|
-
}
|
|
1431
|
-
return ownerId;
|
|
1432
|
-
}
|
|
1433
1558
|
function getRuntimeInitModule(options) {
|
|
1434
1559
|
if (!options) return virtualRuntimeInitStatus;
|
|
1435
1560
|
let runtimeInitModule = runtimeInitModules.get(options);
|
|
1436
1561
|
if (!runtimeInitModule) {
|
|
1437
|
-
|
|
1438
|
-
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", `${options.internalName}${MF_OWNER_INFIX}${ownerId}`);
|
|
1562
|
+
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", getFederationScopeKey(options));
|
|
1439
1563
|
runtimeInitModules.set(options, runtimeInitModule);
|
|
1440
1564
|
}
|
|
1441
1565
|
return runtimeInitModule;
|
|
@@ -1448,7 +1572,7 @@ function getRuntimeRemoteCachePrefix(options) {
|
|
|
1448
1572
|
}
|
|
1449
1573
|
function getRuntimeRemoteAlias(alias, options) {
|
|
1450
1574
|
if (!options) return alias;
|
|
1451
|
-
return `${
|
|
1575
|
+
return `${getFederationScopeKey(options)}__${alias}`;
|
|
1452
1576
|
}
|
|
1453
1577
|
function getRuntimeInitGlobalKey(ownerImportId) {
|
|
1454
1578
|
return `__mf_init__${ownerImportId ?? virtualRuntimeInitStatus.getImportId()}__`;
|
|
@@ -1538,6 +1662,16 @@ globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
|
|
|
1538
1662
|
globalThis[__mfCacheGlobalKey].share ||= {};
|
|
1539
1663
|
globalThis[__mfCacheGlobalKey].remote ||= {};
|
|
1540
1664
|
const __mfModuleCache = globalThis[__mfCacheGlobalKey];
|
|
1665
|
+
const __mfTrackPendingShareLoad = (promise) => {
|
|
1666
|
+
const pendingShareLoads = (__mfModuleCache.pendingShareLoads ||= []);
|
|
1667
|
+
pendingShareLoads.push(promise);
|
|
1668
|
+
const cleanup = () => {
|
|
1669
|
+
const index = pendingShareLoads.indexOf(promise);
|
|
1670
|
+
if (index !== -1) pendingShareLoads.splice(index, 1);
|
|
1671
|
+
};
|
|
1672
|
+
void promise.then(cleanup, cleanup);
|
|
1673
|
+
return promise;
|
|
1674
|
+
};
|
|
1541
1675
|
for (const __mfShareKey of Object.keys(__mfModuleCache.share)) {
|
|
1542
1676
|
if (__mfShareKey.startsWith("default:")) {
|
|
1543
1677
|
const __mfLegacyShareKey = __mfShareKey.slice("default:".length);
|
|
@@ -2218,6 +2352,14 @@ function getAdditionalTopLevelDeclaratorNames(source, start, codePositions) {
|
|
|
2218
2352
|
canStartRegex = false;
|
|
2219
2353
|
continue;
|
|
2220
2354
|
}
|
|
2355
|
+
if (char === "<" && source[index + 1] === "/") {
|
|
2356
|
+
const jsxClosingTag = source.slice(index).match(/^<\/\s*(?:[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}.:-]*\s*)?>/u);
|
|
2357
|
+
if (jsxClosingTag) {
|
|
2358
|
+
index += jsxClosingTag[0].length - 1;
|
|
2359
|
+
canStartRegex = false;
|
|
2360
|
+
continue;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2221
2363
|
if (char === "/" && source[index + 1] === "/") {
|
|
2222
2364
|
index = source.indexOf("\n", index + 2);
|
|
2223
2365
|
if (index === -1) return names;
|
|
@@ -2454,6 +2596,9 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
2454
2596
|
let previousCodeIndex = match.index - 1;
|
|
2455
2597
|
while (previousCodeIndex >= 0 && (/\s/.test(source[previousCodeIndex]) || !codePositions[previousCodeIndex])) previousCodeIndex--;
|
|
2456
2598
|
if (source[previousCodeIndex] === ".") continue;
|
|
2599
|
+
let nextCodeIndex = match.index + match[0].length;
|
|
2600
|
+
while (/\s/.test(source[nextCodeIndex] || "")) nextCodeIndex++;
|
|
2601
|
+
if (source[nextCodeIndex] === "(") continue;
|
|
2457
2602
|
scanState.complete = false;
|
|
2458
2603
|
break;
|
|
2459
2604
|
}
|
|
@@ -2692,7 +2837,6 @@ const legacySharedVirtualModuleState = {
|
|
|
2692
2837
|
warnedMissingImportFalse: /* @__PURE__ */ new Set()
|
|
2693
2838
|
};
|
|
2694
2839
|
const sharedVirtualModuleStates = /* @__PURE__ */ new WeakMap();
|
|
2695
|
-
let nextSharedVirtualModuleOwnerId = 1;
|
|
2696
2840
|
function getSharedVirtualModuleState(options) {
|
|
2697
2841
|
if (!options) try {
|
|
2698
2842
|
const currentOptions = getNormalizeModuleFederationOptions();
|
|
@@ -2709,7 +2853,7 @@ function getSharedVirtualModuleState(options) {
|
|
|
2709
2853
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
2710
2854
|
loadShareCacheMap: {},
|
|
2711
2855
|
warnedMissingImportFalse: /* @__PURE__ */ new Set(),
|
|
2712
|
-
ownerKey:
|
|
2856
|
+
ownerKey: getFederationScopeKey(options)
|
|
2713
2857
|
};
|
|
2714
2858
|
sharedVirtualModuleStates.set(options, state);
|
|
2715
2859
|
}
|
|
@@ -3008,7 +3152,7 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
|
|
|
3008
3152
|
if (import.meta.env.SSR${serveLocalFallback ? " || (import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')" : ""}) {
|
|
3009
3153
|
${applyLocalFallback}
|
|
3010
3154
|
} else {
|
|
3011
|
-
(
|
|
3155
|
+
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3012
3156
|
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3013
3157
|
if (exportModule !== undefined) {
|
|
3014
3158
|
__mfApplyLazyShareExports(exportModule);
|
|
@@ -3053,7 +3197,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor,
|
|
|
3053
3197
|
};
|
|
3054
3198
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3055
3199
|
if (exportModule === undefined) {
|
|
3056
|
-
(
|
|
3200
|
+
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3057
3201
|
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3058
3202
|
if (exportModule === undefined) {
|
|
3059
3203
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
@@ -3140,10 +3284,10 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3140
3284
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
3141
3285
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
3142
3286
|
const isDefaultShareScope = shareItem.scope === void 0 || shareItem.scope === "default" || Array.isArray(shareItem.scope) && shareItem.scope[0] === "default";
|
|
3143
|
-
const usesDeferredSingletonFallback = hasCompleteExportCoverage && (isWorkspacePackage || command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer(resolvedOptions) && (shareItem.shareConfig.singleton === true
|
|
3287
|
+
const usesDeferredSingletonFallback = hasCompleteExportCoverage && shareItem.shareConfig.eager !== true && (isWorkspacePackage || command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer(resolvedOptions) && (shareItem.shareConfig.singleton === true || isDefaultShareScope));
|
|
3144
3288
|
const servesRemoteSingletonFallback = command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true;
|
|
3145
3289
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg, resolvedOptions);
|
|
3146
|
-
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage &&
|
|
3290
|
+
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && !isWorkspaceSingleton && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true && resolvedOptions.hostInitInjectLocation === "entry" && (command === "build" || isConsumedByPeerSingleton);
|
|
3147
3291
|
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && !servesRemoteSingletonFallback && (isConsumedByPeerSingleton || shareItem.shareConfig.eager === true);
|
|
3148
3292
|
const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
|
|
3149
3293
|
const reactMixedModeGuard = pkg === "react" ? createReactMixedModeRuntimeGuard() : "";
|
|
@@ -3432,12 +3576,24 @@ function generateLocalSharedImportMap(options) {
|
|
|
3432
3576
|
}
|
|
3433
3577
|
`;
|
|
3434
3578
|
}
|
|
3579
|
+
/** Expand `pkg/` → package root + matching usedShares; never returns the prefix string. */
|
|
3580
|
+
function expandSharedPrefixKey(prefixKey, used) {
|
|
3581
|
+
const base = prefixKey.slice(0, -1);
|
|
3582
|
+
const expanded = /* @__PURE__ */ new Set([base]);
|
|
3583
|
+
for (const pkg of used) {
|
|
3584
|
+
if (pkg.endsWith("/")) continue;
|
|
3585
|
+
if (pkg === base || pkg.startsWith(`${base}/`)) expanded.add(pkg);
|
|
3586
|
+
}
|
|
3587
|
+
return [...expanded];
|
|
3588
|
+
}
|
|
3435
3589
|
function getOrderedUsedShares(options) {
|
|
3436
3590
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3437
|
-
const
|
|
3591
|
+
const used = getUsedShares(options);
|
|
3592
|
+
const shares = new Set(used);
|
|
3438
3593
|
Object.keys(resolvedOptions.shared ?? {}).forEach((pkg) => {
|
|
3439
3594
|
if (!pkg.endsWith("/")) shares.add(pkg);
|
|
3440
3595
|
});
|
|
3596
|
+
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (pkg.endsWith("/") && share.shareConfig?.eager) for (const concrete of expandSharedPrefixKey(pkg, used)) shares.add(concrete);
|
|
3441
3597
|
return orderSharedDependenciesFirst(Array.from(shares).sort((a, b) => {
|
|
3442
3598
|
const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
|
|
3443
3599
|
return priority(a) - priority(b) || a.localeCompare(b);
|
|
@@ -3447,7 +3603,12 @@ function getMaterializedShares(options) {
|
|
|
3447
3603
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3448
3604
|
const scopedRegistrations = options ? usedSharesByOptions.get(options) : void 0;
|
|
3449
3605
|
const shares = new Set(options && scopedRegistrations?.size ? materializedSharesByOptions.get(options) ?? [] : usedShares);
|
|
3450
|
-
|
|
3606
|
+
const usedForEager = options ? usedSharesByOptions.get(options) ?? [] : usedShares;
|
|
3607
|
+
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) {
|
|
3608
|
+
if (!share.shareConfig?.eager) continue;
|
|
3609
|
+
if (pkg.endsWith("/")) for (const concrete of expandSharedPrefixKey(pkg, usedForEager)) shares.add(concrete);
|
|
3610
|
+
else shares.add(pkg);
|
|
3611
|
+
}
|
|
3451
3612
|
const configured = /* @__PURE__ */ new Map();
|
|
3452
3613
|
for (const pkg of getOrderedUsedShares(options)) {
|
|
3453
3614
|
const packageName = getPackageName(pkg);
|
|
@@ -3620,8 +3781,16 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
|
|
|
3620
3781
|
strategy
|
|
3621
3782
|
) => {
|
|
3622
3783
|
if (!versions || !share) return undefined;
|
|
3784
|
+
// import:false stubs provide nothing, so they are never a selectable
|
|
3785
|
+
// provider and must not be satisfy-checked. Skip the runtime entirely
|
|
3786
|
+
// when nothing remains: it treats an empty map as version "0" and
|
|
3787
|
+
// warns that it fails even a "*" requirement.
|
|
3788
|
+
const candidates = Object.fromEntries(
|
|
3789
|
+
Object.entries(versions).filter(([, provider]) => provider?.shareConfig?.import !== false)
|
|
3790
|
+
);
|
|
3791
|
+
if (Object.keys(candidates).length === 0) return undefined;
|
|
3623
3792
|
const scopes = Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
|
|
3624
|
-
const selectionVersions = __mfCreateProviderSelectionVersions(
|
|
3793
|
+
const selectionVersions = __mfCreateProviderSelectionVersions(candidates, strategy);
|
|
3625
3794
|
const shareScopeMap = {};
|
|
3626
3795
|
for (const scope of scopes) {
|
|
3627
3796
|
shareScopeMap[scope || "default"] = { [pkg]: selectionVersions };
|
|
@@ -4190,7 +4359,21 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4190
4359
|
}
|
|
4191
4360
|
return runtimeScope;
|
|
4192
4361
|
};
|
|
4362
|
+
// runtimeInit() lets runtime plugins register providers (public
|
|
4363
|
+
// registerShared) before initShareScopeMap() replaces the runtime's own
|
|
4364
|
+
// scope map. Carry those registrations over; the runtime's own copies of
|
|
4365
|
+
// usedShared keep registering lazily through loadShare().
|
|
4366
|
+
const __mfKeepRegisteredShares = (scopeName, scope) => {
|
|
4367
|
+
for (const [pkg, versions] of Object.entries(initRes.shareScopeMap?.[scopeName] || {})) {
|
|
4368
|
+
for (const [version, provider] of Object.entries(versions || {})) {
|
|
4369
|
+
if (!provider || provider.get === usedShared[pkg]?.get) continue;
|
|
4370
|
+
const target = scope[pkg] ||= {};
|
|
4371
|
+
if (target[version] === undefined) target[version] = provider;
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
};
|
|
4193
4375
|
const __mfGetRuntimeShareScope = (scopeName, hostScope) => {
|
|
4376
|
+
__mfKeepRegisteredShares(scopeName, hostScope);
|
|
4194
4377
|
const isWebpackScope = !scopeRoot && Object.values(hostScope || {}).some((versions) =>
|
|
4195
4378
|
Object.values(versions || {}).some(isWebpackProvider)
|
|
4196
4379
|
);
|
|
@@ -4586,6 +4769,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4586
4769
|
);
|
|
4587
4770
|
const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
|
|
4588
4771
|
if (!providerEntry) return;
|
|
4772
|
+
if (usedShare.shareConfig?.import === false && __mfMatchesSharedProvider(provider, usedShare)) return;
|
|
4589
4773
|
const { version } = providerEntry;
|
|
4590
4774
|
if (!singleton && version !== usedShare.version) return;
|
|
4591
4775
|
if (
|
|
@@ -4699,6 +4883,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4699
4883
|
scopeRootProvider: undefined
|
|
4700
4884
|
};
|
|
4701
4885
|
if (usedShare.canLiveRebind === false) return;
|
|
4886
|
+
if (usedShare.shareConfig?.import === false && __mfMatchesSharedProvider(provider, usedShare)) return;
|
|
4702
4887
|
// Preserve a singleton already selected by another container. The bridge may
|
|
4703
4888
|
// only replace the provisional local fallback seeded by this container.
|
|
4704
4889
|
if (cachedShare !== undefined && cachedShareOwner !== mfName) return;
|
|
@@ -4865,6 +5050,11 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4865
5050
|
) || share;
|
|
4866
5051
|
const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
|
|
4867
5052
|
if (!providerEntry) return;
|
|
5053
|
+
// A provider registered on this instance through the public registerShared
|
|
5054
|
+
// API carries this container's own name, so tell the own stub apart by its
|
|
5055
|
+
// import:false config rather than by provenance.
|
|
5056
|
+
const __mfIsOwnStub = (candidate) => candidate === share || candidate?.shareConfig?.import === false;
|
|
5057
|
+
if (__mfIsOwnStub(provider)) return;
|
|
4868
5058
|
const { version } = providerEntry;
|
|
4869
5059
|
const currentProvider = versionMap?.[version];
|
|
4870
5060
|
const loadedShare = await __mfLoadPinnedRuntimeShare(
|
|
@@ -4874,13 +5064,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4874
5064
|
version,
|
|
4875
5065
|
currentProvider,
|
|
4876
5066
|
provider,
|
|
4877
|
-
providerEntry.registered
|
|
5067
|
+
providerEntry.registered
|
|
4878
5068
|
);
|
|
4879
5069
|
const providerSelection = loadedShare?.selection;
|
|
4880
5070
|
const actualProvider = loadedShare?.provider;
|
|
4881
5071
|
const resolved = loadedShare?.resolved;
|
|
4882
5072
|
if (!providerSelection) return;
|
|
4883
|
-
if (
|
|
5073
|
+
if (__mfIsOwnStub(actualProvider)) return;
|
|
4884
5074
|
if (resolved === undefined) return;
|
|
4885
5075
|
const latestCachedShare = share.treeShaking
|
|
4886
5076
|
? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
|
|
@@ -5021,6 +5211,16 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5021
5211
|
__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined &&
|
|
5022
5212
|
__mfReadSharedCacheOwner(__mfModuleCache.share, cacheDescriptor) ${_command === "serve" ? "!== undefined" : `=== ${cacheOwner}`}
|
|
5023
5213
|
) return;
|
|
5214
|
+
// An import:false share has nothing to load until a foreign provider
|
|
5215
|
+
// registers: its own stub getter throws by construction.
|
|
5216
|
+
if (
|
|
5217
|
+
share.shareConfig?.import === false &&
|
|
5218
|
+
!(Array.isArray(share.scope) ? share.scope : [share.scope || 'default']).some((scopeName) =>
|
|
5219
|
+
Object.values(runtime.shareScopeMap?.[scopeName]?.[pkg] || {}).some(
|
|
5220
|
+
(provider) => provider?.shareConfig?.import !== false
|
|
5221
|
+
)
|
|
5222
|
+
)
|
|
5223
|
+
) return;
|
|
5024
5224
|
await runtime.loadShare(pkg, {
|
|
5025
5225
|
customShareInfo: { shareConfig: share.shareConfig }
|
|
5026
5226
|
}).then(async (factory) => {
|
|
@@ -5122,6 +5322,7 @@ const usedRemotesMap = {};
|
|
|
5122
5322
|
const usedRemotesByOptions = /* @__PURE__ */ new WeakMap();
|
|
5123
5323
|
const dynamicRemotesByOptions = /* @__PURE__ */ new WeakMap();
|
|
5124
5324
|
const staticRemotesByOptions = /* @__PURE__ */ new WeakMap();
|
|
5325
|
+
const preloadRemotesByOptions = /* @__PURE__ */ new WeakMap();
|
|
5125
5326
|
const EMPTY_STATIC_REMOTES = /* @__PURE__ */ new Set();
|
|
5126
5327
|
function getScopedUsedRemotesMap(options) {
|
|
5127
5328
|
let scoped = usedRemotesByOptions.get(options);
|
|
@@ -5159,8 +5360,16 @@ function markStaticRemote(remote, options) {
|
|
|
5159
5360
|
}
|
|
5160
5361
|
remotes.add(remote);
|
|
5161
5362
|
}
|
|
5162
|
-
function
|
|
5163
|
-
|
|
5363
|
+
function markPreloadRemote(remote, options) {
|
|
5364
|
+
let remotes = preloadRemotesByOptions.get(options);
|
|
5365
|
+
if (!remotes) {
|
|
5366
|
+
remotes = /* @__PURE__ */ new Set();
|
|
5367
|
+
preloadRemotesByOptions.set(options, remotes);
|
|
5368
|
+
}
|
|
5369
|
+
remotes.add(remote);
|
|
5370
|
+
}
|
|
5371
|
+
function getPreloadRemotes(options) {
|
|
5372
|
+
return preloadRemotesByOptions.get(options) ?? EMPTY_STATIC_REMOTES;
|
|
5164
5373
|
}
|
|
5165
5374
|
function isDynamicOnlyRemote(remote, options) {
|
|
5166
5375
|
return (dynamicRemotesByOptions.get(options)?.has(remote) ?? false) && !(staticRemotesByOptions.get(options)?.has(remote) ?? false);
|
|
@@ -5660,7 +5869,7 @@ const __mfCurrentScript = document.currentScript;
|
|
|
5660
5869
|
const normalizedOptions = federationOptions ?? getNormalizeModuleFederationOptions();
|
|
5661
5870
|
const isLoadedFirstClientBuild = (_command === "build" || viteConfig?.command === "build") && waitsForInit && !viteConfig?.build?.ssr && normalizedOptions.shareStrategy === "loaded-first";
|
|
5662
5871
|
if (normalizedOptions.shareStrategy === "loaded-first" && !isLoadedFirstClientBuild) return [];
|
|
5663
|
-
const remoteSources = isLoadedFirstClientBuild ? Array.from(
|
|
5872
|
+
const remoteSources = isLoadedFirstClientBuild ? Array.from(getPreloadRemotes(normalizedOptions)) : Object.entries(getUsedRemotesMap(federationOptions)).flatMap(([, remotes]) => Array.from(remotes)).filter((remote) => !federationOptions || !isDynamicOnlyRemote(remote, federationOptions));
|
|
5664
5873
|
return Array.from(new Set(remoteSources.flatMap((remote) => {
|
|
5665
5874
|
const registration = getRemoteRegistration(remote, normalizedOptions.remotes, federationOptions);
|
|
5666
5875
|
return registration && (registration.type === "module" || registration.type === "esm") && /^(?:https?:)?\/\//.test(registration.entry) ? [registration.entry] : [];
|
|
@@ -5680,7 +5889,7 @@ const __mfCurrentScript = document.currentScript;
|
|
|
5680
5889
|
const normalizedOptions = federationOptions ?? getNormalizeModuleFederationOptions();
|
|
5681
5890
|
const isLoadedFirstClientBuild = (_command === "build" || viteConfig?.command === "build") && waitsForInit && !viteConfig?.build?.ssr && normalizedOptions.shareStrategy === "loaded-first";
|
|
5682
5891
|
const shouldPreloadRemotes = !options?.skipRemotePreload && (normalizedOptions.shareStrategy !== "loaded-first" || isLoadedFirstClientBuild);
|
|
5683
|
-
const remoteSources = isLoadedFirstClientBuild ? Array.from(
|
|
5892
|
+
const remoteSources = isLoadedFirstClientBuild ? Array.from(getPreloadRemotes(normalizedOptions)) : Object.entries(getUsedRemotesMap(federationOptions)).flatMap(([, remotes]) => Array.from(remotes)).filter((remote) => !federationOptions || !isDynamicOnlyRemote(remote, federationOptions));
|
|
5684
5893
|
const remotePreloads = shouldPreloadRemotes ? remoteSources.sort().map((remote) => {
|
|
5685
5894
|
const registration = isLoadedFirstClientBuild ? getRemoteRegistration(remote, normalizedOptions.remotes, federationOptions) : void 0;
|
|
5686
5895
|
return `__mfPreloadRemote(${JSON.stringify(getRuntimeRemoteId(remote, normalizedOptions.remotes, federationOptions))}, ${JSON.stringify(remote)}${registration ? `, ${JSON.stringify(registration)}` : ""})`;
|
|
@@ -5922,6 +6131,10 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
5922
6131
|
else if (Array.isArray(inputOptions)) entryFiles = inputOptions.filter((input) => !isReactRouterClientRouteInput(String(input))).map(resolveProjectId);
|
|
5923
6132
|
else if (typeof inputOptions === "object") entryFiles = Object.values(inputOptions).filter((input) => !isReactRouterClientRouteInput(String(input))).map((input) => resolveProjectId(String(input)));
|
|
5924
6133
|
if (entryFiles.length > 0) htmlFilePath = getFirstHtmlEntryFile(entryFiles);
|
|
6134
|
+
if (config.command === "serve" && !htmlFilePath) {
|
|
6135
|
+
const rootIndexHtml = path$1.resolve(config.root, "index.html");
|
|
6136
|
+
if (fs$2.existsSync(rootIndexHtml)) htmlFilePath = rootIndexHtml;
|
|
6137
|
+
}
|
|
5925
6138
|
if (htmlFilePath) addHtmlScriptEntries(htmlFilePath);
|
|
5926
6139
|
},
|
|
5927
6140
|
buildStart() {
|
|
@@ -7028,8 +7241,30 @@ function getRemoteEntrySSRId(options) {
|
|
|
7028
7241
|
return `${REMOTE_ENTRY_SSR_ID}:${getVirtualModuleScopeKey(options)}`;
|
|
7029
7242
|
}
|
|
7030
7243
|
function getSsrRemoteEntryFileName(browserFilename) {
|
|
7031
|
-
|
|
7032
|
-
|
|
7244
|
+
let filename = browserFilename;
|
|
7245
|
+
if (filename.includes("[hash")) {
|
|
7246
|
+
filename = filename.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
|
|
7247
|
+
if (!/\.[^.]+$/.test(filename)) filename = `${filename}.js`;
|
|
7248
|
+
}
|
|
7249
|
+
const ext = filename.match(/\.[^.]+$/)?.[0] || ".js";
|
|
7250
|
+
return `${filename.slice(0, filename.length - ext.length)}.ssr${ext}`;
|
|
7251
|
+
}
|
|
7252
|
+
/** Singleton map for SSR loadShare: expand `pkg/` via usedShares; never serialize the prefix. */
|
|
7253
|
+
function getSsrSharedSingletons(options) {
|
|
7254
|
+
const used = getUsedShares(options);
|
|
7255
|
+
const result = {};
|
|
7256
|
+
for (const [pkg, share] of Object.entries(options.shared)) {
|
|
7257
|
+
if (!share.shareConfig.singleton) continue;
|
|
7258
|
+
if (pkg.endsWith("/")) {
|
|
7259
|
+
for (const concrete of expandSharedPrefixKey(pkg, used)) result[concrete] = {
|
|
7260
|
+
...share,
|
|
7261
|
+
name: concrete
|
|
7262
|
+
};
|
|
7263
|
+
continue;
|
|
7264
|
+
}
|
|
7265
|
+
result[pkg] = share;
|
|
7266
|
+
}
|
|
7267
|
+
return result;
|
|
7033
7268
|
}
|
|
7034
7269
|
/**
|
|
7035
7270
|
* Generates the SSR remote entry module.
|
|
@@ -7043,7 +7278,7 @@ function getSsrRemoteEntryFileName(browserFilename) {
|
|
|
7043
7278
|
*/
|
|
7044
7279
|
function generateRemoteEntrySSR(options) {
|
|
7045
7280
|
const virtualExposesSSRId = getVirtualExposesSSRId(options);
|
|
7046
|
-
const sharedSingletons =
|
|
7281
|
+
const sharedSingletons = getSsrSharedSingletons(options);
|
|
7047
7282
|
return `
|
|
7048
7283
|
import { init as runtimeInit } from "@module-federation/runtime";
|
|
7049
7284
|
|
|
@@ -7398,7 +7633,7 @@ const Manifest = (providedOptions) => {
|
|
|
7398
7633
|
if (this.environment?.name === "ssr") return;
|
|
7399
7634
|
let filesMap = {};
|
|
7400
7635
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
7401
|
-
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(
|
|
7636
|
+
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions.filename);
|
|
7402
7637
|
const foundSsrRemoteEntryFile = Object.values(bundle).find((file) => file.fileName === expectedSsrRemoteEntryFile)?.fileName;
|
|
7403
7638
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
7404
7639
|
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(resolveDevRemoteEntryFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
@@ -7788,12 +8023,10 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
7788
8023
|
}
|
|
7789
8024
|
function collectImportSources(code) {
|
|
7790
8025
|
const sources = /* @__PURE__ */ new Map();
|
|
7791
|
-
for (const
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
sources.set(source, (sources.get(source) ?? true) && dynamic);
|
|
7796
|
-
}
|
|
8026
|
+
for (const { source, kind, syntax, typeOnly } of findModuleImportDescriptors(code)) {
|
|
8027
|
+
if (syntax !== "import" || typeOnly) continue;
|
|
8028
|
+
const dynamic = kind === "dynamic";
|
|
8029
|
+
sources.set(source, (sources.get(source) ?? true) && dynamic);
|
|
7797
8030
|
}
|
|
7798
8031
|
return Array.from(sources, ([source, dynamic]) => ({
|
|
7799
8032
|
source,
|
|
@@ -7810,7 +8043,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
7810
8043
|
seen.add(id);
|
|
7811
8044
|
let code;
|
|
7812
8045
|
try {
|
|
7813
|
-
code = readFileSync$1(id, "utf8");
|
|
8046
|
+
code = getScannableModuleSource(id, readFileSync$1(id, "utf8"));
|
|
7814
8047
|
} catch {
|
|
7815
8048
|
return [];
|
|
7816
8049
|
}
|
|
@@ -8205,6 +8438,35 @@ function excludeSharedSubDependencies(shared) {
|
|
|
8205
8438
|
}
|
|
8206
8439
|
}
|
|
8207
8440
|
}
|
|
8441
|
+
const sharedDependencyCache = /* @__PURE__ */ new Map();
|
|
8442
|
+
/** Whether `dependency` is reachable through the shared package's manifest dependencies. */
|
|
8443
|
+
function isSharedPackageDependency(sharedKey, dependency) {
|
|
8444
|
+
const sharedPackage = getPackageName(sharedKey);
|
|
8445
|
+
let reachable = sharedDependencyCache.get(sharedPackage);
|
|
8446
|
+
if (!reachable) {
|
|
8447
|
+
reachable = /* @__PURE__ */ new Set();
|
|
8448
|
+
const visited = /* @__PURE__ */ new Set();
|
|
8449
|
+
const queue = [getInstalledPackageJson(sharedPackage, { packageName: sharedPackage })];
|
|
8450
|
+
for (let installed = queue.shift(); installed; installed = queue.shift()) {
|
|
8451
|
+
if (visited.has(installed.dir)) continue;
|
|
8452
|
+
visited.add(installed.dir);
|
|
8453
|
+
const manifest = installed.packageJson;
|
|
8454
|
+
for (const dep of Object.keys({
|
|
8455
|
+
...manifest.dependencies,
|
|
8456
|
+
...manifest.peerDependencies,
|
|
8457
|
+
...manifest.optionalDependencies
|
|
8458
|
+
})) {
|
|
8459
|
+
reachable.add(dep);
|
|
8460
|
+
queue.push(getInstalledPackageJson(dep, {
|
|
8461
|
+
cwd: installed.dir,
|
|
8462
|
+
packageName: dep
|
|
8463
|
+
}));
|
|
8464
|
+
}
|
|
8465
|
+
}
|
|
8466
|
+
sharedDependencyCache.set(sharedPackage, reachable);
|
|
8467
|
+
}
|
|
8468
|
+
return reachable.has(dependency);
|
|
8469
|
+
}
|
|
8208
8470
|
function proxySharedModule(options) {
|
|
8209
8471
|
const { shared = {}, federationOptions, getParsePromise = () => Promise.resolve() } = options;
|
|
8210
8472
|
let _config;
|
|
@@ -8286,6 +8548,7 @@ function proxySharedModule(options) {
|
|
|
8286
8548
|
setTreeShakingBuildMode(command === "build", federationOptions);
|
|
8287
8549
|
resetTreeShakingExports(federationOptions);
|
|
8288
8550
|
emittedTreeShakingProviders.clear();
|
|
8551
|
+
sharedDependencyCache.clear();
|
|
8289
8552
|
const isVinext = hasPackageDependency("vinext");
|
|
8290
8553
|
const isAstro = hasPackageDependency("astro");
|
|
8291
8554
|
const isRolldown = getIsRolldown(this);
|
|
@@ -8374,6 +8637,9 @@ function proxySharedModule(options) {
|
|
|
8374
8637
|
}
|
|
8375
8638
|
const key = findSharedKeyForSource(source, shared);
|
|
8376
8639
|
if (!key) return;
|
|
8640
|
+
const importerPackage = importer ? getPackageNameFromNodeModulePath(importer) : void 0;
|
|
8641
|
+
if (importerPackage === getPackageName(key)) return;
|
|
8642
|
+
if (importerPackage && isSharedPackageDependency(key, importerPackage)) return;
|
|
8377
8643
|
if (useDirectReactImport && key === "react") return;
|
|
8378
8644
|
if (isAssetLikeImport(source)) return;
|
|
8379
8645
|
if (isBuildConfigImporter(importer)) return;
|
|
@@ -9562,7 +9828,7 @@ function registerEntryImports(options, projectRoot, recordShared = true, entryFi
|
|
|
9562
9828
|
const { file, preloadRemotes } = pending.pop();
|
|
9563
9829
|
if (visited.get(file) || visited.has(file) && !preloadRemotes) continue;
|
|
9564
9830
|
visited.set(file, preloadRemotes);
|
|
9565
|
-
const code = readFileSync(file, "utf8");
|
|
9831
|
+
const code = getScannableModuleSource(file, readFileSync(file, "utf8"));
|
|
9566
9832
|
for (const { source: request, kind, typeOnly } of findModuleImportDescriptors(code)) {
|
|
9567
9833
|
const isStatic = kind === "static" && !typeOnly;
|
|
9568
9834
|
const remoteKey = preloadRemotes && isStatic && request ? Object.keys(options.remotes).find((name) => request === name || request.startsWith(`${name}/`)) : void 0;
|
|
@@ -9570,6 +9836,7 @@ function registerEntryImports(options, projectRoot, recordShared = true, entryFi
|
|
|
9570
9836
|
if (remoteKey) {
|
|
9571
9837
|
addUsedRemote(remoteKey, request, options);
|
|
9572
9838
|
markStaticRemote(request, options);
|
|
9839
|
+
markPreloadRemote(request, options);
|
|
9573
9840
|
} else if (sharedKey && recordShared) addUsedShares(request, options);
|
|
9574
9841
|
else if (request && !typeOnly) enqueue(request, file, preloadRemotes && isStatic);
|
|
9575
9842
|
}
|
|
@@ -9743,7 +10010,11 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
9743
10010
|
else optimizeDeps.include.push(key);
|
|
9744
10011
|
for (const subpath of getCommonSharedSubpaths(key)) {
|
|
9745
10012
|
const canResolveSubpath = canResolveSharedSubpath(subpath, root);
|
|
9746
|
-
if ([
|
|
10013
|
+
if ([
|
|
10014
|
+
"react/compiler-runtime",
|
|
10015
|
+
"react-dom/client",
|
|
10016
|
+
"react-dom/profiling"
|
|
10017
|
+
].includes(subpath) && !canResolveSubpath) {
|
|
9747
10018
|
optimizeDeps.exclude.push(subpath);
|
|
9748
10019
|
continue;
|
|
9749
10020
|
}
|
|
@@ -9812,7 +10083,7 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
9812
10083
|
}
|
|
9813
10084
|
function loadPluginDts(options) {
|
|
9814
10085
|
if (options.dts === false) return [];
|
|
9815
|
-
return [import("./pluginDts-
|
|
10086
|
+
return [import("./pluginDts-C2bUY8h9.js").then(({ default: pluginDts }) => pluginDts(options))];
|
|
9816
10087
|
}
|
|
9817
10088
|
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
9818
10089
|
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
@@ -5,11 +5,7 @@ const COMMON_SHARED_SUBPATHS = {
|
|
|
5
5
|
"react/jsx-dev-runtime",
|
|
6
6
|
"react/compiler-runtime"
|
|
7
7
|
],
|
|
8
|
-
"react-dom": [
|
|
9
|
-
"react-dom/client",
|
|
10
|
-
"react-dom/server",
|
|
11
|
-
"react-dom/server.browser"
|
|
12
|
-
],
|
|
8
|
+
"react-dom": ["react-dom/client", "react-dom/profiling"],
|
|
13
9
|
"solid-js": [
|
|
14
10
|
"solid-js/web",
|
|
15
11
|
"solid-js/store",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as normalizePathForImport } from "./buildPaths-BkaQHrd2.js";
|
|
2
|
-
import { _ as mfError, g as createModuleFederationError, l as hasPackageDependency, p as resolveImportPath } from "./dtsConstants-
|
|
2
|
+
import { _ as mfError, g as createModuleFederationError, l as hasPackageDependency, p as resolveImportPath } from "./dtsConstants-CScOzmdO.js";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
5
|
import os from "os";
|
|
@@ -606,7 +606,7 @@ async function importTempModule(filePath, versionKey) {
|
|
|
606
606
|
}
|
|
607
607
|
let warnedVmUnavailable = false;
|
|
608
608
|
async function tryVmStrategy(ssrEntry, options) {
|
|
609
|
-
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-
|
|
609
|
+
const { loadViaVmStrategy, isVmStrategyAvailable } = await import("./ssrVmStrategy-tpI6we9Q.js");
|
|
610
610
|
if (!await isVmStrategyAvailable()) {
|
|
611
611
|
if (!warnedVmUnavailable) {
|
|
612
612
|
warnedVmUnavailable = true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as getCommonSharedSubpaths } from "./pathNormalization-
|
|
2
|
-
import { c as readResponseTextBounded, n as neutralizeBrowserPreloadHelpers, s as fetchWithTimeout, t as SsrEntryHttpError } from "./ssrEntryLoader-
|
|
1
|
+
import { a as getCommonSharedSubpaths } from "./pathNormalization-CHct3UwV.js";
|
|
2
|
+
import { c as readResponseTextBounded, n as neutralizeBrowserPreloadHelpers, s as fetchWithTimeout, t as SsrEntryHttpError } from "./ssrEntryLoader-BMtjS_Vl.js";
|
|
3
3
|
//#region src/utils/ssrVmStrategy.ts
|
|
4
4
|
/**
|
|
5
5
|
* vm.SourceTextModule strategy for loading remote SSR entries.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-
|
|
1
|
+
import { i as ssrEntryLoaderPlugin, n as neutralizeBrowserPreloadHelpers, r as revalidate, t as SsrEntryHttpError } from "../ssrEntryLoader-BMtjS_Vl.js";
|
|
2
2
|
export { SsrEntryHttpError, ssrEntryLoaderPlugin as default, neutralizeBrowserPreloadHelpers, revalidate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.3",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"lib/**/*"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"prepare": "husky
|
|
31
|
+
"prepare": "husky",
|
|
32
32
|
"fmt": "oxfmt src",
|
|
33
33
|
"fmt.check": "oxfmt --check src",
|
|
34
34
|
"dev": "tsdown --watch",
|
|
@@ -93,4 +93,4 @@
|
|
|
93
93
|
"vite": "8.2.0",
|
|
94
94
|
"vitest": "4.1.10"
|
|
95
95
|
}
|
|
96
|
-
}
|
|
96
|
+
}
|