@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.
@@ -0,0 +1,476 @@
1
+ import { existsSync, readFileSync, readdirSync } from "fs";
2
+ import { createRequire } from "module";
3
+ import * as path$1 from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "url";
5
+ //#region src/utils/logger.ts
6
+ const MODULE_FEDERATION_LOG_PREFIX = "[Module Federation]";
7
+ function formatModuleFederationMessage(message) {
8
+ return `${MODULE_FEDERATION_LOG_PREFIX} ${message}`;
9
+ }
10
+ function createModuleFederationError(message) {
11
+ return new Error(formatModuleFederationMessage(message));
12
+ }
13
+ function toConsoleArgs(message, rest = []) {
14
+ if (typeof message === "string") return [formatModuleFederationMessage(message), ...rest];
15
+ if (message === void 0) return [MODULE_FEDERATION_LOG_PREFIX, ...rest];
16
+ return [
17
+ MODULE_FEDERATION_LOG_PREFIX,
18
+ message,
19
+ ...rest
20
+ ];
21
+ }
22
+ const moduleFederationConsole = {
23
+ log(message, ...rest) {
24
+ console.log(...toConsoleArgs(message, rest));
25
+ },
26
+ warn(message, ...rest) {
27
+ console.warn(...toConsoleArgs(message, rest));
28
+ },
29
+ error(message, ...rest) {
30
+ console.error(...toConsoleArgs(message, rest));
31
+ }
32
+ };
33
+ const mfWarn = moduleFederationConsole.warn;
34
+ const mfError = moduleFederationConsole.error;
35
+ //#endregion
36
+ //#region src/utils/packageUtils.ts
37
+ const dependencyPresenceCache = /* @__PURE__ */ new Map();
38
+ let packageDetectionCwd;
39
+ function getDependencyCacheKey(cwd, dependencyName) {
40
+ return `${cwd}:${dependencyName}`;
41
+ }
42
+ const installedPackageJsonCache = /* @__PURE__ */ new Map();
43
+ function setPackageDetectionCwd(cwd) {
44
+ packageDetectionCwd = cwd;
45
+ }
46
+ function getPackageDetectionCwd() {
47
+ return packageDetectionCwd || process.cwd();
48
+ }
49
+ function resolveImportPath(specifier) {
50
+ const resolved = import.meta.resolve(specifier);
51
+ if (!resolved.startsWith("file:")) return resolved;
52
+ const filePath = fileURLToPath(resolved);
53
+ if (!existsSync(filePath)) {
54
+ const error = /* @__PURE__ */ new Error(`Cannot find module '${specifier}'`);
55
+ error.code = "MODULE_NOT_FOUND";
56
+ throw error;
57
+ }
58
+ return filePath;
59
+ }
60
+ const DEFAULT_EXPORT_CONDITIONS = [
61
+ "browser",
62
+ "import",
63
+ "module",
64
+ "default"
65
+ ];
66
+ function resolveExportsEntry(exportsField, conditions = DEFAULT_EXPORT_CONDITIONS) {
67
+ return resolveExportsEntryWithConditions(exportsField, new Set(conditions));
68
+ }
69
+ function resolveExportsEntryWithConditions(exportsField, conditions) {
70
+ if (typeof exportsField === "string") return exportsField;
71
+ if (!exportsField || typeof exportsField !== "object") return void 0;
72
+ if (Array.isArray(exportsField)) {
73
+ for (const target of exportsField) {
74
+ const resolved = resolveExportsEntryWithConditions(target, conditions);
75
+ if (resolved) return resolved;
76
+ }
77
+ return;
78
+ }
79
+ const record = exportsField;
80
+ const rootExport = record["."];
81
+ if (rootExport) return resolveExportsEntryWithConditions(rootExport, conditions);
82
+ for (const [condition, value] of Object.entries(record)) {
83
+ if (condition !== "default" && !conditions.has(condition)) continue;
84
+ const target = resolveExportsEntryWithConditions(value, conditions);
85
+ if (target) return target;
86
+ }
87
+ }
88
+ function substituteExportsWildcard(target, patternMatch) {
89
+ if (typeof target === "string") return target.split("*").join(patternMatch);
90
+ if (Array.isArray(target)) return target.map((entry) => substituteExportsWildcard(entry, patternMatch));
91
+ if (target && typeof target === "object") {
92
+ const source = target;
93
+ const out = {};
94
+ for (const key of Object.keys(source)) out[key] = substituteExportsWildcard(source[key], patternMatch);
95
+ return out;
96
+ }
97
+ return target;
98
+ }
99
+ function matchExportsSubpath(record, subpath) {
100
+ if (subpath in record) return record[subpath];
101
+ let bestKey;
102
+ let bestBaseLength = -1;
103
+ let bestKeyLength = -1;
104
+ for (const key of Object.keys(record)) {
105
+ const wildcardIndex = key.indexOf("*");
106
+ if (wildcardIndex === -1) continue;
107
+ const patternBase = key.slice(0, wildcardIndex);
108
+ const patternTrailer = key.slice(wildcardIndex + 1);
109
+ if (patternTrailer.includes("*")) continue;
110
+ if (!subpath.startsWith(patternBase) || !subpath.endsWith(patternTrailer)) continue;
111
+ if (subpath.length <= patternBase.length + patternTrailer.length) continue;
112
+ if (patternBase.length > bestBaseLength || patternBase.length === bestBaseLength && key.length > bestKeyLength) {
113
+ bestKey = key;
114
+ bestBaseLength = patternBase.length;
115
+ bestKeyLength = key.length;
116
+ }
117
+ }
118
+ if (bestKey === void 0) return void 0;
119
+ const patternTrailer = bestKey.slice(bestKey.indexOf("*") + 1);
120
+ const patternMatch = subpath.slice(bestBaseLength, subpath.length - patternTrailer.length);
121
+ return substituteExportsWildcard(record[bestKey], patternMatch);
122
+ }
123
+ function getPackageExportsTarget(pkg, packageName, exportsField) {
124
+ if (typeof exportsField === "string") return pkg === packageName ? exportsField : void 0;
125
+ if (!exportsField || typeof exportsField !== "object") return void 0;
126
+ const record = exportsField;
127
+ const subpath = pkg === packageName ? "." : `.${pkg.slice(packageName.length)}`;
128
+ if (subpath !== ".") return matchExportsSubpath(record, subpath);
129
+ return record["."] ?? (!Object.keys(record).some((key) => key.startsWith(".")) ? record : void 0);
130
+ }
131
+ /**
132
+ * Escaping rules:
133
+ * Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
134
+ * @ => 1
135
+ * / => 2
136
+ * - => 3
137
+ * . => 4
138
+ */
139
+ /**
140
+ * Encodes a package name into a valid file name.
141
+ * @param {string} name - The package name, e.g., "@scope/xx-xx.xx".
142
+ * @returns {string} - The encoded file name.
143
+ */
144
+ function packageNameEncode(name) {
145
+ if (typeof name !== "string") throw createModuleFederationError("A string package name is required");
146
+ return name.replace(/@/g, "_mf_0_").replace(/\//g, "_mf_1_").replace(/-/g, "_mf_2_").replace(/\./g, "_mf_3_");
147
+ }
148
+ /**
149
+ * Decodes an encoded file name back to the original package name.
150
+ * @param {string} encoded - The encoded file name, e.g., "_mf_0_scope_mf_1_xx_mf_2_xx_mf_3_xx".
151
+ * @returns {string} - The decoded package name.
152
+ */
153
+ function packageNameDecode(encoded) {
154
+ if (typeof encoded !== "string") throw createModuleFederationError("A string encoded file name is required");
155
+ return encoded.replace(/_mf_0_/g, "@").replace(/_mf_1_/g, "/").replace(/_mf_2_/g, "-").replace(/_mf_3_/g, ".");
156
+ }
157
+ /**
158
+ * Removes any subpath from an npm package specifier and returns the package name only.
159
+ * @param {string} packageString - The package specifier, e.g., "@scope/pkg/runtime" or "react/jsx-runtime".
160
+ * @returns {string} - The base npm package name.
161
+ */
162
+ function getPackageName(packageString) {
163
+ const match = packageString.match(/^(?:@[^/]+\/)?[^/]+/);
164
+ return match ? match[0] : packageString;
165
+ }
166
+ function getPackageNameFromNodeModulePath(source) {
167
+ const normalized = source.replace(/\\/g, "/");
168
+ const nodeModulesIndex = normalized.lastIndexOf("/node_modules/");
169
+ if (nodeModulesIndex < 0) return;
170
+ const parts = normalized.slice(nodeModulesIndex + 14).split("/");
171
+ if (!parts[0]) return;
172
+ if (parts[0].startsWith("@")) return parts[1] ? `${parts[0]}/${parts[1]}` : void 0;
173
+ return parts[0];
174
+ }
175
+ function getSharedCacheKeyParts(input) {
176
+ const scope = (Array.isArray(input.scope) ? input.scope[0] : input.scope) || "default";
177
+ const id = input.singleton || !input.version ? input.pkg : `${input.pkg}@${input.version}`;
178
+ return {
179
+ scope,
180
+ id,
181
+ key: `${scope}:${id}`
182
+ };
183
+ }
184
+ function getSharedCacheDescriptor(pkg, shareItem) {
185
+ const parts = getSharedCacheKeyParts({
186
+ pkg,
187
+ singleton: shareItem.shareConfig.singleton,
188
+ version: shareItem.version,
189
+ scope: shareItem.scope
190
+ });
191
+ return {
192
+ canonical: parts.key,
193
+ ...parts.scope === "default" ? { aliases: [parts.id] } : {}
194
+ };
195
+ }
196
+ const sharedCacheHelperCode = `const __mfGetSharedCacheDescriptor = (pkg, singleton, version, scope) => {
197
+ const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
198
+ const scopeName = normalizedScope || "default";
199
+ const id = singleton || !version ? pkg : pkg + "@" + version;
200
+ const descriptor = { canonical: scopeName + ":" + id };
201
+ if (scopeName === "default") descriptor.aliases = [id];
202
+ return descriptor;
203
+ };
204
+ const __mfReadSharedCache = (cache, descriptor) => {
205
+ const value = cache[descriptor.canonical];
206
+ if (value !== undefined) return value;
207
+ const aliases = descriptor.aliases || [];
208
+ for (const alias of aliases) {
209
+ if (!Object.prototype.hasOwnProperty.call(cache, alias)) continue;
210
+ const aliasValue = cache[alias];
211
+ if (aliasValue !== undefined) {
212
+ cache[descriptor.canonical] = aliasValue;
213
+ return aliasValue;
214
+ }
215
+ }
216
+ return undefined;
217
+ };
218
+ const __mfSharedCacheListenersKey = Symbol.for("module-federation.shared-cache-listeners");
219
+ const __mfGetSharedCacheListeners = (cache) => {
220
+ let listeners = cache[__mfSharedCacheListenersKey];
221
+ if (listeners === undefined) {
222
+ listeners = Object.create(null);
223
+ Object.defineProperty(cache, __mfSharedCacheListenersKey, {
224
+ value: listeners,
225
+ enumerable: false,
226
+ configurable: false,
227
+ writable: false
228
+ });
229
+ }
230
+ return listeners;
231
+ };
232
+ const __mfSubscribeSharedCache = (cache, descriptor, listener) => {
233
+ const listeners = __mfGetSharedCacheListeners(cache);
234
+ (listeners[descriptor.canonical] ||= new Set()).add(listener);
235
+ };
236
+ const __mfSharedCacheOwnersKey = Symbol.for("module-federation.shared-cache-owners");
237
+ const __mfGetSharedCacheOwners = (cache) => {
238
+ let owners = cache[__mfSharedCacheOwnersKey];
239
+ if (owners === undefined) {
240
+ owners = Object.create(null);
241
+ Object.defineProperty(cache, __mfSharedCacheOwnersKey, {
242
+ value: owners,
243
+ enumerable: false,
244
+ configurable: false,
245
+ writable: false
246
+ });
247
+ }
248
+ return owners;
249
+ };
250
+ const __mfReadSharedCacheOwner = (cache, descriptor) =>
251
+ cache[__mfSharedCacheOwnersKey]?.[descriptor.canonical];
252
+ const __mfWriteSharedCache = (cache, descriptor, value, owner) => {
253
+ cache[descriptor.canonical] = value;
254
+ const aliases = descriptor.aliases || [];
255
+ for (const alias of aliases) {
256
+ Object.defineProperty(cache, alias, {
257
+ value,
258
+ enumerable: true,
259
+ configurable: true,
260
+ writable: true
261
+ });
262
+ }
263
+ const owners = cache[__mfSharedCacheOwnersKey];
264
+ if (owner === undefined) {
265
+ if (owners) delete owners[descriptor.canonical];
266
+ } else {
267
+ __mfGetSharedCacheOwners(cache)[descriptor.canonical] = owner;
268
+ }
269
+ const listeners = cache[__mfSharedCacheListenersKey]?.[descriptor.canonical];
270
+ if (listeners) {
271
+ for (const listener of listeners) listener(value);
272
+ }
273
+ return value;
274
+ };
275
+ const __mfTreeShakingSharedCacheKey = Symbol.for("module-federation.tree-shaking-shared-cache");
276
+ const __mfGetTreeShakingSharedCache = (cache) => {
277
+ let metadata = cache[__mfTreeShakingSharedCacheKey];
278
+ if (metadata === undefined) {
279
+ metadata = Object.create(null);
280
+ Object.defineProperty(cache, __mfTreeShakingSharedCacheKey, {
281
+ value: metadata,
282
+ enumerable: false,
283
+ configurable: false,
284
+ writable: false
285
+ });
286
+ }
287
+ return metadata;
288
+ };
289
+ const __mfReadTreeShakingSharedCache = (cache, descriptor, requiredExports) => {
290
+ const fullModule = __mfReadSharedCache(cache, descriptor);
291
+ if (fullModule !== undefined) return fullModule;
292
+ if (!Array.isArray(requiredExports)) return undefined;
293
+ const metadata = cache[__mfTreeShakingSharedCacheKey];
294
+ const entries = metadata?.[descriptor.canonical] || [];
295
+ let compatibleEntry;
296
+ for (const entry of entries) {
297
+ if (!requiredExports.every((name) => entry.providedExports.includes(name))) continue;
298
+ if (!compatibleEntry || entry.providedExports.length < compatibleEntry.providedExports.length) {
299
+ compatibleEntry = entry;
300
+ }
301
+ }
302
+ return compatibleEntry?.value;
303
+ };
304
+ const __mfWriteTreeShakingSharedCache = (cache, descriptor, providedExports, value) => {
305
+ if (!Array.isArray(providedExports)) return value;
306
+ const normalizedExports = [...new Set(providedExports)].sort();
307
+ const metadata = __mfGetTreeShakingSharedCache(cache);
308
+ const entries = (metadata[descriptor.canonical] ||= []);
309
+ const existing = entries.find((entry) =>
310
+ entry.providedExports.length === normalizedExports.length &&
311
+ entry.providedExports.every((name, index) => name === normalizedExports[index])
312
+ );
313
+ if (existing) existing.value = value;
314
+ else entries.push({ providedExports: normalizedExports, value });
315
+ return value;
316
+ };
317
+ const __mfTreeShakingSelectionCacheKey = Symbol.for("module-federation.tree-shaking-shared-selection-cache");
318
+ const __mfGetTreeShakingSelectionCache = (cache) => {
319
+ let selections = cache[__mfTreeShakingSelectionCacheKey];
320
+ if (selections === undefined) {
321
+ selections = Object.create(null);
322
+ Object.defineProperty(cache, __mfTreeShakingSelectionCacheKey, {
323
+ value: selections,
324
+ enumerable: false,
325
+ configurable: false,
326
+ writable: false
327
+ });
328
+ }
329
+ return selections;
330
+ };
331
+ const __mfReadTreeShakingSharedSelection = (cache, descriptor, consumer) => {
332
+ const fullModule = __mfReadSharedCache(cache, descriptor);
333
+ if (fullModule !== undefined) return fullModule;
334
+ return cache[__mfTreeShakingSelectionCacheKey]?.[descriptor.canonical]?.[consumer];
335
+ };
336
+ const __mfWriteTreeShakingSharedSelection = (cache, descriptor, consumer, value) => {
337
+ const selections = __mfGetTreeShakingSelectionCache(cache);
338
+ const byConsumer = (selections[descriptor.canonical] ||= Object.create(null));
339
+ byConsumer[consumer] = value;
340
+ return value;
341
+ };`;
342
+ function getInstalledPackageJson(pkg, opts) {
343
+ const cwd = opts?.cwd || getPackageDetectionCwd();
344
+ const packageName = opts?.packageName || getPackageName(pkg);
345
+ const cacheKey = `${cwd}\0${pkg}\0${packageName}\0${opts?.fromResolvedEntry ?? ""}`;
346
+ if (installedPackageJsonCache.has(cacheKey)) return installedPackageJsonCache.get(cacheKey);
347
+ const result = resolveInstalledPackageJson(pkg, cwd, packageName, opts);
348
+ installedPackageJsonCache.set(cacheKey, result);
349
+ return result;
350
+ }
351
+ function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
352
+ const tryReadPackageJson = (packageJsonPath) => {
353
+ if (!existsSync(packageJsonPath)) return void 0;
354
+ try {
355
+ return {
356
+ path: packageJsonPath,
357
+ dir: path$1.dirname(packageJsonPath),
358
+ packageJson: JSON.parse(readFileSync(packageJsonPath, "utf-8"))
359
+ };
360
+ } catch {
361
+ return;
362
+ }
363
+ };
364
+ const findPackageInPnpmStore = (startDir) => {
365
+ let currentDir = startDir;
366
+ const rootDir = path$1.parse(currentDir).root;
367
+ while (true) {
368
+ const pnpmStoreDir = path$1.join(currentDir, "node_modules", ".pnpm");
369
+ if (existsSync(pnpmStoreDir)) try {
370
+ for (const entry of readdirSync(pnpmStoreDir, { withFileTypes: true })) {
371
+ if (!entry.isDirectory()) continue;
372
+ const candidate = tryReadPackageJson(path$1.join(pnpmStoreDir, entry.name, "node_modules", packageName, "package.json"));
373
+ if (candidate?.packageJson.name === packageName) return candidate;
374
+ }
375
+ } catch {}
376
+ if (currentDir === rootDir) break;
377
+ currentDir = path$1.dirname(currentDir);
378
+ }
379
+ };
380
+ try {
381
+ const projectRequire = createRequire(pathToFileURL(path$1.join(cwd, "package.json")));
382
+ let resolvedPath;
383
+ if (opts?.fromResolvedEntry) resolvedPath = opts.fromResolvedEntry;
384
+ else try {
385
+ resolvedPath = projectRequire.resolve(pkg);
386
+ } catch {
387
+ resolvedPath = projectRequire.resolve(packageName);
388
+ }
389
+ let currentDir = path$1.dirname(resolvedPath);
390
+ const rootDir = path$1.parse(currentDir).root;
391
+ while (true) {
392
+ const packageJsonPath = path$1.join(currentDir, "package.json");
393
+ if (existsSync(packageJsonPath)) {
394
+ const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
395
+ try {
396
+ const packageJson = JSON.parse(packageJsonContent);
397
+ if (packageJson.name === packageName) return {
398
+ path: packageJsonPath,
399
+ dir: currentDir,
400
+ packageJson
401
+ };
402
+ } catch (error) {
403
+ if (!(error instanceof SyntaxError)) throw error;
404
+ }
405
+ }
406
+ if (currentDir === rootDir) break;
407
+ currentDir = path$1.dirname(currentDir);
408
+ }
409
+ } catch {
410
+ let currentDir = cwd;
411
+ const rootDir = path$1.parse(currentDir).root;
412
+ while (true) {
413
+ const directCandidate = tryReadPackageJson(path$1.join(currentDir, "node_modules", packageName, "package.json"));
414
+ if (directCandidate?.packageJson.name === packageName) return directCandidate;
415
+ if (currentDir === rootDir) break;
416
+ currentDir = path$1.dirname(currentDir);
417
+ }
418
+ return findPackageInPnpmStore(cwd);
419
+ }
420
+ }
421
+ function getInstalledPackageEntry(pkg, opts) {
422
+ const installed = getInstalledPackageJson(pkg, opts);
423
+ if (!installed) return void 0;
424
+ const cwd = opts?.cwd || getPackageDetectionCwd();
425
+ const packageName = opts?.packageName || getPackageName(pkg);
426
+ const packageJson = installed.packageJson;
427
+ if (pkg !== packageName && (opts?.resolveSubpathWithRequire !== false || packageJson.exports === void 0)) try {
428
+ return createRequire(pathToFileURL(path$1.join(cwd, "package.json"))).resolve(pkg);
429
+ } catch {}
430
+ 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";
431
+ return path$1.join(installed.dir, explicitEntry);
432
+ }
433
+ /**
434
+ * Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
435
+ * on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
436
+ */
437
+ function getIsRolldown(ctx) {
438
+ const viteVersion = ctx?.meta?.viteVersion;
439
+ const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
440
+ return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
441
+ }
442
+ /** Walk up from Vite `config.root` (Nuxt may point at `.nuxt` cache dirs). */
443
+ function isNuxtProjectRoot(root) {
444
+ let dir = root;
445
+ for (let i = 0; i < 8; i++) {
446
+ if (hasPackageDependency("nuxt", dir) || hasPackageDependency("nuxt-nightly", dir)) return true;
447
+ const parent = path$1.dirname(dir);
448
+ if (parent === dir) break;
449
+ dir = parent;
450
+ }
451
+ return false;
452
+ }
453
+ function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
454
+ const cacheKey = getDependencyCacheKey(cwd, dependencyName);
455
+ const cached = dependencyPresenceCache.get(cacheKey);
456
+ if (cached !== void 0) return cached;
457
+ try {
458
+ const packageJson = JSON.parse(readFileSync(path$1.join(cwd, "package.json"), "utf8"));
459
+ const hasDependency = [
460
+ packageJson.dependencies,
461
+ packageJson.devDependencies,
462
+ packageJson.peerDependencies,
463
+ packageJson.optionalDependencies
464
+ ].some((deps) => !!deps?.[dependencyName]);
465
+ dependencyPresenceCache.set(cacheKey, hasDependency);
466
+ return hasDependency;
467
+ } catch {
468
+ dependencyPresenceCache.set(cacheKey, false);
469
+ return false;
470
+ }
471
+ }
472
+ //#endregion
473
+ //#region src/utils/dtsConstants.ts
474
+ const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
475
+ //#endregion
476
+ export { mfError as _, getPackageDetectionCwd as a, getSharedCacheDescriptor as c, packageNameDecode as d, packageNameEncode as f, createModuleFederationError as g, sharedCacheHelperCode as h, getIsRolldown as i, hasPackageDependency as l, setPackageDetectionCwd as m, getInstalledPackageEntry as n, getPackageName as o, resolveImportPath as p, getInstalledPackageJson as r, getPackageNameFromNodeModulePath as s, DEFAULT_PUBLIC_TYPES_FOLDER as t, isNuxtProjectRoot as u, mfWarn as v };