@module-federation/metro 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/babel/transformer.js +1 -1
  2. package/dist/commands/bundle-host/index.js +5 -4
  3. package/dist/commands/bundle-host/index.mjs +5 -26
  4. package/dist/commands/bundle-remote/index.js +22 -11
  5. package/dist/commands/bundle-remote/index.mjs +22 -32
  6. package/dist/commands/utils/create-resolver.d.ts +1 -1
  7. package/dist/commands/utils/get-community-plugin.d.ts +1 -2
  8. package/dist/commands/utils/get-community-plugin.js +3 -4
  9. package/dist/commands/utils/get-community-plugin.mjs +3 -4
  10. package/dist/commands/utils/path-utils.d.ts +2 -0
  11. package/dist/commands/utils/path-utils.js +47 -0
  12. package/dist/commands/utils/path-utils.mjs +12 -0
  13. package/dist/commands/utils/save-bundle-and-map.d.ts +1 -1
  14. package/dist/commands/utils/save-bundle-and-map.js +2 -3
  15. package/dist/commands/utils/save-bundle-and-map.mjs +2 -25
  16. package/dist/logger.d.ts +2 -0
  17. package/dist/logger.js +39 -0
  18. package/dist/logger.mjs +7 -0
  19. package/dist/modules/asyncRequire.ts +0 -3
  20. package/dist/modules/asyncStartup.tsx +1 -0
  21. package/dist/modules/metroCorePlugin.ts +3 -3
  22. package/dist/plugin/babel-transformer.js +1 -1
  23. package/dist/plugin/babel-transformer.mjs +1 -1
  24. package/dist/plugin/constants.d.ts +1 -0
  25. package/dist/plugin/constants.js +4 -0
  26. package/dist/plugin/constants.mjs +2 -1
  27. package/dist/plugin/generators.js +6 -3
  28. package/dist/plugin/generators.mjs +6 -3
  29. package/dist/plugin/helpers.d.ts +1 -0
  30. package/dist/plugin/helpers.js +11 -5
  31. package/dist/plugin/helpers.mjs +4 -1
  32. package/dist/plugin/index.d.ts +2 -0
  33. package/dist/plugin/index.js +33 -1
  34. package/dist/plugin/index.mjs +33 -1
  35. package/dist/plugin/manifest.js +8 -2
  36. package/dist/plugin/manifest.mjs +8 -2
  37. package/dist/plugin/normalize-options.js +57 -8
  38. package/dist/plugin/normalize-options.mjs +57 -8
  39. package/dist/plugin/resolver.js +1 -1
  40. package/dist/plugin/resolver.mjs +2 -2
  41. package/dist/plugin/rewrite-request.d.ts +5 -1
  42. package/dist/plugin/rewrite-request.js +11 -2
  43. package/dist/plugin/rewrite-request.mjs +12 -3
  44. package/dist/plugin/serializer.js +24 -9
  45. package/dist/plugin/serializer.mjs +24 -31
  46. package/dist/plugin/validate-options.js +106 -5
  47. package/dist/plugin/validate-options.mjs +95 -5
  48. package/dist/types.d.ts +15 -15
  49. package/dist/utils/federated-remote-types.d.ts +12 -0
  50. package/dist/utils/federated-remote-types.js +159 -0
  51. package/dist/utils/federated-remote-types.mjs +91 -0
  52. package/dist/utils/metro-compat.d.ts +23 -0
  53. package/dist/utils/metro-compat.js +70 -0
  54. package/dist/utils/metro-compat.mjs +26 -0
  55. package/dist/utils/vm-manager.d.ts +1 -1
  56. package/package.json +7 -3
  57. package/dist/babel/transformer.d.ts +0 -2
  58. package/dist/runtime/host-entry.d.ts +0 -1
  59. package/dist/runtime/init-host.d.ts +0 -1
  60. package/dist/runtime/remote-entry.d.ts +0 -1
  61. package/dist/runtime/remote-hmr.d.ts +0 -1
  62. package/dist/runtime/remote-module-registry.d.ts +0 -7
  63. package/dist/runtime/remote-module.d.ts +0 -1
@@ -0,0 +1,91 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
3
+ import { promises } from "node:fs";
4
+ import node_util from "node:util";
5
+ async function maybeGenerateFederatedRemoteTypes(opts) {
6
+ const { federationConfig, projectRoot, outputDir, logger } = opts;
7
+ if (false === federationConfig.dts) return;
8
+ const dtsPlugin = await import("@module-federation/dts-plugin");
9
+ const dtsPluginCore = await import("@module-federation/dts-plugin/core");
10
+ const dtsConfig = true === federationConfig.dts ? {
11
+ consumeTypes: false
12
+ } : 'object' != typeof federationConfig.dts || null === federationConfig.dts || Object.prototype.hasOwnProperty.call(federationConfig.dts, 'consumeTypes') ? federationConfig.dts : {
13
+ ...federationConfig.dts,
14
+ consumeTypes: false
15
+ };
16
+ const mfOptions = {
17
+ name: federationConfig.name,
18
+ filename: federationConfig.filename,
19
+ remotes: federationConfig.remotes,
20
+ exposes: federationConfig.exposes,
21
+ shared: federationConfig.shared,
22
+ dts: dtsConfig
23
+ };
24
+ const normalizedDtsOptions = dtsPlugin.normalizeDtsOptions(mfOptions, projectRoot, {
25
+ defaultGenerateOptions: {
26
+ generateAPITypes: true,
27
+ compileInChildProcess: false,
28
+ abortOnError: false,
29
+ extractThirdParty: false,
30
+ extractRemoteTypes: false
31
+ },
32
+ defaultConsumeOptions: {
33
+ abortOnError: true,
34
+ consumeAPITypes: true
35
+ }
36
+ });
37
+ if (!normalizedDtsOptions) return;
38
+ const dtsManagerOptions = dtsPlugin.normalizeGenerateTypesOptions({
39
+ context: projectRoot,
40
+ outputDir,
41
+ dtsOptions: normalizedDtsOptions,
42
+ pluginOptions: mfOptions
43
+ });
44
+ if (!dtsManagerOptions) return;
45
+ if (dtsManagerOptions.host) {
46
+ let remoteTypeUrls = dtsManagerOptions.host.remoteTypeUrls;
47
+ if ('function' == typeof remoteTypeUrls) remoteTypeUrls = await remoteTypeUrls();
48
+ await dtsPluginCore.consumeTypes({
49
+ ...dtsManagerOptions,
50
+ host: {
51
+ ...dtsManagerOptions.host,
52
+ remoteTypeUrls
53
+ }
54
+ });
55
+ }
56
+ logger.info(`${node_util.styleText('blue', 'Generating federated types (d.ts)')}`);
57
+ await dtsPlugin.generateTypesAPI({
58
+ dtsManagerOptions
59
+ });
60
+ const { zipTypesPath, apiTypesPath, zipName, apiFileName } = dtsPluginCore.retrieveTypesAssetsInfo(dtsManagerOptions.remote);
61
+ const produced = {};
62
+ const fileExists = async (p)=>{
63
+ try {
64
+ await promises.stat(p);
65
+ return true;
66
+ } catch {
67
+ return false;
68
+ }
69
+ };
70
+ if (zipTypesPath && zipName && await fileExists(zipTypesPath)) produced.zipName = zipName;
71
+ if (apiTypesPath && apiFileName && await fileExists(apiTypesPath)) produced.apiFileName = apiFileName;
72
+ if (process.env['FEDERATION_DEBUG']) logger.info(`dts debug: zipTypesPath=${zipTypesPath} zipExists=${String(Boolean(produced.zipName))} apiTypesPath=${apiTypesPath} apiExists=${String(Boolean(produced.apiFileName))}`);
73
+ if (!produced.zipName && !produced.apiFileName) return void logger.warn(`${node_util.styleText('yellow', 'Federated types enabled, but no types files were produced.')}`);
74
+ logger.info(`Done writing federated types:\n${node_util.styleText('dim', [
75
+ produced.zipName,
76
+ produced.apiFileName
77
+ ].filter(Boolean).join('\n'))}`);
78
+ return {
79
+ zipName: produced.zipName ?? '',
80
+ apiFileName: produced.apiFileName ?? ''
81
+ };
82
+ }
83
+ function applyTypesMetaToManifest(manifest, typesMeta) {
84
+ if (!(null == typesMeta ? void 0 : typesMeta.zipName) && !(null == typesMeta ? void 0 : typesMeta.apiFileName)) return manifest;
85
+ manifest.metaData = manifest.metaData || {};
86
+ manifest.metaData.types = manifest.metaData.types || {};
87
+ if (typesMeta.zipName) manifest.metaData.types.zip = typesMeta.zipName;
88
+ if (typesMeta.apiFileName) manifest.metaData.types.api = typesMeta.apiFileName;
89
+ return manifest;
90
+ }
91
+ export { applyTypesMetaToManifest, maybeGenerateFederatedRemoteTypes };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Metro Compatibility Layer
3
+ *
4
+ * Provides backwards-compatible imports for Metro 0.82 and 0.83+
5
+ *
6
+ * Metro 0.83 introduced a restrictive `exports` field that only allows
7
+ * `metro/private/*` paths instead of direct `metro/src/*` imports.
8
+ *
9
+ * This module dynamically resolves the correct import path based on the
10
+ * installed Metro version, ensuring compatibility with both versions.
11
+ */
12
+ import type DefaultServer from 'metro/src/Server';
13
+ import type DefaultBaseJSBundle from 'metro/src/DeltaBundler/Serializers/baseJSBundle';
14
+ import type DefaultCountingSet from 'metro/src/lib/CountingSet';
15
+ import type DefaultBundleToString from 'metro/src/lib/bundleToString';
16
+ import type { MixedSourceMap } from 'metro-source-map';
17
+ export declare const Server: typeof DefaultServer;
18
+ export type Server = DefaultServer;
19
+ export declare const baseJSBundle: typeof DefaultBaseJSBundle;
20
+ export declare const CountingSet: typeof DefaultCountingSet;
21
+ export declare const bundleToString: typeof DefaultBundleToString;
22
+ export declare const relativizeSourceMapInline: (sourceMap: MixedSourceMap, sourcesRoot: string) => void;
23
+ export type { RequestOptions, OutputOptions } from 'metro/src/shared/types';
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ CountingSet: ()=>CountingSet,
28
+ Server: ()=>Server,
29
+ baseJSBundle: ()=>baseJSBundle,
30
+ bundleToString: ()=>bundleToString,
31
+ relativizeSourceMapInline: ()=>relativizeSourceMapInline
32
+ });
33
+ function resolveAndImport(metro83Path, metro82Path) {
34
+ let resolvedPath;
35
+ try {
36
+ resolvedPath = require.resolve(metro83Path);
37
+ } catch {
38
+ try {
39
+ resolvedPath = require.resolve(metro82Path);
40
+ } catch {
41
+ throw new Error(`Could not resolve 'metro' module. Tried:\n - ${metro83Path}\n - ${metro82Path}\nEnsure 'metro' is installed.`);
42
+ }
43
+ }
44
+ return require(resolvedPath);
45
+ }
46
+ function getDefaultExport(mod) {
47
+ if (null != mod && 'object' == typeof mod && 'default' in mod) return mod.default;
48
+ return mod;
49
+ }
50
+ const Server = getDefaultExport(resolveAndImport('metro/private/Server', 'metro/src/Server'));
51
+ const baseJSBundle = getDefaultExport(resolveAndImport('metro/private/DeltaBundler/Serializers/baseJSBundle', 'metro/src/DeltaBundler/Serializers/baseJSBundle'));
52
+ const CountingSet = getDefaultExport(resolveAndImport('metro/private/lib/CountingSet', 'metro/src/lib/CountingSet'));
53
+ const bundleToString = getDefaultExport(resolveAndImport('metro/private/lib/bundleToString', 'metro/src/lib/bundleToString'));
54
+ const relativizeSourceMapModule = resolveAndImport('metro/private/lib/relativizeSourceMap', 'metro/src/lib/relativizeSourceMap');
55
+ const relativizeSourceMapInline = relativizeSourceMapModule.relativizeSourceMapInline || getDefaultExport(relativizeSourceMapModule);
56
+ exports.CountingSet = __webpack_exports__.CountingSet;
57
+ exports.Server = __webpack_exports__.Server;
58
+ exports.baseJSBundle = __webpack_exports__.baseJSBundle;
59
+ exports.bundleToString = __webpack_exports__.bundleToString;
60
+ exports.relativizeSourceMapInline = __webpack_exports__.relativizeSourceMapInline;
61
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
62
+ "CountingSet",
63
+ "Server",
64
+ "baseJSBundle",
65
+ "bundleToString",
66
+ "relativizeSourceMapInline"
67
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
68
+ Object.defineProperty(exports, '__esModule', {
69
+ value: true
70
+ });
@@ -0,0 +1,26 @@
1
+ import __rslib_shim_module__ from 'module';
2
+ const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.url);
3
+ function resolveAndImport(metro83Path, metro82Path) {
4
+ let resolvedPath;
5
+ try {
6
+ resolvedPath = require.resolve(metro83Path);
7
+ } catch {
8
+ try {
9
+ resolvedPath = require.resolve(metro82Path);
10
+ } catch {
11
+ throw new Error(`Could not resolve 'metro' module. Tried:\n - ${metro83Path}\n - ${metro82Path}\nEnsure 'metro' is installed.`);
12
+ }
13
+ }
14
+ return require(resolvedPath);
15
+ }
16
+ function getDefaultExport(mod) {
17
+ if (null != mod && 'object' == typeof mod && 'default' in mod) return mod.default;
18
+ return mod;
19
+ }
20
+ const Server = getDefaultExport(resolveAndImport('metro/private/Server', 'metro/src/Server'));
21
+ const baseJSBundle = getDefaultExport(resolveAndImport('metro/private/DeltaBundler/Serializers/baseJSBundle', 'metro/src/DeltaBundler/Serializers/baseJSBundle'));
22
+ const CountingSet = getDefaultExport(resolveAndImport('metro/private/lib/CountingSet', 'metro/src/lib/CountingSet'));
23
+ const bundleToString = getDefaultExport(resolveAndImport('metro/private/lib/bundleToString', 'metro/src/lib/bundleToString'));
24
+ const relativizeSourceMapModule = resolveAndImport('metro/private/lib/relativizeSourceMap', 'metro/src/lib/relativizeSourceMap');
25
+ const relativizeSourceMapInline = relativizeSourceMapModule.relativizeSourceMapInline || getDefaultExport(relativizeSourceMapModule);
26
+ export { CountingSet, Server, baseJSBundle, bundleToString, relativizeSourceMapInline };
@@ -1,5 +1,5 @@
1
1
  import type { MetroConfig, ServerConfigT, TransformerConfigT } from 'metro-config';
2
- import type MetroServer from 'metro/src/Server';
2
+ import type { Server as MetroServer } from './metro-compat';
3
3
  type EnhanceMiddleware = ServerConfigT['enhanceMiddleware'];
4
4
  type GetTransformOptions = TransformerConfigT['getTransformOptions'];
5
5
  type Bundler = ReturnType<ReturnType<MetroServer['getBundler']>['getBundler']>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/metro",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Module Federation for Metro bundler",
5
5
  "keywords": [
6
6
  "module-federation",
@@ -57,8 +57,9 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@expo/metro-runtime": "^5.0.4",
60
- "@module-federation/runtime": "2.0.0",
61
- "@module-federation/sdk": "2.0.0"
60
+ "@module-federation/dts-plugin": "2.1.0",
61
+ "@module-federation/sdk": "2.1.0",
62
+ "@module-federation/runtime": "2.1.0"
62
63
  },
63
64
  "peerDependencies": {
64
65
  "@babel/types": "^7.25.0",
@@ -84,6 +85,7 @@
84
85
  "@typescript-eslint/parser": "8.54.0",
85
86
  "@types/node": "^20.19.5",
86
87
  "@types/react": "^19.1.0",
88
+ "memfs": "4.46.0",
87
89
  "metro": "^0.82.1",
88
90
  "metro-config": "^0.82.1",
89
91
  "metro-file-map": "^0.82.1",
@@ -96,6 +98,8 @@
96
98
  },
97
99
  "scripts": {
98
100
  "build": "rslib build",
101
+ "test": "vitest run --config vitest.config.mts",
102
+ "test:watch": "vitest --config vitest.config.mts",
99
103
  "typecheck": "tsc --noEmit"
100
104
  }
101
105
  }
@@ -1,2 +0,0 @@
1
- declare const _exports: any;
2
- export = _exports;
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export function setup(): void;
@@ -1,7 +0,0 @@
1
- export function loadAndGetShared(id: any): Promise<any>;
2
- export function loadAndGetRemote(id: any): Promise<any>;
3
- export function loadRemoteToRegistry(id: any): Promise<void>;
4
- export function loadSharedToRegistry(id: any): void | Promise<void>;
5
- export function loadSharedToRegistryAsync(id: any): Promise<void>;
6
- export function loadSharedToRegistrySync(id: any): void;
7
- export function getModuleFromRegistry(id: any): any;
@@ -1 +0,0 @@
1
- export {};