@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
@@ -30,6 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
30
30
  HMR_CLIENT_REGEX: ()=>HMR_CLIENT_REGEX,
31
31
  INIT_HOST: ()=>INIT_HOST,
32
32
  MANIFEST_FILENAME: ()=>MANIFEST_FILENAME,
33
+ PLUGIN_IDENTIFIER: ()=>PLUGIN_IDENTIFIER,
33
34
  REMOTE_HMR_SETUP: ()=>REMOTE_HMR_SETUP,
34
35
  REMOTE_MODULE_REGISTRY: ()=>REMOTE_MODULE_REGISTRY,
35
36
  TMP_DIR_NAME: ()=>TMP_DIR_NAME
@@ -38,6 +39,7 @@ const INIT_HOST = 'mf:init-host';
38
39
  const ASYNC_REQUIRE = 'mf:async-require';
39
40
  const REMOTE_MODULE_REGISTRY = 'mf:remote-module-registry';
40
41
  const REMOTE_HMR_SETUP = 'mf:remote-hmr';
42
+ const PLUGIN_IDENTIFIER = '[ Module Federation Metro ]';
41
43
  const DEFAULT_ENTRY_FILENAME = 'remoteEntry.bundle';
42
44
  const GET_DEV_SERVER_REGEX = /react-native\/Libraries\/Core\/Devtools\/getDevServer\.js$/;
43
45
  const HMR_CLIENT_REGEX = /react-native\/Libraries\/Utilities\/HMRClient\.js$/;
@@ -49,6 +51,7 @@ exports.GET_DEV_SERVER_REGEX = __webpack_exports__.GET_DEV_SERVER_REGEX;
49
51
  exports.HMR_CLIENT_REGEX = __webpack_exports__.HMR_CLIENT_REGEX;
50
52
  exports.INIT_HOST = __webpack_exports__.INIT_HOST;
51
53
  exports.MANIFEST_FILENAME = __webpack_exports__.MANIFEST_FILENAME;
54
+ exports.PLUGIN_IDENTIFIER = __webpack_exports__.PLUGIN_IDENTIFIER;
52
55
  exports.REMOTE_HMR_SETUP = __webpack_exports__.REMOTE_HMR_SETUP;
53
56
  exports.REMOTE_MODULE_REGISTRY = __webpack_exports__.REMOTE_MODULE_REGISTRY;
54
57
  exports.TMP_DIR_NAME = __webpack_exports__.TMP_DIR_NAME;
@@ -59,6 +62,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
59
62
  "HMR_CLIENT_REGEX",
60
63
  "INIT_HOST",
61
64
  "MANIFEST_FILENAME",
65
+ "PLUGIN_IDENTIFIER",
62
66
  "REMOTE_HMR_SETUP",
63
67
  "REMOTE_MODULE_REGISTRY",
64
68
  "TMP_DIR_NAME"
@@ -4,9 +4,10 @@ const INIT_HOST = 'mf:init-host';
4
4
  const ASYNC_REQUIRE = 'mf:async-require';
5
5
  const REMOTE_MODULE_REGISTRY = 'mf:remote-module-registry';
6
6
  const REMOTE_HMR_SETUP = 'mf:remote-hmr';
7
+ const PLUGIN_IDENTIFIER = '[ Module Federation Metro ]';
7
8
  const DEFAULT_ENTRY_FILENAME = 'remoteEntry.bundle';
8
9
  const GET_DEV_SERVER_REGEX = /react-native\/Libraries\/Core\/Devtools\/getDevServer\.js$/;
9
10
  const HMR_CLIENT_REGEX = /react-native\/Libraries\/Utilities\/HMRClient\.js$/;
10
11
  const TMP_DIR_NAME = '.mf-metro';
11
12
  const MANIFEST_FILENAME = 'mf-manifest.json';
12
- export { ASYNC_REQUIRE, DEFAULT_ENTRY_FILENAME, GET_DEV_SERVER_REGEX, HMR_CLIENT_REGEX, INIT_HOST, MANIFEST_FILENAME, REMOTE_HMR_SETUP, REMOTE_MODULE_REGISTRY, TMP_DIR_NAME };
13
+ export { ASYNC_REQUIRE, DEFAULT_ENTRY_FILENAME, GET_DEV_SERVER_REGEX, HMR_CLIENT_REGEX, INIT_HOST, MANIFEST_FILENAME, PLUGIN_IDENTIFIER, REMOTE_HMR_SETUP, REMOTE_MODULE_REGISTRY, TMP_DIR_NAME };
@@ -44,13 +44,15 @@ const external_node_fs_namespaceObject = require("node:fs");
44
44
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
45
45
  const external_node_path_namespaceObject = require("node:path");
46
46
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
47
+ const external_helpers_js_namespaceObject = require("./helpers.js");
47
48
  function getRemoteModule(name) {
48
49
  const template = getModuleTemplate('remote-module.js');
49
50
  return template.replaceAll('__MODULE_ID__', `"${name}"`);
50
51
  }
51
52
  function getHostEntryModule(_, paths) {
52
53
  const template = getModuleTemplate('host-entry.js');
53
- return template.replaceAll('__ENTRYPOINT_IMPORT__', `import './${external_node_path_default().relative(paths.tmpDir, paths.originalEntry)}'`);
54
+ const relativeEntryPath = (0, external_helpers_js_namespaceObject.toPosixPath)(external_node_path_default().relative(paths.tmpDir, paths.originalEntry));
55
+ return template.replaceAll('__ENTRYPOINT_IMPORT__', `import './${relativeEntryPath}'`);
54
56
  }
55
57
  function getInitHostModule(options) {
56
58
  const template = getModuleTemplate('init-host.js');
@@ -71,7 +73,7 @@ function getRemoteHMRSetupModule() {
71
73
  function generateExposes(exposes, paths) {
72
74
  const exposesString = Object.keys(exposes).map((key)=>{
73
75
  const importPath = external_node_path_default().join(paths.projectDir, exposes[key]);
74
- const relativeImportPath = external_node_path_default().relative(paths.tmpDir, importPath);
76
+ const relativeImportPath = (0, external_helpers_js_namespaceObject.toPosixPath)(external_node_path_default().relative(paths.tmpDir, importPath));
75
77
  return `"${key}": async () => import("${relativeImportPath}")`;
76
78
  });
77
79
  return `{${exposesString.join(',')}}`;
@@ -82,7 +84,8 @@ function generateRuntimePlugins(runtimePlugins) {
82
84
  runtimePlugins.forEach((plugin, index)=>{
83
85
  const pluginName = `plugin${index}`;
84
86
  pluginNames.push(`${pluginName}()`);
85
- pluginImports.push(`import ${pluginName} from "${plugin}";`);
87
+ const pluginPath = (0, external_helpers_js_namespaceObject.toPosixPath)(plugin);
88
+ pluginImports.push(`import ${pluginName} from "${pluginPath}";`);
86
89
  });
87
90
  const imports = pluginImports.join('\n');
88
91
  const plugins = `const plugins = [${pluginNames.join(', ')}];`;
@@ -2,13 +2,15 @@ import __rslib_shim_module__ from 'module';
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.url);
3
3
  import node_fs from "node:fs";
4
4
  import node_path from "node:path";
5
+ import { toPosixPath } from "./helpers.mjs";
5
6
  function getRemoteModule(name) {
6
7
  const template = getModuleTemplate('remote-module.js');
7
8
  return template.replaceAll('__MODULE_ID__', `"${name}"`);
8
9
  }
9
10
  function getHostEntryModule(_, paths) {
10
11
  const template = getModuleTemplate('host-entry.js');
11
- return template.replaceAll('__ENTRYPOINT_IMPORT__', `import './${node_path.relative(paths.tmpDir, paths.originalEntry)}'`);
12
+ const relativeEntryPath = toPosixPath(node_path.relative(paths.tmpDir, paths.originalEntry));
13
+ return template.replaceAll('__ENTRYPOINT_IMPORT__', `import './${relativeEntryPath}'`);
12
14
  }
13
15
  function getInitHostModule(options) {
14
16
  const template = getModuleTemplate('init-host.js');
@@ -29,7 +31,7 @@ function getRemoteHMRSetupModule() {
29
31
  function generateExposes(exposes, paths) {
30
32
  const exposesString = Object.keys(exposes).map((key)=>{
31
33
  const importPath = node_path.join(paths.projectDir, exposes[key]);
32
- const relativeImportPath = node_path.relative(paths.tmpDir, importPath);
34
+ const relativeImportPath = toPosixPath(node_path.relative(paths.tmpDir, importPath));
33
35
  return `"${key}": async () => import("${relativeImportPath}")`;
34
36
  });
35
37
  return `{${exposesString.join(',')}}`;
@@ -40,7 +42,8 @@ function generateRuntimePlugins(runtimePlugins) {
40
42
  runtimePlugins.forEach((plugin, index)=>{
41
43
  const pluginName = `plugin${index}`;
42
44
  pluginNames.push(`${pluginName}()`);
43
- pluginImports.push(`import ${pluginName} from "${plugin}";`);
45
+ const pluginPath = toPosixPath(plugin);
46
+ pluginImports.push(`import ${pluginName} from "${pluginPath}";`);
44
47
  });
45
48
  const imports = pluginImports.join('\n');
46
49
  const plugins = `const plugins = [${pluginNames.join(', ')}];`;
@@ -5,3 +5,4 @@ export declare function removeExtension(filepath: string): string;
5
5
  export declare function stubHostEntry(hostEntryPath: string): void;
6
6
  export declare function stubRemoteEntry(remoteEntryPath: string): void;
7
7
  export declare function prepareTmpDir(projectRootPath: string): string;
8
+ export declare function toPosixPath(value: string): string;
@@ -33,13 +33,14 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- stubHostEntry: ()=>stubHostEntry,
37
36
  stubRemoteEntry: ()=>stubRemoteEntry,
38
- isUsingMFCommand: ()=>isUsingMFCommand,
39
- isUsingMFBundleCommand: ()=>isUsingMFBundleCommand,
40
37
  removeExtension: ()=>removeExtension,
38
+ replaceExtension: ()=>replaceExtension,
41
39
  prepareTmpDir: ()=>prepareTmpDir,
42
- replaceExtension: ()=>replaceExtension
40
+ toPosixPath: ()=>toPosixPath,
41
+ isUsingMFCommand: ()=>isUsingMFCommand,
42
+ stubHostEntry: ()=>stubHostEntry,
43
+ isUsingMFBundleCommand: ()=>isUsingMFBundleCommand
43
44
  });
44
45
  const external_node_fs_namespaceObject = require("node:fs");
45
46
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
@@ -98,6 +99,9 @@ function prepareTmpDir(projectRootPath) {
98
99
  });
99
100
  return tmpDirPath;
100
101
  }
102
+ function toPosixPath(value) {
103
+ return value.replaceAll('\\', '/');
104
+ }
101
105
  exports.isUsingMFBundleCommand = __webpack_exports__.isUsingMFBundleCommand;
102
106
  exports.isUsingMFCommand = __webpack_exports__.isUsingMFCommand;
103
107
  exports.prepareTmpDir = __webpack_exports__.prepareTmpDir;
@@ -105,6 +109,7 @@ exports.removeExtension = __webpack_exports__.removeExtension;
105
109
  exports.replaceExtension = __webpack_exports__.replaceExtension;
106
110
  exports.stubHostEntry = __webpack_exports__.stubHostEntry;
107
111
  exports.stubRemoteEntry = __webpack_exports__.stubRemoteEntry;
112
+ exports.toPosixPath = __webpack_exports__.toPosixPath;
108
113
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
109
114
  "isUsingMFBundleCommand",
110
115
  "isUsingMFCommand",
@@ -112,7 +117,8 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
112
117
  "removeExtension",
113
118
  "replaceExtension",
114
119
  "stubHostEntry",
115
- "stubRemoteEntry"
120
+ "stubRemoteEntry",
121
+ "toPosixPath"
116
122
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
117
123
  Object.defineProperty(exports, '__esModule', {
118
124
  value: true
@@ -55,4 +55,7 @@ function prepareTmpDir(projectRootPath) {
55
55
  });
56
56
  return tmpDirPath;
57
57
  }
58
- export { isUsingMFBundleCommand, isUsingMFCommand, prepareTmpDir, removeExtension, replaceExtension, stubHostEntry, stubRemoteEntry };
58
+ function toPosixPath(value) {
59
+ return value.replaceAll('\\', '/');
60
+ }
61
+ export { isUsingMFBundleCommand, isUsingMFCommand, prepareTmpDir, removeExtension, replaceExtension, stubHostEntry, stubRemoteEntry, toPosixPath };
@@ -1,9 +1,11 @@
1
1
  import type { ConfigT } from 'metro-config';
2
2
  import type { ModuleFederationConfig, ModuleFederationConfigNormalized, ModuleFederationExtraOptions } from '../types';
3
+ import type { FederatedTypesMeta } from '../utils/federated-remote-types';
3
4
  declare global {
4
5
  var __METRO_FEDERATION_CONFIG: ModuleFederationConfigNormalized;
5
6
  var __METRO_FEDERATION_ORIGINAL_ENTRY_PATH: string | undefined;
6
7
  var __METRO_FEDERATION_REMOTE_ENTRY_PATH: string | undefined;
7
8
  var __METRO_FEDERATION_MANIFEST_PATH: string | undefined;
9
+ var __METRO_FEDERATION_DTS_ASSETS: FederatedTypesMeta | undefined;
8
10
  }
9
11
  export declare function withModuleFederation(config: ConfigT, federationOptions: ModuleFederationConfig, extraOptions?: ModuleFederationExtraOptions): ConfigT;
@@ -37,9 +37,11 @@ __webpack_require__.d(__webpack_exports__, {
37
37
  });
38
38
  const external_node_path_namespaceObject = require("node:path");
39
39
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
40
+ const external_node_fs_namespaceObject = require("node:fs");
40
41
  const external_node_util_namespaceObject = require("node:util");
41
42
  var external_node_util_default = /*#__PURE__*/ __webpack_require__.n(external_node_util_namespaceObject);
42
43
  const index_js_namespaceObject = require("../utils/index.js");
44
+ const federated_remote_types_js_namespaceObject = require("../utils/federated-remote-types.js");
43
45
  const external_babel_transformer_js_namespaceObject = require("./babel-transformer.js");
44
46
  const external_helpers_js_namespaceObject = require("./helpers.js");
45
47
  const external_manifest_js_namespaceObject = require("./manifest.js");
@@ -92,6 +94,14 @@ function augmentConfig(config, federationOptions, extraOptions) {
92
94
  global.__METRO_FEDERATION_HOST_ENTRY_PATH = hostEntryPath;
93
95
  global.__METRO_FEDERATION_REMOTE_ENTRY_PATH = remoteEntryPath;
94
96
  global.__METRO_FEDERATION_MANIFEST_PATH = manifestPath;
97
+ global.__METRO_FEDERATION_DTS_ASSETS = void 0;
98
+ maybeGenerateRemoteTypesForStart({
99
+ isRemote,
100
+ options,
101
+ projectRoot: config.projectRoot,
102
+ tmpDirPath,
103
+ manifestPath
104
+ });
95
105
  return {
96
106
  ...config,
97
107
  serializer: {
@@ -146,11 +156,33 @@ function augmentConfig(config, federationOptions, extraOptions) {
146
156
  originalEntryFilename,
147
157
  remoteEntryFilename,
148
158
  manifestPath,
149
- tmpDirPath
159
+ tmpDirPath,
160
+ getDtsAssetNames: ()=>global.__METRO_FEDERATION_DTS_ASSETS
150
161
  })
151
162
  }
152
163
  };
153
164
  }
165
+ function maybeGenerateRemoteTypesForStart(opts) {
166
+ if ('start' !== process.argv[2]) return;
167
+ if (!opts.isRemote || false === opts.options.dts) return;
168
+ (async ()=>{
169
+ try {
170
+ const typesMeta = await (0, federated_remote_types_js_namespaceObject.maybeGenerateFederatedRemoteTypes)({
171
+ federationConfig: opts.options,
172
+ projectRoot: opts.projectRoot,
173
+ outputDir: opts.tmpDirPath,
174
+ logger: console
175
+ });
176
+ if (!typesMeta) return;
177
+ global.__METRO_FEDERATION_DTS_ASSETS = typesMeta;
178
+ const manifest = JSON.parse(await external_node_fs_namespaceObject.promises.readFile(opts.manifestPath, 'utf-8'));
179
+ (0, federated_remote_types_js_namespaceObject.applyTypesMetaToManifest)(manifest, typesMeta);
180
+ await external_node_fs_namespaceObject.promises.writeFile(opts.manifestPath, JSON.stringify(manifest, void 0, 2), 'utf-8');
181
+ } catch (error) {
182
+ console.warn(`${external_node_util_default().styleText('yellow', 'Failed to generate federated types for dev server:')}\n${String(error)}`);
183
+ }
184
+ })();
185
+ }
154
186
  function getOriginalEntry(projectRoot, entryFilename) {
155
187
  const originalEntryFilename = external_node_path_default().basename(global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH ?? entryFilename);
156
188
  const originalEntryPath = external_node_path_default().resolve(projectRoot, global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH ?? entryFilename);
@@ -1,8 +1,10 @@
1
1
  import __rslib_shim_module__ from 'module';
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.url);
3
3
  import node_path from "node:path";
4
+ import { promises } from "node:fs";
4
5
  import node_util from "node:util";
5
6
  import { VirtualModuleManager } from "../utils/index.mjs";
7
+ import { applyTypesMetaToManifest, maybeGenerateFederatedRemoteTypes } from "../utils/federated-remote-types.mjs";
6
8
  import { createBabelTransformer } from "./babel-transformer.mjs";
7
9
  import { isUsingMFBundleCommand, isUsingMFCommand, prepareTmpDir, replaceExtension, stubHostEntry, stubRemoteEntry } from "./helpers.mjs";
8
10
  import { createManifest } from "./manifest.mjs";
@@ -55,6 +57,14 @@ function augmentConfig(config, federationOptions, extraOptions) {
55
57
  global.__METRO_FEDERATION_HOST_ENTRY_PATH = hostEntryPath;
56
58
  global.__METRO_FEDERATION_REMOTE_ENTRY_PATH = remoteEntryPath;
57
59
  global.__METRO_FEDERATION_MANIFEST_PATH = manifestPath;
60
+ global.__METRO_FEDERATION_DTS_ASSETS = void 0;
61
+ maybeGenerateRemoteTypesForStart({
62
+ isRemote,
63
+ options,
64
+ projectRoot: config.projectRoot,
65
+ tmpDirPath,
66
+ manifestPath
67
+ });
58
68
  return {
59
69
  ...config,
60
70
  serializer: {
@@ -109,11 +119,33 @@ function augmentConfig(config, federationOptions, extraOptions) {
109
119
  originalEntryFilename,
110
120
  remoteEntryFilename,
111
121
  manifestPath,
112
- tmpDirPath
122
+ tmpDirPath,
123
+ getDtsAssetNames: ()=>global.__METRO_FEDERATION_DTS_ASSETS
113
124
  })
114
125
  }
115
126
  };
116
127
  }
128
+ function maybeGenerateRemoteTypesForStart(opts) {
129
+ if ('start' !== process.argv[2]) return;
130
+ if (!opts.isRemote || false === opts.options.dts) return;
131
+ (async ()=>{
132
+ try {
133
+ const typesMeta = await maybeGenerateFederatedRemoteTypes({
134
+ federationConfig: opts.options,
135
+ projectRoot: opts.projectRoot,
136
+ outputDir: opts.tmpDirPath,
137
+ logger: console
138
+ });
139
+ if (!typesMeta) return;
140
+ global.__METRO_FEDERATION_DTS_ASSETS = typesMeta;
141
+ const manifest = JSON.parse(await promises.readFile(opts.manifestPath, 'utf-8'));
142
+ applyTypesMetaToManifest(manifest, typesMeta);
143
+ await promises.writeFile(opts.manifestPath, JSON.stringify(manifest, void 0, 2), 'utf-8');
144
+ } catch (error) {
145
+ console.warn(`${node_util.styleText('yellow', 'Failed to generate federated types for dev server:')}\n${String(error)}`);
146
+ }
147
+ })();
148
+ }
117
149
  function getOriginalEntry(projectRoot, entryFilename) {
118
150
  const originalEntryFilename = node_path.basename(global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH ?? entryFilename);
119
151
  const originalEntryPath = node_path.resolve(projectRoot, global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH ?? entryFilename);
@@ -115,14 +115,20 @@ function generateShared(config) {
115
115
  return {
116
116
  id: sharedName,
117
117
  name: sharedName,
118
- version: config.shared[sharedName].version,
119
- requiredVersion: config.shared[sharedName].requiredVersion,
118
+ version: getManifestVersion(config.shared[sharedName].version),
119
+ requiredVersion: getManifestRequiredVersion(config.shared[sharedName].requiredVersion),
120
120
  singleton: config.shared[sharedName].singleton,
121
121
  hash: '',
122
122
  assets
123
123
  };
124
124
  });
125
125
  }
126
+ function getManifestVersion(version) {
127
+ return 'string' == typeof version ? version : '';
128
+ }
129
+ function getManifestRequiredVersion(requiredVersion) {
130
+ return 'string' == typeof requiredVersion ? requiredVersion : '*';
131
+ }
126
132
  function getEmptyAssets() {
127
133
  return {
128
134
  js: {
@@ -77,14 +77,20 @@ function generateShared(config) {
77
77
  return {
78
78
  id: sharedName,
79
79
  name: sharedName,
80
- version: config.shared[sharedName].version,
81
- requiredVersion: config.shared[sharedName].requiredVersion,
80
+ version: getManifestVersion(config.shared[sharedName].version),
81
+ requiredVersion: getManifestRequiredVersion(config.shared[sharedName].requiredVersion),
82
82
  singleton: config.shared[sharedName].singleton,
83
83
  hash: '',
84
84
  assets
85
85
  };
86
86
  });
87
87
  }
88
+ function getManifestVersion(version) {
89
+ return 'string' == typeof version ? version : '';
90
+ }
91
+ function getManifestRequiredVersion(requiredVersion) {
92
+ return 'string' == typeof requiredVersion ? requiredVersion : '*';
93
+ }
88
94
  function getEmptyAssets() {
89
95
  return {
90
96
  js: {
@@ -40,23 +40,45 @@ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node
40
40
  const external_node_path_namespaceObject = require("node:path");
41
41
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
42
42
  const external_constants_js_namespaceObject = require("./constants.js");
43
+ const external_helpers_js_namespaceObject = require("./helpers.js");
43
44
  function normalizeOptions(options, { projectRoot, tmpDirPath }) {
44
45
  const shared = getNormalizedShared(options, projectRoot);
46
+ const remotes = getNormalizedRemotes(options);
47
+ const exposes = getNormalizedExposes(options);
45
48
  const shareStrategy = getNormalizedShareStrategy(options);
46
- const plugins = getNormalizedPlugins(options, tmpDirPath);
49
+ const plugins = getNormalizedPlugins(options, tmpDirPath, projectRoot);
47
50
  return {
48
51
  name: options.name,
49
52
  filename: options.filename ?? external_constants_js_namespaceObject.DEFAULT_ENTRY_FILENAME,
50
- remotes: options.remotes ?? {},
51
- exposes: options.exposes ?? {},
53
+ remotes,
54
+ exposes,
52
55
  shared,
53
56
  shareStrategy,
54
- plugins
57
+ plugins,
58
+ dts: options.dts ?? false
59
+ };
60
+ }
61
+ function getNormalizedRemotes(options) {
62
+ return {
63
+ ...options.remotes ?? {}
64
+ };
65
+ }
66
+ function getNormalizedExposes(options) {
67
+ return {
68
+ ...options.exposes ?? {}
55
69
  };
56
70
  }
57
71
  function getNormalizedShared(options, projectRoot) {
58
72
  const pkg = getProjectPackageJson(projectRoot);
59
- const shared = options.shared ?? {};
73
+ const sharedInput = options.shared ?? {};
74
+ const shared = Object.entries(sharedInput).reduce((acc, [sharedName, config])=>{
75
+ if ('string' == typeof config) return acc;
76
+ const metroSharedConfig = {
77
+ ...config
78
+ };
79
+ acc[sharedName] = metroSharedConfig;
80
+ return acc;
81
+ }, {});
60
82
  if (!options.exposes) for (const sharedName of Object.keys(shared))shared[sharedName].eager = true;
61
83
  for (const sharedName of Object.keys(shared))if (!shared[sharedName].requiredVersion) {
62
84
  var _pkg_dependencies, _pkg_devDependencies;
@@ -71,10 +93,37 @@ function getNormalizedShared(options, projectRoot) {
71
93
  function getNormalizedShareStrategy(options) {
72
94
  return options.shareStrategy ?? 'loaded-first';
73
95
  }
74
- function getNormalizedPlugins(options, tmpDirPath) {
96
+ function getNormalizedPlugins(options, tmpDirPath, projectRoot) {
97
+ const runtimePlugins = getNormalizedRuntimePlugins(options);
75
98
  const plugins = options.plugins ?? [];
76
- plugins.unshift(require.resolve('../modules/metroCorePlugin.ts'));
77
- return plugins.map((pluginPath)=>external_node_path_default().relative(tmpDirPath, pluginPath));
99
+ const allPlugins = [
100
+ require.resolve('../modules/metroCorePlugin.ts'),
101
+ ...runtimePlugins,
102
+ ...plugins
103
+ ];
104
+ const deduplicatedPlugins = Array.from(new Set(allPlugins));
105
+ return deduplicatedPlugins.map((pluginPath)=>{
106
+ if (!isLocalPluginPath(pluginPath, projectRoot)) return pluginPath;
107
+ const resolvedPluginPath = external_node_path_default().isAbsolute(pluginPath) ? pluginPath : external_node_path_default().resolve(projectRoot, pluginPath);
108
+ return (0, external_helpers_js_namespaceObject.toPosixPath)(external_node_path_default().relative(tmpDirPath, resolvedPluginPath));
109
+ });
110
+ }
111
+ function isLocalPluginPath(pluginPath, projectRoot) {
112
+ if (external_node_path_default().isAbsolute(pluginPath)) return true;
113
+ if (pluginPath.startsWith('./') || pluginPath.startsWith('../')) return true;
114
+ return external_node_fs_default().existsSync(external_node_path_default().resolve(projectRoot, pluginPath));
115
+ }
116
+ function getNormalizedRuntimePlugins(options) {
117
+ const runtimePlugins = options.runtimePlugins ?? [];
118
+ const normalizedRuntimePlugins = [];
119
+ runtimePlugins.forEach((runtimePlugin)=>{
120
+ if ('string' == typeof runtimePlugin) return void normalizedRuntimePlugins.push(runtimePlugin);
121
+ if (Array.isArray(runtimePlugin)) {
122
+ const [pluginPath] = runtimePlugin;
123
+ if ('string' == typeof pluginPath) normalizedRuntimePlugins.push(pluginPath);
124
+ }
125
+ });
126
+ return normalizedRuntimePlugins;
78
127
  }
79
128
  function getProjectPackageJson(projectRoot) {
80
129
  const packageJsonPath = external_node_path_default().join(projectRoot, 'package.json');
@@ -3,23 +3,45 @@ const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.ur
3
3
  import node_fs from "node:fs";
4
4
  import node_path from "node:path";
5
5
  import { DEFAULT_ENTRY_FILENAME } from "./constants.mjs";
6
+ import { toPosixPath } from "./helpers.mjs";
6
7
  function normalizeOptions(options, { projectRoot, tmpDirPath }) {
7
8
  const shared = getNormalizedShared(options, projectRoot);
9
+ const remotes = getNormalizedRemotes(options);
10
+ const exposes = getNormalizedExposes(options);
8
11
  const shareStrategy = getNormalizedShareStrategy(options);
9
- const plugins = getNormalizedPlugins(options, tmpDirPath);
12
+ const plugins = getNormalizedPlugins(options, tmpDirPath, projectRoot);
10
13
  return {
11
14
  name: options.name,
12
15
  filename: options.filename ?? DEFAULT_ENTRY_FILENAME,
13
- remotes: options.remotes ?? {},
14
- exposes: options.exposes ?? {},
16
+ remotes,
17
+ exposes,
15
18
  shared,
16
19
  shareStrategy,
17
- plugins
20
+ plugins,
21
+ dts: options.dts ?? false
22
+ };
23
+ }
24
+ function getNormalizedRemotes(options) {
25
+ return {
26
+ ...options.remotes ?? {}
27
+ };
28
+ }
29
+ function getNormalizedExposes(options) {
30
+ return {
31
+ ...options.exposes ?? {}
18
32
  };
19
33
  }
20
34
  function getNormalizedShared(options, projectRoot) {
21
35
  const pkg = getProjectPackageJson(projectRoot);
22
- const shared = options.shared ?? {};
36
+ const sharedInput = options.shared ?? {};
37
+ const shared = Object.entries(sharedInput).reduce((acc, [sharedName, config])=>{
38
+ if ('string' == typeof config) return acc;
39
+ const metroSharedConfig = {
40
+ ...config
41
+ };
42
+ acc[sharedName] = metroSharedConfig;
43
+ return acc;
44
+ }, {});
23
45
  if (!options.exposes) for (const sharedName of Object.keys(shared))shared[sharedName].eager = true;
24
46
  for (const sharedName of Object.keys(shared))if (!shared[sharedName].requiredVersion) {
25
47
  var _pkg_dependencies, _pkg_devDependencies;
@@ -34,10 +56,37 @@ function getNormalizedShared(options, projectRoot) {
34
56
  function getNormalizedShareStrategy(options) {
35
57
  return options.shareStrategy ?? 'loaded-first';
36
58
  }
37
- function getNormalizedPlugins(options, tmpDirPath) {
59
+ function getNormalizedPlugins(options, tmpDirPath, projectRoot) {
60
+ const runtimePlugins = getNormalizedRuntimePlugins(options);
38
61
  const plugins = options.plugins ?? [];
39
- plugins.unshift(require.resolve('../modules/metroCorePlugin.ts'));
40
- return plugins.map((pluginPath)=>node_path.relative(tmpDirPath, pluginPath));
62
+ const allPlugins = [
63
+ require.resolve('../modules/metroCorePlugin.ts'),
64
+ ...runtimePlugins,
65
+ ...plugins
66
+ ];
67
+ const deduplicatedPlugins = Array.from(new Set(allPlugins));
68
+ return deduplicatedPlugins.map((pluginPath)=>{
69
+ if (!isLocalPluginPath(pluginPath, projectRoot)) return pluginPath;
70
+ const resolvedPluginPath = node_path.isAbsolute(pluginPath) ? pluginPath : node_path.resolve(projectRoot, pluginPath);
71
+ return toPosixPath(node_path.relative(tmpDirPath, resolvedPluginPath));
72
+ });
73
+ }
74
+ function isLocalPluginPath(pluginPath, projectRoot) {
75
+ if (node_path.isAbsolute(pluginPath)) return true;
76
+ if (pluginPath.startsWith('./') || pluginPath.startsWith('../')) return true;
77
+ return node_fs.existsSync(node_path.resolve(projectRoot, pluginPath));
78
+ }
79
+ function getNormalizedRuntimePlugins(options) {
80
+ const runtimePlugins = options.runtimePlugins ?? [];
81
+ const normalizedRuntimePlugins = [];
82
+ runtimePlugins.forEach((runtimePlugin)=>{
83
+ if ('string' == typeof runtimePlugin) return void normalizedRuntimePlugins.push(runtimePlugin);
84
+ if (Array.isArray(runtimePlugin)) {
85
+ const [pluginPath] = runtimePlugin;
86
+ if ('string' == typeof pluginPath) normalizedRuntimePlugins.push(pluginPath);
87
+ }
88
+ });
89
+ return normalizedRuntimePlugins;
41
90
  }
42
91
  function getProjectPackageJson(projectRoot) {
43
92
  const packageJsonPath = node_path.join(projectRoot, 'package.json');
@@ -187,7 +187,7 @@ function replaceModule(from, to) {
187
187
  }
188
188
  function getEntryPathRegex(paths) {
189
189
  const relativeEntryPath = external_node_path_default().relative(paths.projectDir, paths.entry);
190
- const entryName = (0, external_helpers_js_namespaceObject.removeExtension)(relativeEntryPath);
190
+ const entryName = (0, external_helpers_js_namespaceObject.toPosixPath)((0, external_helpers_js_namespaceObject.removeExtension)(relativeEntryPath));
191
191
  return new RegExp(`^\\./${entryName}(\\.js)?$`);
192
192
  }
193
193
  exports.createResolveRequest = __webpack_exports__.createResolveRequest;
@@ -5,7 +5,7 @@ import { dirname as __webpack_dirname__ } from "node:path";
5
5
  import node_path from "node:path";
6
6
  import { ASYNC_REQUIRE, GET_DEV_SERVER_REGEX, HMR_CLIENT_REGEX, INIT_HOST, REMOTE_HMR_SETUP, REMOTE_MODULE_REGISTRY } from "./constants.mjs";
7
7
  import { getHostEntryModule, getInitHostModule, getRemoteEntryModule, getRemoteHMRSetupModule, getRemoteModule, getRemoteModuleRegistryModule } from "./generators.mjs";
8
- import { isUsingMFBundleCommand, removeExtension } from "./helpers.mjs";
8
+ import { isUsingMFBundleCommand, removeExtension, toPosixPath } from "./helpers.mjs";
9
9
  var resolver_dirname = __webpack_dirname__(__webpack_fileURLToPath__(import.meta.url));
10
10
  function createResolveRequest({ vmManager, options, hacks, paths, isRemote, customResolver }) {
11
11
  const hostEntryPathRegex = getEntryPathRegex({
@@ -154,7 +154,7 @@ function replaceModule(from, to) {
154
154
  }
155
155
  function getEntryPathRegex(paths) {
156
156
  const relativeEntryPath = node_path.relative(paths.projectDir, paths.entry);
157
- const entryName = removeExtension(relativeEntryPath);
157
+ const entryName = toPosixPath(removeExtension(relativeEntryPath));
158
158
  return new RegExp(`^\\./${entryName}(\\.js)?$`);
159
159
  }
160
160
  export { createResolveRequest };
@@ -5,6 +5,10 @@ type CreateRewriteRequestOptions = {
5
5
  remoteEntryFilename: string;
6
6
  manifestPath: string;
7
7
  tmpDirPath: string;
8
+ getDtsAssetNames?: () => {
9
+ zipName?: string;
10
+ apiFileName?: string;
11
+ };
8
12
  };
9
- export declare function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath, }: CreateRewriteRequestOptions): (url: string) => string;
13
+ export declare function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath, getDtsAssetNames, }: CreateRewriteRequestOptions): (url: string) => string;
10
14
  export {};
@@ -39,7 +39,7 @@ const external_node_path_namespaceObject = require("node:path");
39
39
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
40
40
  const external_constants_js_namespaceObject = require("./constants.js");
41
41
  const external_helpers_js_namespaceObject = require("./helpers.js");
42
- function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath }) {
42
+ function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath, getDtsAssetNames }) {
43
43
  const hostEntryName = (0, external_helpers_js_namespaceObject.removeExtension)(originalEntryFilename);
44
44
  const remoteEntryName = (0, external_helpers_js_namespaceObject.removeExtension)(remoteEntryFilename);
45
45
  const relativeTmpDirPath = external_node_path_default().relative(config.projectRoot, tmpDirPath).split(external_node_path_default().sep).join(external_node_path_default().posix.sep);
@@ -57,9 +57,18 @@ function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilena
57
57
  return url.replace(remoteEntryName, target);
58
58
  }
59
59
  if (pathname.startsWith(`/${external_constants_js_namespaceObject.MANIFEST_FILENAME}`)) {
60
- const target = manifestPath.replace(root, '[metro-project]');
60
+ const target = (0, external_helpers_js_namespaceObject.toPosixPath)(manifestPath.replace(root, '[metro-project]'));
61
61
  return url.replace(external_constants_js_namespaceObject.MANIFEST_FILENAME, target);
62
62
  }
63
+ const dtsAssets = null == getDtsAssetNames ? void 0 : getDtsAssetNames();
64
+ const dtsAssetName = [
65
+ null == dtsAssets ? void 0 : dtsAssets.zipName,
66
+ null == dtsAssets ? void 0 : dtsAssets.apiFileName
67
+ ].filter((value)=>Boolean(value)).find((value)=>pathname === `/${value}`);
68
+ if (dtsAssetName) {
69
+ const target = `${relativeTmpDirPath}/${dtsAssetName}`;
70
+ return url.replace(dtsAssetName, target);
71
+ }
63
72
  if (config.server.rewriteRequestUrl) return config.server.rewriteRequestUrl(url);
64
73
  return url;
65
74
  };
@@ -2,8 +2,8 @@ import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
3
  import node_path from "node:path";
4
4
  import { MANIFEST_FILENAME } from "./constants.mjs";
5
- import { removeExtension } from "./helpers.mjs";
6
- function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath }) {
5
+ import { removeExtension, toPosixPath } from "./helpers.mjs";
6
+ function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilename, manifestPath, tmpDirPath, getDtsAssetNames }) {
7
7
  const hostEntryName = removeExtension(originalEntryFilename);
8
8
  const remoteEntryName = removeExtension(remoteEntryFilename);
9
9
  const relativeTmpDirPath = node_path.relative(config.projectRoot, tmpDirPath).split(node_path.sep).join(node_path.posix.sep);
@@ -21,9 +21,18 @@ function createRewriteRequest({ config, originalEntryFilename, remoteEntryFilena
21
21
  return url.replace(remoteEntryName, target);
22
22
  }
23
23
  if (pathname.startsWith(`/${MANIFEST_FILENAME}`)) {
24
- const target = manifestPath.replace(root, '[metro-project]');
24
+ const target = toPosixPath(manifestPath.replace(root, '[metro-project]'));
25
25
  return url.replace(MANIFEST_FILENAME, target);
26
26
  }
27
+ const dtsAssets = null == getDtsAssetNames ? void 0 : getDtsAssetNames();
28
+ const dtsAssetName = [
29
+ null == dtsAssets ? void 0 : dtsAssets.zipName,
30
+ null == dtsAssets ? void 0 : dtsAssets.apiFileName
31
+ ].filter((value)=>Boolean(value)).find((value)=>pathname === `/${value}`);
32
+ if (dtsAssetName) {
33
+ const target = `${relativeTmpDirPath}/${dtsAssetName}`;
34
+ return url.replace(dtsAssetName, target);
35
+ }
27
36
  if (config.server.rewriteRequestUrl) return config.server.rewriteRequestUrl(url);
28
37
  return url;
29
38
  };