@module-federation/metro 2.0.1 → 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 (52) hide show
  1. package/dist/babel/transformer.js +1 -1
  2. package/dist/commands/bundle-host/index.js +3 -1
  3. package/dist/commands/bundle-host/index.mjs +3 -1
  4. package/dist/commands/bundle-remote/index.js +19 -7
  5. package/dist/commands/bundle-remote/index.mjs +19 -7
  6. package/dist/commands/utils/path-utils.d.ts +2 -0
  7. package/dist/commands/utils/path-utils.js +47 -0
  8. package/dist/commands/utils/path-utils.mjs +12 -0
  9. package/dist/logger.d.ts +2 -0
  10. package/dist/logger.js +39 -0
  11. package/dist/logger.mjs +7 -0
  12. package/dist/modules/asyncRequire.ts +0 -3
  13. package/dist/modules/asyncStartup.tsx +1 -0
  14. package/dist/modules/metroCorePlugin.ts +3 -3
  15. package/dist/plugin/babel-transformer.js +1 -1
  16. package/dist/plugin/babel-transformer.mjs +1 -1
  17. package/dist/plugin/constants.d.ts +1 -0
  18. package/dist/plugin/constants.js +4 -0
  19. package/dist/plugin/constants.mjs +2 -1
  20. package/dist/plugin/generators.js +6 -3
  21. package/dist/plugin/generators.mjs +6 -3
  22. package/dist/plugin/helpers.d.ts +1 -0
  23. package/dist/plugin/helpers.js +11 -5
  24. package/dist/plugin/helpers.mjs +4 -1
  25. package/dist/plugin/index.d.ts +2 -0
  26. package/dist/plugin/index.js +33 -1
  27. package/dist/plugin/index.mjs +33 -1
  28. package/dist/plugin/manifest.js +8 -2
  29. package/dist/plugin/manifest.mjs +8 -2
  30. package/dist/plugin/normalize-options.js +57 -8
  31. package/dist/plugin/normalize-options.mjs +57 -8
  32. package/dist/plugin/resolver.js +1 -1
  33. package/dist/plugin/resolver.mjs +2 -2
  34. package/dist/plugin/rewrite-request.d.ts +5 -1
  35. package/dist/plugin/rewrite-request.js +11 -2
  36. package/dist/plugin/rewrite-request.mjs +12 -3
  37. package/dist/plugin/serializer.js +21 -1
  38. package/dist/plugin/serializer.mjs +21 -1
  39. package/dist/plugin/validate-options.js +106 -5
  40. package/dist/plugin/validate-options.mjs +95 -5
  41. package/dist/types.d.ts +15 -15
  42. package/dist/utils/federated-remote-types.d.ts +12 -0
  43. package/dist/utils/federated-remote-types.js +159 -0
  44. package/dist/utils/federated-remote-types.mjs +91 -0
  45. package/package.json +7 -3
  46. package/dist/babel/transformer.d.ts +0 -2
  47. package/dist/runtime/host-entry.d.ts +0 -1
  48. package/dist/runtime/init-host.d.ts +0 -1
  49. package/dist/runtime/remote-entry.d.ts +0 -1
  50. package/dist/runtime/remote-hmr.d.ts +0 -1
  51. package/dist/runtime/remote-module-registry.d.ts +0 -7
  52. package/dist/runtime/remote-module.d.ts +0 -1
@@ -1,5 +1,14 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
3
12
  (()=>{
4
13
  __webpack_require__.d = (exports1, definition)=>{
5
14
  for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
@@ -26,8 +35,41 @@ __webpack_require__.r(__webpack_exports__);
26
35
  __webpack_require__.d(__webpack_exports__, {
27
36
  validateOptions: ()=>validateOptions
28
37
  });
38
+ const external_node_path_namespaceObject = require("node:path");
39
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
40
+ const external_logger_js_namespaceObject = require("../logger.js");
41
+ var external_logger_js_default = /*#__PURE__*/ __webpack_require__.n(external_logger_js_namespaceObject);
29
42
  const index_js_namespaceObject = require("../utils/index.js");
43
+ const unsupportedTopLevelOptions = [
44
+ 'library',
45
+ 'remoteType',
46
+ 'runtime',
47
+ 'shareScope',
48
+ 'getPublicPath',
49
+ 'implementation',
50
+ 'manifest',
51
+ 'dev',
52
+ 'dataPrefetch',
53
+ 'virtualRuntimeEntry',
54
+ 'experiments',
55
+ 'bridge',
56
+ 'async',
57
+ 'treeShakingDir',
58
+ 'injectTreeShakingUsedExports',
59
+ 'treeShakingSharedExcludePlugins',
60
+ 'treeShakingSharedPlugins'
61
+ ];
62
+ const unsupportedSharedFields = [
63
+ 'packageName',
64
+ 'shareKey',
65
+ 'shareScope',
66
+ 'strictVersion',
67
+ 'treeShaking',
68
+ 'shareStrategy'
69
+ ];
70
+ const warningSet = new Set();
30
71
  function validateName(name) {
72
+ if (!name || 'string' != typeof name) throw new index_js_namespaceObject.ConfigError("Option 'name' is required.");
31
73
  const validEcmaIdentifierRegex = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
32
74
  if (!validEcmaIdentifierRegex.test(name)) throw new index_js_namespaceObject.ConfigError(`Invalid 'name': ${name}. The 'name' must be a valid JavaScript identifier.`);
33
75
  }
@@ -39,17 +81,76 @@ function validateShared(shared) {
39
81
  if (!shared) throw new index_js_namespaceObject.ConfigError('Shared configuration is required.');
40
82
  if ('object' != typeof shared) throw new index_js_namespaceObject.ConfigError('Shared must be an object.');
41
83
  if (Array.isArray(shared)) throw new index_js_namespaceObject.ConfigError('Array format is not supported for shared.');
42
- if (!('react' in shared)) throw new index_js_namespaceObject.ConfigError("Dependency 'react' must be present in shared.");
43
- if (!('react-native' in shared)) throw new index_js_namespaceObject.ConfigError("Dependency 'react-native' must be present in shared.");
44
- for (const sharedName of Object.keys(shared)){
45
- if (sharedName.startsWith('./') || sharedName.startsWith('../')) throw new index_js_namespaceObject.ConfigError('Relative paths are not supported as shared module names.');
46
- if (sharedName.startsWith('/')) throw new index_js_namespaceObject.ConfigError('Absolute paths are not supported as shared module names.');
84
+ if (!isPlainObject(shared)) throw new index_js_namespaceObject.ConfigError('Shared must be an object.');
85
+ const sharedObject = shared;
86
+ if (!('react' in sharedObject)) throw new index_js_namespaceObject.ConfigError("Dependency 'react' must be present in shared.");
87
+ if (!('react-native' in sharedObject)) throw new index_js_namespaceObject.ConfigError("Dependency 'react-native' must be present in shared.");
88
+ for (const sharedName of Object.keys(sharedObject)){
89
+ const sharedConfig = sharedObject[sharedName];
90
+ if (isRelativePathLike(sharedName)) throw new index_js_namespaceObject.ConfigError('Relative paths are not supported as shared module names.');
91
+ if (isAbsolutePathLike(sharedName)) throw new index_js_namespaceObject.ConfigError('Absolute paths are not supported as shared module names.');
47
92
  if (sharedName.endsWith('/')) throw new index_js_namespaceObject.ConfigError("Deep import wildcards are not supported as shared module names. You need to list all deep imports explicitly.");
93
+ if (!isPlainObject(sharedConfig)) throw new index_js_namespaceObject.ConfigError(`Unsupported shared format for '${sharedName}'. Metro only supports object notation for shared modules.`);
94
+ if ('import' in sharedConfig && false !== sharedConfig.import && 'string' != typeof sharedConfig.import) throw new index_js_namespaceObject.ConfigError(`Unsupported shared.import value for '${sharedName}'. Only string and false are supported in Metro.`);
95
+ for (const unsupportedField of unsupportedSharedFields)if (unsupportedField in sharedConfig) warnUnsupported(`shared.${sharedName}.${unsupportedField}`, `Option 'shared.${sharedName}.${unsupportedField}' is not supported in Metro and will have no effect.`);
48
96
  }
49
97
  }
98
+ function validateRemotes(remotes) {
99
+ if (void 0 === remotes) return;
100
+ if (!isPlainObject(remotes)) throw new index_js_namespaceObject.ConfigError('Unsupported remotes format. Metro only supports remotes as Record<string, string>.');
101
+ for (const remoteConfig of Object.values(remotes))if ('string' != typeof remoteConfig) throw new index_js_namespaceObject.ConfigError('Unsupported remotes format. Metro only supports remotes as Record<string, string>.');
102
+ }
103
+ function validateExposes(exposes) {
104
+ if (void 0 === exposes) return;
105
+ if (!isPlainObject(exposes)) throw new index_js_namespaceObject.ConfigError('Unsupported exposes format. Metro only supports exposes as Record<string, string>.');
106
+ for (const exposeConfig of Object.values(exposes))if ('string' != typeof exposeConfig) throw new index_js_namespaceObject.ConfigError('Unsupported exposes format. Metro only supports exposes as Record<string, string>.');
107
+ }
108
+ function validateRuntimePlugins(runtimePlugins) {
109
+ if (void 0 === runtimePlugins) return;
110
+ if (!Array.isArray(runtimePlugins)) throw new index_js_namespaceObject.ConfigError('runtimePlugins must be an array.');
111
+ runtimePlugins.forEach((runtimePlugin, index)=>{
112
+ if ('string' == typeof runtimePlugin) return;
113
+ if (!Array.isArray(runtimePlugin)) throw new index_js_namespaceObject.ConfigError('runtimePlugins entries must be either a string or a tuple of [path, params].');
114
+ const [pluginPath, pluginParams] = runtimePlugin;
115
+ if ('string' != typeof pluginPath) throw new index_js_namespaceObject.ConfigError(`Invalid runtimePlugins[${index}] path. Expected a string path.`);
116
+ if (void 0 !== pluginParams) warnUnsupported(`runtimePlugins[${index}][1]`, `Option 'runtimePlugins[${index}][1]' is not supported in Metro and will have no effect.`);
117
+ });
118
+ }
119
+ function validateDts(dts) {
120
+ if (void 0 === dts || 'boolean' == typeof dts) return;
121
+ if (!isPlainObject(dts)) throw new index_js_namespaceObject.ConfigError("Option 'dts' must be a boolean or a plain object.");
122
+ }
123
+ function validateUnsupportedTopLevelOptions(options) {
124
+ unsupportedTopLevelOptions.forEach((unsupportedOption)=>{
125
+ if (void 0 !== options[unsupportedOption]) warnUnsupported(String(unsupportedOption), `Option '${String(unsupportedOption)}' is not supported in Metro and will have no effect.`);
126
+ });
127
+ }
128
+ function validateDeprecatedOptions(options) {
129
+ if (options.plugins && options.plugins.length > 0) warnUnsupported('deprecated.plugins', "The 'plugins' option is deprecated. Use 'runtimePlugins' instead. Support for 'plugins' will be removed in the next major version.");
130
+ }
131
+ function warnUnsupported(key, message) {
132
+ if (warningSet.has(key)) return;
133
+ warningSet.add(key);
134
+ external_logger_js_default().warn(message);
135
+ }
136
+ function isPlainObject(value) {
137
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
138
+ }
139
+ function isRelativePathLike(value) {
140
+ return /^\.{1,2}[\\/]/.test(value);
141
+ }
142
+ function isAbsolutePathLike(value) {
143
+ return external_node_path_default().posix.isAbsolute(value) || external_node_path_default().win32.isAbsolute(value);
144
+ }
50
145
  function validateOptions(options) {
146
+ validateUnsupportedTopLevelOptions(options);
147
+ validateDeprecatedOptions(options);
51
148
  validateName(options.name);
52
149
  validateFilename(options.filename);
150
+ validateRemotes(options.remotes);
151
+ validateExposes(options.exposes);
152
+ validateRuntimePlugins(options.runtimePlugins);
153
+ validateDts(options.dts);
53
154
  validateShared(options.shared);
54
155
  }
55
156
  exports.validateOptions = __webpack_exports__.validateOptions;
@@ -1,7 +1,38 @@
1
1
  import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
+ import node_path from "node:path";
4
+ import logger from "../logger.mjs";
3
5
  import { ConfigError } from "../utils/index.mjs";
6
+ const unsupportedTopLevelOptions = [
7
+ 'library',
8
+ 'remoteType',
9
+ 'runtime',
10
+ 'shareScope',
11
+ 'getPublicPath',
12
+ 'implementation',
13
+ 'manifest',
14
+ 'dev',
15
+ 'dataPrefetch',
16
+ 'virtualRuntimeEntry',
17
+ 'experiments',
18
+ 'bridge',
19
+ 'async',
20
+ 'treeShakingDir',
21
+ 'injectTreeShakingUsedExports',
22
+ 'treeShakingSharedExcludePlugins',
23
+ 'treeShakingSharedPlugins'
24
+ ];
25
+ const unsupportedSharedFields = [
26
+ 'packageName',
27
+ 'shareKey',
28
+ 'shareScope',
29
+ 'strictVersion',
30
+ 'treeShaking',
31
+ 'shareStrategy'
32
+ ];
33
+ const warningSet = new Set();
4
34
  function validateName(name) {
35
+ if (!name || 'string' != typeof name) throw new ConfigError("Option 'name' is required.");
5
36
  const validEcmaIdentifierRegex = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
6
37
  if (!validEcmaIdentifierRegex.test(name)) throw new ConfigError(`Invalid 'name': ${name}. The 'name' must be a valid JavaScript identifier.`);
7
38
  }
@@ -13,17 +44,76 @@ function validateShared(shared) {
13
44
  if (!shared) throw new ConfigError('Shared configuration is required.');
14
45
  if ('object' != typeof shared) throw new ConfigError('Shared must be an object.');
15
46
  if (Array.isArray(shared)) throw new ConfigError('Array format is not supported for shared.');
16
- if (!('react' in shared)) throw new ConfigError("Dependency 'react' must be present in shared.");
17
- if (!('react-native' in shared)) throw new ConfigError("Dependency 'react-native' must be present in shared.");
18
- for (const sharedName of Object.keys(shared)){
19
- if (sharedName.startsWith('./') || sharedName.startsWith('../')) throw new ConfigError('Relative paths are not supported as shared module names.');
20
- if (sharedName.startsWith('/')) throw new ConfigError('Absolute paths are not supported as shared module names.');
47
+ if (!isPlainObject(shared)) throw new ConfigError('Shared must be an object.');
48
+ const sharedObject = shared;
49
+ if (!('react' in sharedObject)) throw new ConfigError("Dependency 'react' must be present in shared.");
50
+ if (!('react-native' in sharedObject)) throw new ConfigError("Dependency 'react-native' must be present in shared.");
51
+ for (const sharedName of Object.keys(sharedObject)){
52
+ const sharedConfig = sharedObject[sharedName];
53
+ if (isRelativePathLike(sharedName)) throw new ConfigError('Relative paths are not supported as shared module names.');
54
+ if (isAbsolutePathLike(sharedName)) throw new ConfigError('Absolute paths are not supported as shared module names.');
21
55
  if (sharedName.endsWith('/')) throw new ConfigError("Deep import wildcards are not supported as shared module names. You need to list all deep imports explicitly.");
56
+ if (!isPlainObject(sharedConfig)) throw new ConfigError(`Unsupported shared format for '${sharedName}'. Metro only supports object notation for shared modules.`);
57
+ if ('import' in sharedConfig && false !== sharedConfig.import && 'string' != typeof sharedConfig.import) throw new ConfigError(`Unsupported shared.import value for '${sharedName}'. Only string and false are supported in Metro.`);
58
+ for (const unsupportedField of unsupportedSharedFields)if (unsupportedField in sharedConfig) warnUnsupported(`shared.${sharedName}.${unsupportedField}`, `Option 'shared.${sharedName}.${unsupportedField}' is not supported in Metro and will have no effect.`);
22
59
  }
23
60
  }
61
+ function validateRemotes(remotes) {
62
+ if (void 0 === remotes) return;
63
+ if (!isPlainObject(remotes)) throw new ConfigError('Unsupported remotes format. Metro only supports remotes as Record<string, string>.');
64
+ for (const remoteConfig of Object.values(remotes))if ('string' != typeof remoteConfig) throw new ConfigError('Unsupported remotes format. Metro only supports remotes as Record<string, string>.');
65
+ }
66
+ function validateExposes(exposes) {
67
+ if (void 0 === exposes) return;
68
+ if (!isPlainObject(exposes)) throw new ConfigError('Unsupported exposes format. Metro only supports exposes as Record<string, string>.');
69
+ for (const exposeConfig of Object.values(exposes))if ('string' != typeof exposeConfig) throw new ConfigError('Unsupported exposes format. Metro only supports exposes as Record<string, string>.');
70
+ }
71
+ function validateRuntimePlugins(runtimePlugins) {
72
+ if (void 0 === runtimePlugins) return;
73
+ if (!Array.isArray(runtimePlugins)) throw new ConfigError('runtimePlugins must be an array.');
74
+ runtimePlugins.forEach((runtimePlugin, index)=>{
75
+ if ('string' == typeof runtimePlugin) return;
76
+ if (!Array.isArray(runtimePlugin)) throw new ConfigError('runtimePlugins entries must be either a string or a tuple of [path, params].');
77
+ const [pluginPath, pluginParams] = runtimePlugin;
78
+ if ('string' != typeof pluginPath) throw new ConfigError(`Invalid runtimePlugins[${index}] path. Expected a string path.`);
79
+ if (void 0 !== pluginParams) warnUnsupported(`runtimePlugins[${index}][1]`, `Option 'runtimePlugins[${index}][1]' is not supported in Metro and will have no effect.`);
80
+ });
81
+ }
82
+ function validateDts(dts) {
83
+ if (void 0 === dts || 'boolean' == typeof dts) return;
84
+ if (!isPlainObject(dts)) throw new ConfigError("Option 'dts' must be a boolean or a plain object.");
85
+ }
86
+ function validateUnsupportedTopLevelOptions(options) {
87
+ unsupportedTopLevelOptions.forEach((unsupportedOption)=>{
88
+ if (void 0 !== options[unsupportedOption]) warnUnsupported(String(unsupportedOption), `Option '${String(unsupportedOption)}' is not supported in Metro and will have no effect.`);
89
+ });
90
+ }
91
+ function validateDeprecatedOptions(options) {
92
+ if (options.plugins && options.plugins.length > 0) warnUnsupported('deprecated.plugins', "The 'plugins' option is deprecated. Use 'runtimePlugins' instead. Support for 'plugins' will be removed in the next major version.");
93
+ }
94
+ function warnUnsupported(key, message) {
95
+ if (warningSet.has(key)) return;
96
+ warningSet.add(key);
97
+ logger.warn(message);
98
+ }
99
+ function isPlainObject(value) {
100
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
101
+ }
102
+ function isRelativePathLike(value) {
103
+ return /^\.{1,2}[\\/]/.test(value);
104
+ }
105
+ function isAbsolutePathLike(value) {
106
+ return node_path.posix.isAbsolute(value) || node_path.win32.isAbsolute(value);
107
+ }
24
108
  function validateOptions(options) {
109
+ validateUnsupportedTopLevelOptions(options);
110
+ validateDeprecatedOptions(options);
25
111
  validateName(options.name);
26
112
  validateFilename(options.filename);
113
+ validateRemotes(options.remotes);
114
+ validateExposes(options.exposes);
115
+ validateRuntimePlugins(options.runtimePlugins);
116
+ validateDts(options.dts);
27
117
  validateShared(options.shared);
28
118
  }
29
119
  export { validateOptions };
package/dist/types.d.ts CHANGED
@@ -1,21 +1,21 @@
1
- export interface SharedConfig {
2
- singleton: boolean;
3
- eager: boolean;
4
- version: string;
5
- requiredVersion: string;
6
- import?: false;
1
+ import type { moduleFederationPlugin } from '@module-federation/sdk';
2
+ export interface ModuleFederationConfig extends moduleFederationPlugin.ModuleFederationPluginOptions {
3
+ /**
4
+ * @deprecated Use runtimePlugins instead. Scheduled for removal in the next major version.
5
+ */
6
+ plugins?: string[];
7
7
  }
8
- export type Shared = Record<string, SharedConfig>;
9
- export interface ModuleFederationConfig {
8
+ export type ShareObject = Record<string, moduleFederationPlugin.SharedConfig>;
9
+ export interface ModuleFederationConfigNormalized {
10
10
  name: string;
11
- filename?: string;
12
- remotes?: Record<string, string>;
13
- exposes?: Record<string, string>;
14
- shared?: Shared;
15
- shareStrategy?: 'loaded-first' | 'version-first';
16
- plugins?: string[];
11
+ filename: string;
12
+ remotes: Record<string, string>;
13
+ exposes: Record<string, string>;
14
+ shared: ShareObject;
15
+ shareStrategy: moduleFederationPlugin.SharedStrategy;
16
+ plugins: string[];
17
+ dts: boolean | moduleFederationPlugin.PluginDtsOptions;
17
18
  }
18
- export type ModuleFederationConfigNormalized = Required<ModuleFederationConfig>;
19
19
  export type ModuleFederationExtraOptions = {
20
20
  flags?: MetroMFFlags;
21
21
  };
@@ -0,0 +1,12 @@
1
+ import type { ModuleFederationConfigNormalized } from '../types';
2
+ export type FederatedTypesMeta = {
3
+ zipName: string;
4
+ apiFileName: string;
5
+ };
6
+ export declare function maybeGenerateFederatedRemoteTypes(opts: {
7
+ federationConfig: ModuleFederationConfigNormalized;
8
+ projectRoot: string;
9
+ outputDir: string;
10
+ logger: Pick<Console, 'info' | 'warn'>;
11
+ }): Promise<FederatedTypesMeta | undefined>;
12
+ export declare function applyTypesMetaToManifest(manifest: Record<string, any>, typesMeta: FederatedTypesMeta | undefined): Record<string, any>;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __webpack_modules__ = {
3
+ "@module-federation/dts-plugin": function(module) {
4
+ module.exports = import("@module-federation/dts-plugin").then(function(module) {
5
+ return module;
6
+ });
7
+ },
8
+ "@module-federation/dts-plugin/core": function(module) {
9
+ module.exports = import("@module-federation/dts-plugin/core").then(function(module) {
10
+ return module;
11
+ });
12
+ }
13
+ };
14
+ var __webpack_module_cache__ = {};
15
+ function __webpack_require__(moduleId) {
16
+ var cachedModule = __webpack_module_cache__[moduleId];
17
+ if (void 0 !== cachedModule) return cachedModule.exports;
18
+ var module = __webpack_module_cache__[moduleId] = {
19
+ exports: {}
20
+ };
21
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
22
+ return module.exports;
23
+ }
24
+ (()=>{
25
+ __webpack_require__.n = (module)=>{
26
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
27
+ __webpack_require__.d(getter, {
28
+ a: getter
29
+ });
30
+ return getter;
31
+ };
32
+ })();
33
+ (()=>{
34
+ __webpack_require__.d = (exports1, definition)=>{
35
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
36
+ enumerable: true,
37
+ get: definition[key]
38
+ });
39
+ };
40
+ })();
41
+ (()=>{
42
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
43
+ })();
44
+ (()=>{
45
+ __webpack_require__.r = (exports1)=>{
46
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
47
+ value: 'Module'
48
+ });
49
+ Object.defineProperty(exports1, '__esModule', {
50
+ value: true
51
+ });
52
+ };
53
+ })();
54
+ var __webpack_exports__ = {};
55
+ (()=>{
56
+ __webpack_require__.r(__webpack_exports__);
57
+ __webpack_require__.d(__webpack_exports__, {
58
+ maybeGenerateFederatedRemoteTypes: ()=>maybeGenerateFederatedRemoteTypes,
59
+ applyTypesMetaToManifest: ()=>applyTypesMetaToManifest
60
+ });
61
+ const external_node_fs_namespaceObject = require("node:fs");
62
+ const external_node_util_namespaceObject = require("node:util");
63
+ var external_node_util_default = /*#__PURE__*/ __webpack_require__.n(external_node_util_namespaceObject);
64
+ async function maybeGenerateFederatedRemoteTypes(opts) {
65
+ const { federationConfig, projectRoot, outputDir, logger } = opts;
66
+ if (false === federationConfig.dts) return;
67
+ const dtsPlugin = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "@module-federation/dts-plugin"));
68
+ const dtsPluginCore = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "@module-federation/dts-plugin/core"));
69
+ const dtsConfig = true === federationConfig.dts ? {
70
+ consumeTypes: false
71
+ } : 'object' != typeof federationConfig.dts || null === federationConfig.dts || Object.prototype.hasOwnProperty.call(federationConfig.dts, 'consumeTypes') ? federationConfig.dts : {
72
+ ...federationConfig.dts,
73
+ consumeTypes: false
74
+ };
75
+ const mfOptions = {
76
+ name: federationConfig.name,
77
+ filename: federationConfig.filename,
78
+ remotes: federationConfig.remotes,
79
+ exposes: federationConfig.exposes,
80
+ shared: federationConfig.shared,
81
+ dts: dtsConfig
82
+ };
83
+ const normalizedDtsOptions = dtsPlugin.normalizeDtsOptions(mfOptions, projectRoot, {
84
+ defaultGenerateOptions: {
85
+ generateAPITypes: true,
86
+ compileInChildProcess: false,
87
+ abortOnError: false,
88
+ extractThirdParty: false,
89
+ extractRemoteTypes: false
90
+ },
91
+ defaultConsumeOptions: {
92
+ abortOnError: true,
93
+ consumeAPITypes: true
94
+ }
95
+ });
96
+ if (!normalizedDtsOptions) return;
97
+ const dtsManagerOptions = dtsPlugin.normalizeGenerateTypesOptions({
98
+ context: projectRoot,
99
+ outputDir,
100
+ dtsOptions: normalizedDtsOptions,
101
+ pluginOptions: mfOptions
102
+ });
103
+ if (!dtsManagerOptions) return;
104
+ if (dtsManagerOptions.host) {
105
+ let remoteTypeUrls = dtsManagerOptions.host.remoteTypeUrls;
106
+ if ('function' == typeof remoteTypeUrls) remoteTypeUrls = await remoteTypeUrls();
107
+ await dtsPluginCore.consumeTypes({
108
+ ...dtsManagerOptions,
109
+ host: {
110
+ ...dtsManagerOptions.host,
111
+ remoteTypeUrls
112
+ }
113
+ });
114
+ }
115
+ logger.info(`${external_node_util_default().styleText('blue', 'Generating federated types (d.ts)')}`);
116
+ await dtsPlugin.generateTypesAPI({
117
+ dtsManagerOptions
118
+ });
119
+ const { zipTypesPath, apiTypesPath, zipName, apiFileName } = dtsPluginCore.retrieveTypesAssetsInfo(dtsManagerOptions.remote);
120
+ const produced = {};
121
+ const fileExists = async (p)=>{
122
+ try {
123
+ await external_node_fs_namespaceObject.promises.stat(p);
124
+ return true;
125
+ } catch {
126
+ return false;
127
+ }
128
+ };
129
+ if (zipTypesPath && zipName && await fileExists(zipTypesPath)) produced.zipName = zipName;
130
+ if (apiTypesPath && apiFileName && await fileExists(apiTypesPath)) produced.apiFileName = apiFileName;
131
+ if (process.env['FEDERATION_DEBUG']) logger.info(`dts debug: zipTypesPath=${zipTypesPath} zipExists=${String(Boolean(produced.zipName))} apiTypesPath=${apiTypesPath} apiExists=${String(Boolean(produced.apiFileName))}`);
132
+ if (!produced.zipName && !produced.apiFileName) return void logger.warn(`${external_node_util_default().styleText('yellow', 'Federated types enabled, but no types files were produced.')}`);
133
+ logger.info(`Done writing federated types:\n${external_node_util_default().styleText('dim', [
134
+ produced.zipName,
135
+ produced.apiFileName
136
+ ].filter(Boolean).join('\n'))}`);
137
+ return {
138
+ zipName: produced.zipName ?? '',
139
+ apiFileName: produced.apiFileName ?? ''
140
+ };
141
+ }
142
+ function applyTypesMetaToManifest(manifest, typesMeta) {
143
+ if (!(null == typesMeta ? void 0 : typesMeta.zipName) && !(null == typesMeta ? void 0 : typesMeta.apiFileName)) return manifest;
144
+ manifest.metaData = manifest.metaData || {};
145
+ manifest.metaData.types = manifest.metaData.types || {};
146
+ if (typesMeta.zipName) manifest.metaData.types.zip = typesMeta.zipName;
147
+ if (typesMeta.apiFileName) manifest.metaData.types.api = typesMeta.apiFileName;
148
+ return manifest;
149
+ }
150
+ })();
151
+ exports.applyTypesMetaToManifest = __webpack_exports__.applyTypesMetaToManifest;
152
+ exports.maybeGenerateFederatedRemoteTypes = __webpack_exports__.maybeGenerateFederatedRemoteTypes;
153
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
154
+ "applyTypesMetaToManifest",
155
+ "maybeGenerateFederatedRemoteTypes"
156
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
157
+ Object.defineProperty(exports, '__esModule', {
158
+ value: true
159
+ });
@@ -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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/metro",
3
- "version": "2.0.1",
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.1",
61
- "@module-federation/sdk": "2.0.1"
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 {};