@module-federation/metro 0.0.0-next-20250827124348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/babel-plugin/index.js +115 -0
- package/babel-plugin/patch-initialize-core.js +61 -0
- package/babel-plugin/patch-require.js +174 -0
- package/bootstrap/index.d.ts +1 -0
- package/bootstrap/index.js +1 -0
- package/dist/babel/transformer.d.ts +2 -0
- package/dist/babel/transformer.js +15 -0
- package/dist/commands/bundle-host/index.d.ts +13 -0
- package/dist/commands/bundle-host/index.js +95 -0
- package/dist/commands/bundle-host/index.mjs +69 -0
- package/dist/commands/bundle-host/options.d.ts +5 -0
- package/dist/commands/bundle-host/options.js +39 -0
- package/dist/commands/bundle-host/options.mjs +7 -0
- package/dist/commands/bundle-host/types.d.ts +22 -0
- package/dist/commands/bundle-host/types.js +18 -0
- package/dist/commands/bundle-host/types.mjs +2 -0
- package/dist/commands/bundle-remote/index.d.ts +12 -0
- package/dist/commands/bundle-remote/index.js +226 -0
- package/dist/commands/bundle-remote/index.mjs +200 -0
- package/dist/commands/bundle-remote/options.d.ts +32 -0
- package/dist/commands/bundle-remote/options.js +109 -0
- package/dist/commands/bundle-remote/options.mjs +67 -0
- package/dist/commands/bundle-remote/types.d.ts +16 -0
- package/dist/commands/bundle-remote/types.js +18 -0
- package/dist/commands/bundle-remote/types.mjs +2 -0
- package/dist/commands/index.d.ts +48 -0
- package/dist/commands/index.js +72 -0
- package/dist/commands/index.mjs +13 -0
- package/dist/commands/types.d.ts +14 -0
- package/dist/commands/types.js +18 -0
- package/dist/commands/types.mjs +2 -0
- package/dist/commands/utils/create-module-path-remapper.d.ts +7 -0
- package/dist/commands/utils/create-module-path-remapper.js +64 -0
- package/dist/commands/utils/create-module-path-remapper.mjs +32 -0
- package/dist/commands/utils/create-resolver.d.ts +20 -0
- package/dist/commands/utils/create-resolver.js +57 -0
- package/dist/commands/utils/create-resolver.mjs +25 -0
- package/dist/commands/utils/get-community-plugin.d.ts +29 -0
- package/dist/commands/utils/get-community-plugin.js +50 -0
- package/dist/commands/utils/get-community-plugin.mjs +18 -0
- package/dist/commands/utils/load-metro-config.d.ts +3 -0
- package/dist/commands/utils/load-metro-config.js +84 -0
- package/dist/commands/utils/load-metro-config.mjs +43 -0
- package/dist/commands/utils/save-bundle-and-map.d.ts +5 -0
- package/dist/commands/utils/save-bundle-and-map.js +77 -0
- package/dist/commands/utils/save-bundle-and-map.mjs +57 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +40 -0
- package/dist/index.mjs +5 -0
- package/dist/modules/HMRClient.ts +31 -0
- package/dist/modules/HMRClientShim.ts +1 -0
- package/dist/modules/asyncRequire.ts +134 -0
- package/dist/modules/asyncStartup.tsx +38 -0
- package/dist/modules/getDevServer.ts +15 -0
- package/dist/modules/metroCorePlugin.ts +83 -0
- package/dist/plugin/babel-transformer.d.ts +11 -0
- package/dist/plugin/babel-transformer.js +68 -0
- package/dist/plugin/babel-transformer.mjs +25 -0
- package/dist/plugin/constants.d.ts +9 -0
- package/dist/plugin/constants.js +68 -0
- package/dist/plugin/constants.mjs +12 -0
- package/dist/plugin/generators.d.ts +13 -0
- package/dist/plugin/generators.js +157 -0
- package/dist/plugin/generators.mjs +99 -0
- package/dist/plugin/helpers.d.ts +7 -0
- package/dist/plugin/helpers.js +119 -0
- package/dist/plugin/helpers.mjs +58 -0
- package/dist/plugin/index.d.ts +9 -0
- package/dist/plugin/index.js +167 -0
- package/dist/plugin/index.mjs +124 -0
- package/dist/plugin/manifest.d.ts +3 -0
- package/dist/plugin/manifest.js +146 -0
- package/dist/plugin/manifest.mjs +100 -0
- package/dist/plugin/normalize-extra-options.d.ts +8 -0
- package/dist/plugin/normalize-extra-options.js +46 -0
- package/dist/plugin/normalize-extra-options.mjs +14 -0
- package/dist/plugin/normalize-options.d.ts +7 -0
- package/dist/plugin/normalize-options.js +89 -0
- package/dist/plugin/normalize-options.mjs +46 -0
- package/dist/plugin/resolver.d.ts +25 -0
- package/dist/plugin/resolver.js +199 -0
- package/dist/plugin/resolver.mjs +160 -0
- package/dist/plugin/rewrite-request.d.ts +10 -0
- package/dist/plugin/rewrite-request.js +76 -0
- package/dist/plugin/rewrite-request.mjs +34 -0
- package/dist/plugin/serializer.d.ts +5 -0
- package/dist/plugin/serializer.js +171 -0
- package/dist/plugin/serializer.mjs +151 -0
- package/dist/plugin/validate-options.d.ts +2 -0
- package/dist/plugin/validate-options.js +61 -0
- package/dist/plugin/validate-options.mjs +29 -0
- package/dist/runtime/host-entry.d.ts +1 -0
- package/dist/runtime/host-entry.js +3 -0
- package/dist/runtime/init-host.d.ts +1 -0
- package/dist/runtime/init-host.js +31 -0
- package/dist/runtime/remote-entry.d.ts +1 -0
- package/dist/runtime/remote-entry.js +57 -0
- package/dist/runtime/remote-hmr.d.ts +1 -0
- package/dist/runtime/remote-hmr.js +19 -0
- package/dist/runtime/remote-module-registry.d.ts +7 -0
- package/dist/runtime/remote-module-registry.js +57 -0
- package/dist/runtime/remote-module.d.ts +1 -0
- package/dist/runtime/remote-module.js +2 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.js +18 -0
- package/dist/types.mjs +2 -0
- package/dist/utils/errors.d.ts +8 -0
- package/dist/utils/errors.js +50 -0
- package/dist/utils/errors.mjs +15 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +43 -0
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/vm-manager.d.ts +21 -0
- package/dist/utils/vm-manager.js +116 -0
- package/dist/utils/vm-manager.mjs +73 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Callstack and Zephyr Cloud
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// reuse `@babel/types` from `metro`
|
|
2
|
+
const metroPath = require.resolve('metro');
|
|
3
|
+
const babelTypesPath = require.resolve('@babel/types', { paths: [metroPath] });
|
|
4
|
+
const t = require(babelTypesPath);
|
|
5
|
+
|
|
6
|
+
const UNSUPPORTED_IMPORT_MESSAGE =
|
|
7
|
+
'The module path for import() must be a static string literal. Expressions or variables are not supported.';
|
|
8
|
+
const WEBPACK_IGNORE_COMMENT = 'webpackIgnore: true';
|
|
9
|
+
|
|
10
|
+
function isIgnoredWebpackImport(path) {
|
|
11
|
+
const [firstArg] = path.node.arguments;
|
|
12
|
+
|
|
13
|
+
const comments = [
|
|
14
|
+
...(firstArg?.leadingComments || []),
|
|
15
|
+
...(path.node?.leadingComments || []),
|
|
16
|
+
...(path.node?.innerComments || []),
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
t.isImport(path.node.callee) &&
|
|
21
|
+
comments.some((comment) => comment.value.includes(WEBPACK_IGNORE_COMMENT))
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getRemotesRegExp(remotes) {
|
|
26
|
+
return new RegExp(`^(${Object.keys(remotes).join('|')})/`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getSharedRegExp(shared) {
|
|
30
|
+
return new RegExp(`^(${Object.keys(shared).join('|')})$`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isRemoteImport(path, options) {
|
|
34
|
+
return (
|
|
35
|
+
t.isImport(path.node.callee) &&
|
|
36
|
+
t.isStringLiteral(path.node.arguments[0]) &&
|
|
37
|
+
Object.keys(options.remotes).length > 0 &&
|
|
38
|
+
path.node.arguments[0].value.match(getRemotesRegExp(options.remotes))
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isSharedImport(path, options) {
|
|
43
|
+
return (
|
|
44
|
+
t.isImport(path.node.callee) &&
|
|
45
|
+
t.isStringLiteral(path.node.arguments[0]) &&
|
|
46
|
+
Object.keys(options.shared).length > 0 &&
|
|
47
|
+
path.node.arguments[0].value.match(getSharedRegExp(options.shared))
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createWrappedImport(importName, methodName) {
|
|
52
|
+
const importArg = t.stringLiteral(importName);
|
|
53
|
+
|
|
54
|
+
// require('mf:remote-module-registry')
|
|
55
|
+
const requireCall = t.callExpression(t.identifier('require'), [
|
|
56
|
+
t.stringLiteral('mf:remote-module-registry'),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
// .loadAndGetRemote(importName) or .loadAndGetShared(importName)
|
|
60
|
+
const loadAndGetCall = t.callExpression(
|
|
61
|
+
t.memberExpression(requireCall, t.identifier(methodName)),
|
|
62
|
+
[importArg],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return loadAndGetCall;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getWrappedRemoteImport(importName) {
|
|
69
|
+
return createWrappedImport(importName, 'loadAndGetRemote');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getWrappedSharedImport(importName) {
|
|
73
|
+
return createWrappedImport(importName, 'loadAndGetShared');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getRejectedPromise(errorMessage) {
|
|
77
|
+
return t.callExpression(
|
|
78
|
+
t.memberExpression(t.identifier('Promise'), t.identifier('reject')),
|
|
79
|
+
[t.newExpression(t.identifier('Error'), [t.stringLiteral(errorMessage)])],
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function moduleFederationMetroBabelPlugin() {
|
|
84
|
+
return {
|
|
85
|
+
name: 'module-federation-metro-babel-plugin',
|
|
86
|
+
visitor: {
|
|
87
|
+
CallExpression(path, state) {
|
|
88
|
+
if (state.opts.blacklistedPaths.includes(state.filename)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Workaround to remove problematic import from `loadEsmEntry` in `@module-federation/runtime-core`
|
|
93
|
+
// That causes crashes in Metro bundler
|
|
94
|
+
if (isIgnoredWebpackImport(path)) {
|
|
95
|
+
path.replaceWith(getRejectedPromise(UNSUPPORTED_IMPORT_MESSAGE));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (isRemoteImport(path, state.opts)) {
|
|
100
|
+
const wrappedImport = getWrappedRemoteImport(
|
|
101
|
+
path.node.arguments[0].value,
|
|
102
|
+
);
|
|
103
|
+
path.replaceWith(wrappedImport);
|
|
104
|
+
} else if (isSharedImport(path, state.opts)) {
|
|
105
|
+
const wrappedImport = getWrappedSharedImport(
|
|
106
|
+
path.node.arguments[0].value,
|
|
107
|
+
);
|
|
108
|
+
path.replaceWith(wrappedImport);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = moduleFederationMetroBabelPlugin;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// reuse `@babel/types` from `metro`
|
|
2
|
+
const metroPath = require.resolve('metro');
|
|
3
|
+
const babelTypesPath = require.resolve('@babel/types', { paths: [metroPath] });
|
|
4
|
+
const t = require(babelTypesPath);
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Inject require('mf:init-host') right after 'use strict' directive
|
|
8
|
+
* in React Native's Initialize Core
|
|
9
|
+
*/
|
|
10
|
+
function injectInitHostRequire(path, state) {
|
|
11
|
+
// Only process once per file
|
|
12
|
+
if (state.hasInjected) return;
|
|
13
|
+
|
|
14
|
+
let insertIndex = 0;
|
|
15
|
+
|
|
16
|
+
// Find the position after 'use strict' directive
|
|
17
|
+
for (let i = 0; i < path.node.body.length; i++) {
|
|
18
|
+
const node = path.node.body[i];
|
|
19
|
+
if (
|
|
20
|
+
t.isExpressionStatement(node) &&
|
|
21
|
+
t.isStringLiteral(node.expression) &&
|
|
22
|
+
node.expression.value === 'use strict'
|
|
23
|
+
) {
|
|
24
|
+
insertIndex = i + 1;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Create the require('mf:init-host') statement
|
|
30
|
+
const requireStatement = t.expressionStatement(
|
|
31
|
+
t.callExpression(t.identifier('require'), [
|
|
32
|
+
t.stringLiteral('mf:init-host'),
|
|
33
|
+
]),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Insert the require statement
|
|
37
|
+
path.node.body.splice(insertIndex, 0, requireStatement);
|
|
38
|
+
state.hasInjected = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function metroPatchInitializeCorePlugin() {
|
|
42
|
+
return {
|
|
43
|
+
name: 'module-federation-metro-patch-initialize-core',
|
|
44
|
+
visitor: {
|
|
45
|
+
Program: {
|
|
46
|
+
enter(_, state) {
|
|
47
|
+
state.hasInjected = false;
|
|
48
|
+
state.shouldTransform = state.file.opts.filename.includes(
|
|
49
|
+
'react-native/Libraries/Core/InitializeCore.js',
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
exit(path, state) {
|
|
53
|
+
if (!state.shouldTransform) return;
|
|
54
|
+
injectInitHostRequire(path, state);
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = metroPatchInitializeCorePlugin;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// reuse `@babel/types` from `metro`
|
|
2
|
+
const metroPath = require.resolve('metro');
|
|
3
|
+
const babelTypesPath = require.resolve('@babel/types', { paths: [metroPath] });
|
|
4
|
+
const t = require(babelTypesPath);
|
|
5
|
+
|
|
6
|
+
const METRO_PREFIX = '__METRO_GLOBAL_PREFIX__';
|
|
7
|
+
const GLOBAL_NAMES_TO_PREFIX = ['__r', '__c', '__registerSegment', '__accept'];
|
|
8
|
+
const REFRESH_SYMBOLS = ['$RefreshReg$', '$RefreshSig$'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* - global.__r = metroRequire;
|
|
12
|
+
* + global[`${__METRO_GLOBAL_PREFIX__}__r`] = metroRequire;
|
|
13
|
+
*/
|
|
14
|
+
function prefixGlobalNames(path) {
|
|
15
|
+
const { object, property, computed } = path.node;
|
|
16
|
+
|
|
17
|
+
if (
|
|
18
|
+
t.isIdentifier(object, { name: 'global' }) &&
|
|
19
|
+
t.isIdentifier(property) &&
|
|
20
|
+
!computed &&
|
|
21
|
+
GLOBAL_NAMES_TO_PREFIX.includes(property.name)
|
|
22
|
+
) {
|
|
23
|
+
path.replaceWith(
|
|
24
|
+
t.memberExpression(
|
|
25
|
+
t.identifier('global'),
|
|
26
|
+
t.templateLiteral(
|
|
27
|
+
[
|
|
28
|
+
t.templateElement({ raw: '', cooked: '' }),
|
|
29
|
+
t.templateElement(
|
|
30
|
+
{ raw: property.name, cooked: property.name },
|
|
31
|
+
true,
|
|
32
|
+
),
|
|
33
|
+
],
|
|
34
|
+
[t.identifier(METRO_PREFIX)],
|
|
35
|
+
),
|
|
36
|
+
true,
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* - global.$RefreshReg$ = () => {};
|
|
44
|
+
* - global.$RefreshSig$ = () => (type) => type;
|
|
45
|
+
* + global.$RefreshReg$ = global.$RefreshReg$ ?? (() => {});
|
|
46
|
+
* + global.$RefreshSig$ = global.$RefreshSig$ ?? (() => type => type);
|
|
47
|
+
*/
|
|
48
|
+
function defaultRefreshSymbols(path, state) {
|
|
49
|
+
const { node } = path;
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
t.isMemberExpression(node.left) &&
|
|
53
|
+
t.isIdentifier(node.left.object, { name: 'global' }) &&
|
|
54
|
+
t.isIdentifier(node.left.property) &&
|
|
55
|
+
REFRESH_SYMBOLS.includes(node.left.property.name)
|
|
56
|
+
) {
|
|
57
|
+
const propName = node.left.property.name;
|
|
58
|
+
|
|
59
|
+
if (state.hasTransformed[propName]) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const globalProp = t.memberExpression(
|
|
64
|
+
t.identifier('global'),
|
|
65
|
+
t.identifier(node.left.property.name),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
path.replaceWith(
|
|
69
|
+
t.assignmentExpression(
|
|
70
|
+
'=',
|
|
71
|
+
globalProp,
|
|
72
|
+
t.logicalExpression('??', globalProp, node.right),
|
|
73
|
+
),
|
|
74
|
+
);
|
|
75
|
+
state.hasTransformed[propName] = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* - RefreshRuntime.register(type, moduleId + " " + id);
|
|
81
|
+
* + RefreshRuntime.register(type, __METRO_GLOBAL_PREFIX__ + ' ' + moduleId + ' ' + id);
|
|
82
|
+
*/
|
|
83
|
+
function prefixModuleIDs(path) {
|
|
84
|
+
const { callee, arguments: args } = path.node;
|
|
85
|
+
const isRegisterExports = t.isIdentifier(callee, {
|
|
86
|
+
name: 'registerExportsForReactRefresh',
|
|
87
|
+
});
|
|
88
|
+
const isRefreshRuntimeRegister =
|
|
89
|
+
t.isMemberExpression(callee) &&
|
|
90
|
+
t.isIdentifier(callee.object, { name: 'RefreshRuntime' }) &&
|
|
91
|
+
t.isIdentifier(callee.property, { name: 'register' });
|
|
92
|
+
|
|
93
|
+
if (!isRegisterExports && !isRefreshRuntimeRegister) return;
|
|
94
|
+
|
|
95
|
+
const lastArgIndex = args.length - 1;
|
|
96
|
+
const lastArg = args[lastArgIndex];
|
|
97
|
+
|
|
98
|
+
args[lastArgIndex] = t.binaryExpression(
|
|
99
|
+
'+',
|
|
100
|
+
t.identifier(METRO_PREFIX),
|
|
101
|
+
t.binaryExpression('+', t.stringLiteral(' '), lastArg),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* - global[__METRO_GLOBAL_PREFIX__ + '__ReactRefresh'] || metroRequire.Refresh
|
|
107
|
+
* + global[global.__METRO_GLOBAL_PREFIX__ + '__ReactRefresh'] ||
|
|
108
|
+
* + metroRequire.Refresh
|
|
109
|
+
*/
|
|
110
|
+
function patchRequireRefresh(path) {
|
|
111
|
+
const funcPath = path.findParent(
|
|
112
|
+
(p) =>
|
|
113
|
+
(p.isFunctionDeclaration() || p.isFunctionExpression()) &&
|
|
114
|
+
p.node.id?.name === 'requireRefresh',
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (!funcPath) return;
|
|
118
|
+
|
|
119
|
+
const newReturn = t.logicalExpression(
|
|
120
|
+
'||',
|
|
121
|
+
t.memberExpression(
|
|
122
|
+
t.identifier('global'),
|
|
123
|
+
t.binaryExpression(
|
|
124
|
+
'+',
|
|
125
|
+
t.memberExpression(t.identifier('global'), t.identifier(METRO_PREFIX)),
|
|
126
|
+
t.stringLiteral('__ReactRefresh'),
|
|
127
|
+
),
|
|
128
|
+
true,
|
|
129
|
+
),
|
|
130
|
+
t.memberExpression(t.identifier('metroRequire'), t.identifier('Refresh')),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
path.get('argument').replaceWith(newReturn);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function metroPatchRequireBabelPlugin() {
|
|
137
|
+
return {
|
|
138
|
+
name: 'module-federation-metro-patch-require',
|
|
139
|
+
visitor: {
|
|
140
|
+
Program: {
|
|
141
|
+
enter(_, state) {
|
|
142
|
+
// Transform only require.js from metro-runtime
|
|
143
|
+
state.shouldTransform = state.file.opts.filename.includes(
|
|
144
|
+
'metro-runtime/src/polyfills/require.js',
|
|
145
|
+
);
|
|
146
|
+
// Perform refreshSymbols transformation only once
|
|
147
|
+
// Because it is referenced in multiple places
|
|
148
|
+
state.hasTransformed = {
|
|
149
|
+
$RefreshReg$: false,
|
|
150
|
+
$RefreshSig$: false,
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
MemberExpression(path, state) {
|
|
155
|
+
if (!state.shouldTransform) return;
|
|
156
|
+
prefixGlobalNames(path);
|
|
157
|
+
},
|
|
158
|
+
AssignmentExpression(path, state) {
|
|
159
|
+
if (!state.shouldTransform) return;
|
|
160
|
+
defaultRefreshSymbols(path, state);
|
|
161
|
+
},
|
|
162
|
+
CallExpression(path, state) {
|
|
163
|
+
if (!state.shouldTransform) return;
|
|
164
|
+
prefixModuleIDs(path);
|
|
165
|
+
},
|
|
166
|
+
ReturnStatement(path, state) {
|
|
167
|
+
if (!state.shouldTransform) return;
|
|
168
|
+
patchRequireRefresh(path);
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
module.exports = metroPatchRequireBabelPlugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { withAsyncStartup } from '../dist/modules/asyncStartup';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('../dist/modules/asyncStartup');
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const babelTransformer = require('__BABEL_TRANSFORMER_PATH__');
|
|
2
|
+
const babelPlugins = __BABEL_PLUGINS__;
|
|
3
|
+
function transform(config) {
|
|
4
|
+
return babelTransformer.transform({
|
|
5
|
+
...config,
|
|
6
|
+
plugins: [
|
|
7
|
+
...babelPlugins,
|
|
8
|
+
...config.plugins
|
|
9
|
+
]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
module.exports = {
|
|
13
|
+
...babelTransformer,
|
|
14
|
+
transform
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ModuleFederationConfigNormalized } from '../../types';
|
|
2
|
+
import type { Config } from '../types';
|
|
3
|
+
import type { BundleFederatedHostArgs } from './types';
|
|
4
|
+
declare global {
|
|
5
|
+
var __METRO_FEDERATION_CONFIG: ModuleFederationConfigNormalized;
|
|
6
|
+
var __METRO_FEDERATION_ORIGINAL_ENTRY_PATH: string | undefined;
|
|
7
|
+
var __METRO_FEDERATION_HOST_ENTRY_PATH: string | undefined;
|
|
8
|
+
var __METRO_FEDERATION_REMOTE_ENTRY_PATH: string | undefined;
|
|
9
|
+
var __METRO_FEDERATION_MANIFEST_PATH: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
declare function bundleFederatedHost(_argv: Array<string>, cfg: Config, args: BundleFederatedHostArgs): Promise<void>;
|
|
12
|
+
export default bundleFederatedHost;
|
|
13
|
+
export { default as bundleFederatedHostOptions } from './options';
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
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
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
14
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: definition[key]
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
})();
|
|
20
|
+
(()=>{
|
|
21
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
22
|
+
})();
|
|
23
|
+
(()=>{
|
|
24
|
+
__webpack_require__.r = (exports1)=>{
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
|
+
value: 'Module'
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
29
|
+
value: true
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
})();
|
|
33
|
+
var __webpack_exports__ = {};
|
|
34
|
+
__webpack_require__.r(__webpack_exports__);
|
|
35
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
+
bundleFederatedHostOptions: ()=>external_options_js_default(),
|
|
37
|
+
default: ()=>bundle_host
|
|
38
|
+
});
|
|
39
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
40
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
41
|
+
const external_node_util_namespaceObject = require("node:util");
|
|
42
|
+
var external_node_util_default = /*#__PURE__*/ __webpack_require__.n(external_node_util_namespaceObject);
|
|
43
|
+
const Server_namespaceObject = require("metro/src/Server");
|
|
44
|
+
var Server_default = /*#__PURE__*/ __webpack_require__.n(Server_namespaceObject);
|
|
45
|
+
const errors_js_namespaceObject = require("../../utils/errors.js");
|
|
46
|
+
const create_resolver_js_namespaceObject = require("../utils/create-resolver.js");
|
|
47
|
+
const get_community_plugin_js_namespaceObject = require("../utils/get-community-plugin.js");
|
|
48
|
+
const load_metro_config_js_namespaceObject = require("../utils/load-metro-config.js");
|
|
49
|
+
var load_metro_config_js_default = /*#__PURE__*/ __webpack_require__.n(load_metro_config_js_namespaceObject);
|
|
50
|
+
const save_bundle_and_map_js_namespaceObject = require("../utils/save-bundle-and-map.js");
|
|
51
|
+
const external_options_js_namespaceObject = require("./options.js");
|
|
52
|
+
var external_options_js_default = /*#__PURE__*/ __webpack_require__.n(external_options_js_namespaceObject);
|
|
53
|
+
async function bundleFederatedHost(_argv, cfg, args) {
|
|
54
|
+
const logger = cfg.logger ?? console;
|
|
55
|
+
global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH = args.entryFile;
|
|
56
|
+
const config = await load_metro_config_js_default()(cfg, {
|
|
57
|
+
maxWorkers: args.maxWorkers,
|
|
58
|
+
resetCache: args.resetCache,
|
|
59
|
+
config: args.config
|
|
60
|
+
});
|
|
61
|
+
const hostEntryFilepath = global.__METRO_FEDERATION_HOST_ENTRY_PATH;
|
|
62
|
+
if (!hostEntryFilepath) {
|
|
63
|
+
logger.error(`${external_node_util_default().styleText('red', 'error')} Cannot determine the host entrypoint path.`);
|
|
64
|
+
throw new errors_js_namespaceObject.CLIError('Bundling failed');
|
|
65
|
+
}
|
|
66
|
+
args.entryFile = hostEntryFilepath;
|
|
67
|
+
const communityCliPlugin = (0, get_community_plugin_js_namespaceObject.getCommunityCliPlugin)(cfg.reactNativePath);
|
|
68
|
+
const buildBundleWithConfig = communityCliPlugin.unstable_buildBundleWithConfig;
|
|
69
|
+
return buildBundleWithConfig(args, config, {
|
|
70
|
+
build: async (server, requestOpts)=>{
|
|
71
|
+
config.server.enhanceMiddleware(server.processRequest, server);
|
|
72
|
+
const resolver = await (0, create_resolver_js_namespaceObject.createResolver)(server, args.platform);
|
|
73
|
+
resolver.resolve({
|
|
74
|
+
from: config.projectRoot,
|
|
75
|
+
to: `./${external_node_path_default().relative(config.projectRoot, hostEntryFilepath)}`
|
|
76
|
+
});
|
|
77
|
+
return server.build({
|
|
78
|
+
...Server_default().DEFAULT_BUNDLE_OPTIONS,
|
|
79
|
+
...requestOpts
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
save: save_bundle_and_map_js_namespaceObject.saveBundleAndMap,
|
|
83
|
+
formatName: 'bundle'
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const bundle_host = bundleFederatedHost;
|
|
87
|
+
exports.bundleFederatedHostOptions = __webpack_exports__.bundleFederatedHostOptions;
|
|
88
|
+
exports["default"] = __webpack_exports__["default"];
|
|
89
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
90
|
+
"bundleFederatedHostOptions",
|
|
91
|
+
"default"
|
|
92
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
93
|
+
Object.defineProperty(exports, '__esModule', {
|
|
94
|
+
value: true
|
|
95
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import 'module';
|
|
2
|
+
/*#__PURE__*/ import.meta.url;
|
|
3
|
+
import node_path from "node:path";
|
|
4
|
+
import node_util from "node:util";
|
|
5
|
+
import { CLIError } from "../../utils/errors.mjs";
|
|
6
|
+
import { createResolver } from "../utils/create-resolver.mjs";
|
|
7
|
+
import { getCommunityCliPlugin } from "../utils/get-community-plugin.mjs";
|
|
8
|
+
import load_metro_config from "../utils/load-metro-config.mjs";
|
|
9
|
+
import { saveBundleAndMap } from "../utils/save-bundle-and-map.mjs";
|
|
10
|
+
import options from "./options.mjs";
|
|
11
|
+
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "node:module";
|
|
12
|
+
var __webpack_require__ = {};
|
|
13
|
+
(()=>{
|
|
14
|
+
__webpack_require__.n = (module)=>{
|
|
15
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
16
|
+
__webpack_require__.d(getter, {
|
|
17
|
+
a: getter
|
|
18
|
+
});
|
|
19
|
+
return getter;
|
|
20
|
+
};
|
|
21
|
+
})();
|
|
22
|
+
(()=>{
|
|
23
|
+
__webpack_require__.d = (exports, definition)=>{
|
|
24
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: definition[key]
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
})();
|
|
30
|
+
(()=>{
|
|
31
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
32
|
+
})();
|
|
33
|
+
const Server_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("metro/src/Server");
|
|
34
|
+
var Server_default = /*#__PURE__*/ __webpack_require__.n(Server_namespaceObject);
|
|
35
|
+
async function bundleFederatedHost(_argv, cfg, args) {
|
|
36
|
+
const logger = cfg.logger ?? console;
|
|
37
|
+
global.__METRO_FEDERATION_ORIGINAL_ENTRY_PATH = args.entryFile;
|
|
38
|
+
const config = await load_metro_config(cfg, {
|
|
39
|
+
maxWorkers: args.maxWorkers,
|
|
40
|
+
resetCache: args.resetCache,
|
|
41
|
+
config: args.config
|
|
42
|
+
});
|
|
43
|
+
const hostEntryFilepath = global.__METRO_FEDERATION_HOST_ENTRY_PATH;
|
|
44
|
+
if (!hostEntryFilepath) {
|
|
45
|
+
logger.error(`${node_util.styleText('red', 'error')} Cannot determine the host entrypoint path.`);
|
|
46
|
+
throw new CLIError('Bundling failed');
|
|
47
|
+
}
|
|
48
|
+
args.entryFile = hostEntryFilepath;
|
|
49
|
+
const communityCliPlugin = getCommunityCliPlugin(cfg.reactNativePath);
|
|
50
|
+
const buildBundleWithConfig = communityCliPlugin.unstable_buildBundleWithConfig;
|
|
51
|
+
return buildBundleWithConfig(args, config, {
|
|
52
|
+
build: async (server, requestOpts)=>{
|
|
53
|
+
config.server.enhanceMiddleware(server.processRequest, server);
|
|
54
|
+
const resolver = await createResolver(server, args.platform);
|
|
55
|
+
resolver.resolve({
|
|
56
|
+
from: config.projectRoot,
|
|
57
|
+
to: `./${node_path.relative(config.projectRoot, hostEntryFilepath)}`
|
|
58
|
+
});
|
|
59
|
+
return server.build({
|
|
60
|
+
...Server_default().DEFAULT_BUNDLE_OPTIONS,
|
|
61
|
+
...requestOpts
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
save: saveBundleAndMap,
|
|
65
|
+
formatName: 'bundle'
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const bundle_host = bundleFederatedHost;
|
|
69
|
+
export { options as bundleFederatedHostOptions, bundle_host as default };
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
default: ()=>bundle_host_options
|
|
28
|
+
});
|
|
29
|
+
const get_community_plugin_js_namespaceObject = require("../utils/get-community-plugin.js");
|
|
30
|
+
const communityCliPlugin = (0, get_community_plugin_js_namespaceObject.getCommunityCliPlugin)();
|
|
31
|
+
const options = communityCliPlugin.bundleCommand.options;
|
|
32
|
+
const bundle_host_options = options;
|
|
33
|
+
exports["default"] = __webpack_exports__["default"];
|
|
34
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
35
|
+
"default"
|
|
36
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
37
|
+
Object.defineProperty(exports, '__esModule', {
|
|
38
|
+
value: true
|
|
39
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'module';
|
|
2
|
+
/*#__PURE__*/ import.meta.url;
|
|
3
|
+
import { getCommunityCliPlugin } from "../utils/get-community-plugin.mjs";
|
|
4
|
+
const communityCliPlugin = getCommunityCliPlugin();
|
|
5
|
+
const options = communityCliPlugin.bundleCommand.options;
|
|
6
|
+
const bundle_host_options = options;
|
|
7
|
+
export { bundle_host_options as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type BundleFederatedHostArgs = {
|
|
2
|
+
assetsDest?: string;
|
|
3
|
+
assetCatalogDest?: string;
|
|
4
|
+
entryFile: string;
|
|
5
|
+
resetCache: boolean;
|
|
6
|
+
resetGlobalCache: boolean;
|
|
7
|
+
transformer?: string;
|
|
8
|
+
minify?: boolean;
|
|
9
|
+
config?: string;
|
|
10
|
+
platform: string;
|
|
11
|
+
dev: boolean;
|
|
12
|
+
bundleOutput: string;
|
|
13
|
+
bundleEncoding?: 'utf8' | 'utf16le' | 'ascii';
|
|
14
|
+
maxWorkers?: number;
|
|
15
|
+
sourcemapOutput?: string;
|
|
16
|
+
sourcemapSourcesRoot?: string;
|
|
17
|
+
sourcemapUseAbsolutePath: boolean;
|
|
18
|
+
verbose: boolean;
|
|
19
|
+
unstableTransformProfile: 'hermes-stable' | 'hermes-canary' | 'default';
|
|
20
|
+
indexedRamBundle?: boolean;
|
|
21
|
+
resolverOptions?: Array<string>;
|
|
22
|
+
};
|