@module-federation/modern-js 0.0.0-next-20240624115757 → 0.0.0-next-20240625070454
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/README.md +259 -0
- package/dist/cjs/cli/index.js +4 -1
- package/dist/cjs/cli/utils.js +12 -6
- package/dist/cjs/constant.js +5 -2
- package/dist/esm/cli/index.js +116 -121
- package/dist/esm/cli/utils.js +11 -5
- package/dist/esm/constant.js +3 -1
- package/dist/esm-node/cli/index.js +5 -2
- package/dist/esm-node/cli/utils.js +13 -7
- package/dist/esm-node/constant.js +3 -1
- package/dist/types/cli/utils.d.ts +2 -0
- package/dist/types/constant.d.ts +1 -0
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -1 +1,260 @@
|
|
|
1
1
|
# @module-federation/modern-js
|
|
2
|
+
|
|
3
|
+
This plugin provides Module Federation supporting functions for Modern.js
|
|
4
|
+
|
|
5
|
+
## Supports
|
|
6
|
+
|
|
7
|
+
- modern.js ^2.54.2
|
|
8
|
+
- Server-Side Rendering
|
|
9
|
+
|
|
10
|
+
We highly recommend referencing this application which takes advantage of the best capabilities:
|
|
11
|
+
[module-federation example](https://github.com/module-federation/core/tree/feat/modernjs-ssr/apps/modernjs-ssr)
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Installation
|
|
16
|
+
|
|
17
|
+
You can install the plugin with the following commands:
|
|
18
|
+
|
|
19
|
+
import { PackageManagerTabs } from '@theme';
|
|
20
|
+
|
|
21
|
+
<PackageManagerTabs
|
|
22
|
+
command={{
|
|
23
|
+
npm: 'npm add @module-federation/modern-js --save',
|
|
24
|
+
yarn: 'yarn add @module-federation/modern-js --save',
|
|
25
|
+
pnpm: 'pnpm add @module-federation/modern-js --save',
|
|
26
|
+
bun: 'bun add @module-federation/modern-js --save',
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
|
|
30
|
+
### Apply Plugin
|
|
31
|
+
|
|
32
|
+
Apply this plugin in `plugins` of `modern.config.ts`:
|
|
33
|
+
|
|
34
|
+
```ts title="modern.config.ts"
|
|
35
|
+
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
36
|
+
import { moduleFederationPlugin } from '@module-federation/modern-js';
|
|
37
|
+
|
|
38
|
+
export default defineConfig({
|
|
39
|
+
dev: {
|
|
40
|
+
port: 3005,
|
|
41
|
+
},
|
|
42
|
+
runtime: {
|
|
43
|
+
router: true,
|
|
44
|
+
},
|
|
45
|
+
// moduleFederationPlugin is a plug-in for modern.js, which can make certain modifications to the build/runtime
|
|
46
|
+
plugins: [appTools(), moduleFederationPlugin()],
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then create the `module-federation.config.ts` file and write the required configuration:
|
|
51
|
+
|
|
52
|
+
```ts title="module-federation.config.ts"
|
|
53
|
+
import { createModuleFederationConfig } from '@module-federation/modern-js';
|
|
54
|
+
export default createModuleFederationConfig({
|
|
55
|
+
name: 'host',
|
|
56
|
+
remotes: {
|
|
57
|
+
remote: 'remote@http://localhost:3006/mf-manifest.json',
|
|
58
|
+
},
|
|
59
|
+
shared: {
|
|
60
|
+
react: { singleton: true },
|
|
61
|
+
'react-dom': { singleton: true },
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Type support
|
|
67
|
+
|
|
68
|
+
add `/// <reference types='@module-federation/modern-js/types' />` in `modern-app-env.d.ts` to get type support.
|
|
69
|
+
|
|
70
|
+
```diff title='modern-app-env.d.ts'
|
|
71
|
+
+ /// <reference types='@module-federation/modern-js/types' />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Server-Side Rendering
|
|
75
|
+
|
|
76
|
+
:::info
|
|
77
|
+
For a better performance experience, Module Federation X Modern.js SSR only supports stream SSR.
|
|
78
|
+
:::
|
|
79
|
+
|
|
80
|
+
There is no difference between using Module Federation in SSR scenarios and CSR scenarios. Developers can just keep following the original development behavior.
|
|
81
|
+
|
|
82
|
+
But for a better user experience, we provide supporting functions/components to help developers better use Module Federation.
|
|
83
|
+
|
|
84
|
+
### createRemoteSSRComponent
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
declare function createRemoteSSRComponent(
|
|
88
|
+
props: CreateRemoteSSRComponentOptions
|
|
89
|
+
): (props: ComponentType) => React.JSX.Element;
|
|
90
|
+
|
|
91
|
+
type CreateRemoteSSRComponentOptions = {
|
|
92
|
+
loader: () => Promise<T>;
|
|
93
|
+
loading: React.ReactNode;
|
|
94
|
+
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
95
|
+
injectScript?: boolean;
|
|
96
|
+
injectLink?: boolean;
|
|
97
|
+
export?: E;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
type ComponentType = T[E] extends (...args: any) => any
|
|
101
|
+
? Parameters<T[E]>[0] extends undefined
|
|
102
|
+
? Record<string, never>
|
|
103
|
+
: Parameters<T[E]>[0]
|
|
104
|
+
: Record<string, never>;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This function will also help inject the corresponding style tag/script while loading the component. This behavior can help avoid the CSS flickering problem caused by streaming rendering and accelerate the PID (first screen interactive time).
|
|
108
|
+
|
|
109
|
+
#### Example
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import React, { FC, memo, useEffect } from 'react';
|
|
113
|
+
import { registerRemotes, createRemoteSSRComponent } from '@modern-js/runtime/mf';
|
|
114
|
+
// The remote declared in the build plug-in can be imported directly at the top level
|
|
115
|
+
import RemoteComp from 'remote/Image';
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
const RemoteSSRComponent = createRemoteSSRComponent({
|
|
119
|
+
// The remote declared in the build plug-in can also be loaded using this function: loader: () => import('remote/Image'),
|
|
120
|
+
loader: () => loadRemote('dynamic_remote/Image'),
|
|
121
|
+
loading: <div>loading...</div>,
|
|
122
|
+
fallback: ({ error }) => {
|
|
123
|
+
if (error instanceof Error && error.message.includes('not exist')) {
|
|
124
|
+
return <div>fallback - not existed id</div>;
|
|
125
|
+
}
|
|
126
|
+
return <div>fallback</div>;
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const Product: FC = () => {
|
|
131
|
+
registerRemotes([
|
|
132
|
+
{
|
|
133
|
+
name: 'dynamic_remote',
|
|
134
|
+
entry: 'http://localhost:3008/mf-manifest.json',
|
|
135
|
+
},
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
const fallback = (err: Error) => {
|
|
139
|
+
if (err.message.includes('does not exist in container')) {
|
|
140
|
+
return <div>404</div>;
|
|
141
|
+
}
|
|
142
|
+
throw err;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return <>
|
|
146
|
+
<RemoteSSRComponent />
|
|
147
|
+
<RemoteComp />
|
|
148
|
+
</>;
|
|
149
|
+
};
|
|
150
|
+
export default Product;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### loading
|
|
154
|
+
|
|
155
|
+
- Type:`React.ReactNode`
|
|
156
|
+
- Required: Yes
|
|
157
|
+
- Default value: `undefined`
|
|
158
|
+
|
|
159
|
+
Set module loading status.
|
|
160
|
+
|
|
161
|
+
#### fallback
|
|
162
|
+
|
|
163
|
+
- Type:`((err: Error) => React.ReactElement)`
|
|
164
|
+
- Required: Yes
|
|
165
|
+
- Default value: `undefined`
|
|
166
|
+
|
|
167
|
+
A fault-tolerant component that is rendered when the component fails to **load** or **render**.
|
|
168
|
+
|
|
169
|
+
Note: This component only renders this fault-tolerant component on the client side when **rendering** fails.
|
|
170
|
+
|
|
171
|
+
#### injectLink
|
|
172
|
+
|
|
173
|
+
- Type:`boolean`
|
|
174
|
+
- Required: No
|
|
175
|
+
- Default value: `true`
|
|
176
|
+
|
|
177
|
+
Whether to inject the style of the corresponding component.
|
|
178
|
+
|
|
179
|
+
#### injectScript
|
|
180
|
+
|
|
181
|
+
- Type:`boolean`
|
|
182
|
+
- Required: No
|
|
183
|
+
- Default value: `true`
|
|
184
|
+
|
|
185
|
+
Whether to inject the script of the corresponding component.
|
|
186
|
+
|
|
187
|
+
### collectSSRAssets
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
declare function createRemoteSSRComponent(
|
|
191
|
+
props: CollectSSRAssetsOptions
|
|
192
|
+
): React.ReactNode[];
|
|
193
|
+
|
|
194
|
+
type CollectSSRAssetsOptions = {
|
|
195
|
+
id: string;
|
|
196
|
+
injectScript?: boolean;
|
|
197
|
+
injectLink?: boolean;
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This function collects producer-related scripts and styles rendered on the server side and returns the script/link tag.
|
|
202
|
+
|
|
203
|
+
#### Example
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import React from 'react';
|
|
207
|
+
import { collectSSRAssets } from '@modern-js/runtime/mf';
|
|
208
|
+
import Comp from 'remote/Image';
|
|
209
|
+
|
|
210
|
+
export default (): JSX.Element => (
|
|
211
|
+
<div>
|
|
212
|
+
{collectSSRAssets({ id: 'remote/Image' })}
|
|
213
|
+
<Comp />
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### injectLink
|
|
219
|
+
|
|
220
|
+
- Type:`boolean`
|
|
221
|
+
- Required: No
|
|
222
|
+
- Default value: `true`
|
|
223
|
+
|
|
224
|
+
Whether to inject the style of the corresponding component.
|
|
225
|
+
|
|
226
|
+
#### injectScript
|
|
227
|
+
|
|
228
|
+
- Type:`boolean`
|
|
229
|
+
- Required: No
|
|
230
|
+
- Default value: `true`
|
|
231
|
+
|
|
232
|
+
Whether to inject the script of the corresponding component.
|
|
233
|
+
|
|
234
|
+
### SSRLiveReload
|
|
235
|
+
|
|
236
|
+
:::info
|
|
237
|
+
This component will not take effect in the production environment!
|
|
238
|
+
:::
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
declare function SSRLiveReload(): React.JSX.Element | null;
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
When remote components are updated, page reloads occur automatically.
|
|
245
|
+
|
|
246
|
+
#### Example
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
import { Outlet } from '@modern-js/runtime/router';
|
|
250
|
+
import { SSRLiveReload } from '@modern-js/runtime/mf';
|
|
251
|
+
|
|
252
|
+
export default function Layout() {
|
|
253
|
+
return (
|
|
254
|
+
<div>
|
|
255
|
+
<SSRLiveReload />
|
|
256
|
+
<Outlet />
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
```
|
package/dist/cjs/cli/index.js
CHANGED
|
@@ -89,10 +89,13 @@ const moduleFederationPlugin = (userConfig = {}) => ({
|
|
|
89
89
|
mfConfig: envConfig
|
|
90
90
|
});
|
|
91
91
|
};
|
|
92
|
-
const ipv4 =
|
|
92
|
+
const ipv4 = (0, import_utils2.getIPV4)();
|
|
93
93
|
return {
|
|
94
94
|
tools: {
|
|
95
95
|
rspack(config) {
|
|
96
|
+
if (enableSSR) {
|
|
97
|
+
throw new Error(`${import_constant.PLUGIN_IDENTIFIER} not support ssr for rspack bundler yet!`);
|
|
98
|
+
}
|
|
96
99
|
modifyBundlerConfig(config, false);
|
|
97
100
|
},
|
|
98
101
|
webpack(config, { isServer }) {
|
package/dist/cjs/cli/utils.js
CHANGED
|
@@ -90,11 +90,10 @@ const replaceRemoteUrl = async (mfConfig) => {
|
|
|
90
90
|
handleRemoteObject(mfConfig.remotes);
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
];
|
|
93
|
+
const patchDTSConfig = (mfConfig, isServer) => {
|
|
94
|
+
if (isServer) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
98
97
|
const ModernJSRuntime = "@modern-js/runtime/mf";
|
|
99
98
|
if (mfConfig.dts !== false) {
|
|
100
99
|
var _mfConfig_dts, _mfConfig_dts1;
|
|
@@ -122,6 +121,13 @@ const patchMFConfig = (mfConfig, isServer) => {
|
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
123
|
}
|
|
124
|
+
};
|
|
125
|
+
const patchMFConfig = (mfConfig, isServer) => {
|
|
126
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
127
|
+
const runtimePlugins = [
|
|
128
|
+
...mfConfig.runtimePlugins || []
|
|
129
|
+
];
|
|
130
|
+
patchDTSConfig(mfConfig, isServer);
|
|
125
131
|
injectRuntimePlugins(import_path.default.resolve(__dirname, "./mfRuntimePlugins/shared-strategy.js"), runtimePlugins);
|
|
126
132
|
if (isDev) {
|
|
127
133
|
injectRuntimePlugins(import_path.default.resolve(__dirname, "./mfRuntimePlugins/resolve-entry-ipv4.js"), runtimePlugins);
|
|
@@ -178,7 +184,7 @@ function patchWebpackConfig(options) {
|
|
|
178
184
|
}
|
|
179
185
|
if (!isServer && enableSSR && typeof ((_bundlerConfig_optimization1 = bundlerConfig.optimization) === null || _bundlerConfig_optimization1 === void 0 ? void 0 : _bundlerConfig_optimization1.splitChunks) === "object" && bundlerConfig.optimization.splitChunks.cacheGroups) {
|
|
180
186
|
bundlerConfig.optimization.splitChunks.chunks = "async";
|
|
181
|
-
console.warn(
|
|
187
|
+
console.warn(`${import_constant.PLUGIN_IDENTIFIER} splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"`);
|
|
182
188
|
}
|
|
183
189
|
if (((_bundlerConfig_output = bundlerConfig.output) === null || _bundlerConfig_output === void 0 ? void 0 : _bundlerConfig_output.publicPath) === "auto") {
|
|
184
190
|
var _modernjsConfig_dev, _modernjsConfig_server1;
|
package/dist/cjs/constant.js
CHANGED
|
@@ -19,13 +19,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var constant_exports = {};
|
|
20
20
|
__export(constant_exports, {
|
|
21
21
|
LOCALHOST: () => LOCALHOST,
|
|
22
|
-
MODERN_JS_SERVER_DIR: () => MODERN_JS_SERVER_DIR
|
|
22
|
+
MODERN_JS_SERVER_DIR: () => MODERN_JS_SERVER_DIR,
|
|
23
|
+
PLUGIN_IDENTIFIER: () => PLUGIN_IDENTIFIER
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(constant_exports);
|
|
25
26
|
const MODERN_JS_SERVER_DIR = "bundles";
|
|
26
27
|
const LOCALHOST = "localhost";
|
|
28
|
+
const PLUGIN_IDENTIFIER = "[ Modern.js Module Federation ]";
|
|
27
29
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28
30
|
0 && (module.exports = {
|
|
29
31
|
LOCALHOST,
|
|
30
|
-
MODERN_JS_SERVER_DIR
|
|
32
|
+
MODERN_JS_SERVER_DIR,
|
|
33
|
+
PLUGIN_IDENTIFIER
|
|
31
34
|
});
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { ModuleFederationPlugin as RspackModuleFederationPlugin } from "@module-
|
|
|
7
7
|
import { StreamingTargetPlugin, EntryChunkTrackerPlugin } from "@module-federation/node";
|
|
8
8
|
import { getMFConfig, getTargetEnvConfig, patchWebpackConfig, getIPV4 } from "./utils";
|
|
9
9
|
import { updateStatsAndManifest } from "./manifest";
|
|
10
|
-
import { MODERN_JS_SERVER_DIR } from "../constant";
|
|
10
|
+
import { MODERN_JS_SERVER_DIR, PLUGIN_IDENTIFIER } from "../constant";
|
|
11
11
|
var SSR_PLUGIN_IDENTIFIER = "mfPluginSSR";
|
|
12
12
|
var isDev = process.env.NODE_ENV === "development";
|
|
13
13
|
var moduleFederationPlugin = function() {
|
|
@@ -36,135 +36,130 @@ var moduleFederationPlugin = function() {
|
|
|
36
36
|
config: /* @__PURE__ */ _async_to_generator(function() {
|
|
37
37
|
var _modernjsConfig_dev, bundlerType, WebpackPluginConstructor, RspackPluginConstructor, MFBundlerPlugin, modifyBundlerConfig, ipv4;
|
|
38
38
|
return _ts_generator(this, function(_state2) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
bundlerType = useAppContext().bundlerType === "rspack" ? "rspack" : "webpack";
|
|
40
|
+
WebpackPluginConstructor = userConfig.webpackPluginImplementation || WebpackModuleFederationPlugin;
|
|
41
|
+
RspackPluginConstructor = userConfig.rspackPluginImplementation || RspackModuleFederationPlugin;
|
|
42
|
+
MFBundlerPlugin = bundlerType === "rspack" ? RspackPluginConstructor : WebpackPluginConstructor;
|
|
43
|
+
if (enableSSR) {
|
|
44
|
+
process.env["MF_DISABLE_EMIT_STATS"] = "true";
|
|
45
|
+
process.env["MF_SSR_PRJ"] = "true";
|
|
46
|
+
}
|
|
47
|
+
modifyBundlerConfig = function(config, isServer) {
|
|
48
|
+
var envConfig = getTargetEnvConfig(mfConfig, isServer);
|
|
49
|
+
if (isServer) {
|
|
50
|
+
var _config_plugins, _config_plugins1;
|
|
51
|
+
nodePlugin = new MFBundlerPlugin(envConfig);
|
|
52
|
+
(_config_plugins = config.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(nodePlugin);
|
|
53
|
+
(_config_plugins1 = config.plugins) === null || _config_plugins1 === void 0 ? void 0 : _config_plugins1.push(new StreamingTargetPlugin(envConfig));
|
|
54
|
+
if (isDev) {
|
|
55
|
+
var _config_plugins2;
|
|
56
|
+
(_config_plugins2 = config.plugins) === null || _config_plugins2 === void 0 ? void 0 : _config_plugins2.push(new EntryChunkTrackerPlugin());
|
|
48
57
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
} else {
|
|
59
|
+
var _config_output, _config_plugins3;
|
|
60
|
+
outputDir = ((_config_output = config.output) === null || _config_output === void 0 ? void 0 : _config_output.path) || path.resolve(process.cwd(), "dist");
|
|
61
|
+
browserPlugin = new MFBundlerPlugin(envConfig);
|
|
62
|
+
(_config_plugins3 = config.plugins) === null || _config_plugins3 === void 0 ? void 0 : _config_plugins3.push(browserPlugin);
|
|
63
|
+
}
|
|
64
|
+
patchWebpackConfig({
|
|
65
|
+
bundlerConfig: config,
|
|
66
|
+
isServer,
|
|
67
|
+
modernjsConfig,
|
|
68
|
+
mfConfig: envConfig
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
ipv4 = getIPV4();
|
|
72
|
+
return [
|
|
73
|
+
2,
|
|
74
|
+
{
|
|
75
|
+
tools: {
|
|
76
|
+
rspack: function rspack(config) {
|
|
77
|
+
if (enableSSR) {
|
|
78
|
+
throw new Error("".concat(PLUGIN_IDENTIFIER, " not support ssr for rspack bundler yet!"));
|
|
59
79
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
73
|
-
return [
|
|
74
|
-
4,
|
|
75
|
-
getIPV4()
|
|
76
|
-
];
|
|
77
|
-
case 1:
|
|
78
|
-
ipv4 = _state2.sent();
|
|
79
|
-
return [
|
|
80
|
-
2,
|
|
81
|
-
{
|
|
82
|
-
tools: {
|
|
83
|
-
rspack: function rspack(config) {
|
|
84
|
-
modifyBundlerConfig(config, false);
|
|
85
|
-
},
|
|
86
|
-
webpack: function webpack(config, param2) {
|
|
87
|
-
var isServer = param2.isServer;
|
|
88
|
-
var _modernjsConfig_source;
|
|
89
|
-
modifyBundlerConfig(config, isServer);
|
|
90
|
-
var enableAsyncEntry = (_modernjsConfig_source = modernjsConfig.source) === null || _modernjsConfig_source === void 0 ? void 0 : _modernjsConfig_source.enableAsyncEntry;
|
|
91
|
-
if (!enableAsyncEntry && mfConfig.async !== false) {
|
|
92
|
-
var _config_plugins;
|
|
93
|
-
var asyncBoundaryPluginOptions = typeof mfConfig.async === "object" ? mfConfig.async : {
|
|
94
|
-
eager: function(module) {
|
|
95
|
-
return module && /\.federation/.test((module === null || module === void 0 ? void 0 : module.request) || "");
|
|
96
|
-
},
|
|
97
|
-
excludeChunk: function(chunk) {
|
|
98
|
-
return chunk.name === mfConfig.name;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
(_config_plugins = config.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(new AsyncBoundaryPlugin(asyncBoundaryPluginOptions));
|
|
102
|
-
}
|
|
103
|
-
config.ignoreWarnings = config.ignoreWarnings || [];
|
|
104
|
-
config.ignoreWarnings.push(function(warning) {
|
|
105
|
-
if (warning.message.includes("external script")) {
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
return false;
|
|
109
|
-
});
|
|
110
|
-
},
|
|
111
|
-
devServer: {
|
|
112
|
-
headers: {
|
|
113
|
-
"Access-Control-Allow-Origin": "*",
|
|
114
|
-
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
115
|
-
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
|
|
80
|
+
modifyBundlerConfig(config, false);
|
|
81
|
+
},
|
|
82
|
+
webpack: function webpack(config, param2) {
|
|
83
|
+
var isServer = param2.isServer;
|
|
84
|
+
var _modernjsConfig_source;
|
|
85
|
+
modifyBundlerConfig(config, isServer);
|
|
86
|
+
var enableAsyncEntry = (_modernjsConfig_source = modernjsConfig.source) === null || _modernjsConfig_source === void 0 ? void 0 : _modernjsConfig_source.enableAsyncEntry;
|
|
87
|
+
if (!enableAsyncEntry && mfConfig.async !== false) {
|
|
88
|
+
var _config_plugins;
|
|
89
|
+
var asyncBoundaryPluginOptions = typeof mfConfig.async === "object" ? mfConfig.async : {
|
|
90
|
+
eager: function(module) {
|
|
91
|
+
return module && /\.federation/.test((module === null || module === void 0 ? void 0 : module.request) || "");
|
|
116
92
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!enableSSR) {
|
|
120
|
-
next();
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
try {
|
|
124
|
-
var _req_url, _req_url1, _req_url2;
|
|
125
|
-
var SERVER_PREFIX = "/".concat(MODERN_JS_SERVER_DIR);
|
|
126
|
-
if (((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.startsWith(SERVER_PREFIX)) || ((_req_url1 = req.url) === null || _req_url1 === void 0 ? void 0 : _req_url1.includes(".json")) && !((_req_url2 = req.url) === null || _req_url2 === void 0 ? void 0 : _req_url2.includes("hot-update"))) {
|
|
127
|
-
var filepath = path.join(process.cwd(), "dist".concat(req.url));
|
|
128
|
-
fs.statSync(filepath);
|
|
129
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
130
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
|
131
|
-
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, content-type, Authorization");
|
|
132
|
-
fs.createReadStream(filepath).pipe(res);
|
|
133
|
-
} else {
|
|
134
|
-
next();
|
|
135
|
-
}
|
|
136
|
-
} catch (err) {
|
|
137
|
-
if (process.env.FEDERATION_DEBUG) {
|
|
138
|
-
console.error(err);
|
|
139
|
-
}
|
|
140
|
-
next();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
]
|
|
144
|
-
},
|
|
145
|
-
bundlerChain: function bundlerChain(chain, param2) {
|
|
146
|
-
var isServer = param2.isServer;
|
|
147
|
-
if (isDev && !isServer) {
|
|
148
|
-
chain.externals({
|
|
149
|
-
"@module-federation/node/utils": "NOT_USED_IN_BROWSER"
|
|
150
|
-
});
|
|
93
|
+
excludeChunk: function(chunk) {
|
|
94
|
+
return chunk.name === mfConfig.name;
|
|
151
95
|
}
|
|
96
|
+
};
|
|
97
|
+
(_config_plugins = config.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(new AsyncBoundaryPlugin(asyncBoundaryPluginOptions));
|
|
98
|
+
}
|
|
99
|
+
config.ignoreWarnings = config.ignoreWarnings || [];
|
|
100
|
+
config.ignoreWarnings.push(function(warning) {
|
|
101
|
+
if (warning.message.includes("external script")) {
|
|
102
|
+
return true;
|
|
152
103
|
}
|
|
104
|
+
return false;
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
devServer: {
|
|
108
|
+
headers: {
|
|
109
|
+
"Access-Control-Allow-Origin": "*",
|
|
110
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
111
|
+
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
|
|
153
112
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
113
|
+
before: [
|
|
114
|
+
function(req, res, next) {
|
|
115
|
+
if (!enableSSR) {
|
|
116
|
+
next();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
var _req_url, _req_url1, _req_url2;
|
|
121
|
+
var SERVER_PREFIX = "/".concat(MODERN_JS_SERVER_DIR);
|
|
122
|
+
if (((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.startsWith(SERVER_PREFIX)) || ((_req_url1 = req.url) === null || _req_url1 === void 0 ? void 0 : _req_url1.includes(".json")) && !((_req_url2 = req.url) === null || _req_url2 === void 0 ? void 0 : _req_url2.includes("hot-update"))) {
|
|
123
|
+
var filepath = path.join(process.cwd(), "dist".concat(req.url));
|
|
124
|
+
fs.statSync(filepath);
|
|
125
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
126
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
|
127
|
+
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, content-type, Authorization");
|
|
128
|
+
fs.createReadStream(filepath).pipe(res);
|
|
129
|
+
} else {
|
|
130
|
+
next();
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
if (process.env.FEDERATION_DEBUG) {
|
|
134
|
+
console.error(err);
|
|
135
|
+
}
|
|
136
|
+
next();
|
|
137
|
+
}
|
|
160
138
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
bundlerChain: function bundlerChain(chain, param2) {
|
|
142
|
+
var isServer = param2.isServer;
|
|
143
|
+
if (isDev && !isServer) {
|
|
144
|
+
chain.externals({
|
|
145
|
+
"@module-federation/node/utils": "NOT_USED_IN_BROWSER"
|
|
146
|
+
});
|
|
164
147
|
}
|
|
165
148
|
}
|
|
166
|
-
|
|
167
|
-
|
|
149
|
+
},
|
|
150
|
+
source: {
|
|
151
|
+
alias: {
|
|
152
|
+
"@modern-js/runtime/mf": require.resolve("@module-federation/modern-js/runtime")
|
|
153
|
+
},
|
|
154
|
+
define: {
|
|
155
|
+
FEDERATION_IPV4: JSON.stringify(ipv4)
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
dev: {
|
|
159
|
+
assetPrefix: (modernjsConfig === null || modernjsConfig === void 0 ? void 0 : (_modernjsConfig_dev = modernjsConfig.dev) === null || _modernjsConfig_dev === void 0 ? void 0 : _modernjsConfig_dev.assetPrefix) ? modernjsConfig.dev.assetPrefix : true
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
];
|
|
168
163
|
});
|
|
169
164
|
}),
|
|
170
165
|
modifyEntryImports: function modifyEntryImports(param2) {
|
package/dist/esm/cli/utils.js
CHANGED
|
@@ -7,7 +7,7 @@ import { encodeName } from "@module-federation/sdk";
|
|
|
7
7
|
import path from "path";
|
|
8
8
|
import os from "os";
|
|
9
9
|
import { bundle } from "@modern-js/node-bundle-require";
|
|
10
|
-
import { LOCALHOST } from "../constant";
|
|
10
|
+
import { LOCALHOST, PLUGIN_IDENTIFIER } from "../constant";
|
|
11
11
|
var defaultPath = path.resolve(process.cwd(), "module-federation.config.ts");
|
|
12
12
|
var getMFConfig = function() {
|
|
13
13
|
var _ref = _async_to_generator(function(userConfig) {
|
|
@@ -103,9 +103,10 @@ var replaceRemoteUrl = function() {
|
|
|
103
103
|
return _ref.apply(this, arguments);
|
|
104
104
|
};
|
|
105
105
|
}();
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
var patchDTSConfig = function(mfConfig, isServer) {
|
|
107
|
+
if (isServer) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
109
110
|
var ModernJSRuntime = "@modern-js/runtime/mf";
|
|
110
111
|
if (mfConfig.dts !== false) {
|
|
111
112
|
var _mfConfig_dts, _mfConfig_dts1;
|
|
@@ -133,6 +134,11 @@ var patchMFConfig = function(mfConfig, isServer) {
|
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
}
|
|
137
|
+
};
|
|
138
|
+
var patchMFConfig = function(mfConfig, isServer) {
|
|
139
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
140
|
+
var runtimePlugins = _to_consumable_array(mfConfig.runtimePlugins || []);
|
|
141
|
+
patchDTSConfig(mfConfig, isServer);
|
|
136
142
|
injectRuntimePlugins(path.resolve(__dirname, "./mfRuntimePlugins/shared-strategy.js"), runtimePlugins);
|
|
137
143
|
if (isDev) {
|
|
138
144
|
injectRuntimePlugins(path.resolve(__dirname, "./mfRuntimePlugins/resolve-entry-ipv4.js"), runtimePlugins);
|
|
@@ -184,7 +190,7 @@ function patchWebpackConfig(options) {
|
|
|
184
190
|
}
|
|
185
191
|
if (!isServer && enableSSR && typeof ((_bundlerConfig_optimization1 = bundlerConfig.optimization) === null || _bundlerConfig_optimization1 === void 0 ? void 0 : _bundlerConfig_optimization1.splitChunks) === "object" && bundlerConfig.optimization.splitChunks.cacheGroups) {
|
|
186
192
|
bundlerConfig.optimization.splitChunks.chunks = "async";
|
|
187
|
-
console.warn(
|
|
193
|
+
console.warn("".concat(PLUGIN_IDENTIFIER, ' splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"'));
|
|
188
194
|
}
|
|
189
195
|
if (((_bundlerConfig_output = bundlerConfig.output) === null || _bundlerConfig_output === void 0 ? void 0 : _bundlerConfig_output.publicPath) === "auto") {
|
|
190
196
|
var _modernjsConfig_dev, _modernjsConfig_server1;
|
package/dist/esm/constant.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ModuleFederationPlugin as RspackModuleFederationPlugin } from "@module-
|
|
|
5
5
|
import { StreamingTargetPlugin, EntryChunkTrackerPlugin } from "@module-federation/node";
|
|
6
6
|
import { getMFConfig, getTargetEnvConfig, patchWebpackConfig, getIPV4 } from "./utils";
|
|
7
7
|
import { updateStatsAndManifest } from "./manifest";
|
|
8
|
-
import { MODERN_JS_SERVER_DIR } from "../constant";
|
|
8
|
+
import { MODERN_JS_SERVER_DIR, PLUGIN_IDENTIFIER } from "../constant";
|
|
9
9
|
const SSR_PLUGIN_IDENTIFIER = "mfPluginSSR";
|
|
10
10
|
const isDev = process.env.NODE_ENV === "development";
|
|
11
11
|
const moduleFederationPlugin = (userConfig = {}) => ({
|
|
@@ -53,10 +53,13 @@ const moduleFederationPlugin = (userConfig = {}) => ({
|
|
|
53
53
|
mfConfig: envConfig
|
|
54
54
|
});
|
|
55
55
|
};
|
|
56
|
-
const ipv4 =
|
|
56
|
+
const ipv4 = getIPV4();
|
|
57
57
|
return {
|
|
58
58
|
tools: {
|
|
59
59
|
rspack(config) {
|
|
60
|
+
if (enableSSR) {
|
|
61
|
+
throw new Error(`${PLUGIN_IDENTIFIER} not support ssr for rspack bundler yet!`);
|
|
62
|
+
}
|
|
60
63
|
modifyBundlerConfig(config, false);
|
|
61
64
|
},
|
|
62
65
|
webpack(config, { isServer }) {
|
|
@@ -2,7 +2,7 @@ import { encodeName } from "@module-federation/sdk";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import os from "os";
|
|
4
4
|
import { bundle } from "@modern-js/node-bundle-require";
|
|
5
|
-
import { LOCALHOST } from "../constant";
|
|
5
|
+
import { LOCALHOST, PLUGIN_IDENTIFIER } from "../constant";
|
|
6
6
|
const defaultPath = path.resolve(process.cwd(), "module-federation.config.ts");
|
|
7
7
|
const getMFConfig = async (userConfig) => {
|
|
8
8
|
const { config, configPath } = userConfig;
|
|
@@ -53,11 +53,10 @@ const replaceRemoteUrl = async (mfConfig) => {
|
|
|
53
53
|
handleRemoteObject(mfConfig.remotes);
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
];
|
|
56
|
+
const patchDTSConfig = (mfConfig, isServer) => {
|
|
57
|
+
if (isServer) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
61
60
|
const ModernJSRuntime = "@modern-js/runtime/mf";
|
|
62
61
|
if (mfConfig.dts !== false) {
|
|
63
62
|
var _mfConfig_dts, _mfConfig_dts1;
|
|
@@ -85,6 +84,13 @@ const patchMFConfig = (mfConfig, isServer) => {
|
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
}
|
|
87
|
+
};
|
|
88
|
+
const patchMFConfig = (mfConfig, isServer) => {
|
|
89
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
90
|
+
const runtimePlugins = [
|
|
91
|
+
...mfConfig.runtimePlugins || []
|
|
92
|
+
];
|
|
93
|
+
patchDTSConfig(mfConfig, isServer);
|
|
88
94
|
injectRuntimePlugins(path.resolve(__dirname, "./mfRuntimePlugins/shared-strategy.js"), runtimePlugins);
|
|
89
95
|
if (isDev) {
|
|
90
96
|
injectRuntimePlugins(path.resolve(__dirname, "./mfRuntimePlugins/resolve-entry-ipv4.js"), runtimePlugins);
|
|
@@ -141,7 +147,7 @@ function patchWebpackConfig(options) {
|
|
|
141
147
|
}
|
|
142
148
|
if (!isServer && enableSSR && typeof ((_bundlerConfig_optimization1 = bundlerConfig.optimization) === null || _bundlerConfig_optimization1 === void 0 ? void 0 : _bundlerConfig_optimization1.splitChunks) === "object" && bundlerConfig.optimization.splitChunks.cacheGroups) {
|
|
143
149
|
bundlerConfig.optimization.splitChunks.chunks = "async";
|
|
144
|
-
console.warn(
|
|
150
|
+
console.warn(`${PLUGIN_IDENTIFIER} splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"`);
|
|
145
151
|
}
|
|
146
152
|
if (((_bundlerConfig_output = bundlerConfig.output) === null || _bundlerConfig_output === void 0 ? void 0 : _bundlerConfig_output.publicPath) === "auto") {
|
|
147
153
|
var _modernjsConfig_dev, _modernjsConfig_server1;
|
|
@@ -14,6 +14,7 @@ export declare const patchMFConfig: (mfConfig: moduleFederationPlugin.ModuleFede
|
|
|
14
14
|
runtime?: moduleFederationPlugin.EntryRuntime | undefined;
|
|
15
15
|
shareScope?: string | undefined;
|
|
16
16
|
shared?: moduleFederationPlugin.Shared | undefined;
|
|
17
|
+
getPublicPath?: string | undefined;
|
|
17
18
|
implementation?: string | undefined;
|
|
18
19
|
manifest?: boolean | moduleFederationPlugin.PluginManifestOptions | undefined;
|
|
19
20
|
dev?: boolean | moduleFederationPlugin.PluginDevOptions | undefined;
|
|
@@ -31,6 +32,7 @@ export declare function getTargetEnvConfig(mfConfig: moduleFederationPlugin.Modu
|
|
|
31
32
|
runtime?: moduleFederationPlugin.EntryRuntime | undefined;
|
|
32
33
|
shareScope?: string | undefined;
|
|
33
34
|
shared?: moduleFederationPlugin.Shared | undefined;
|
|
35
|
+
getPublicPath?: string | undefined;
|
|
34
36
|
implementation?: string | undefined;
|
|
35
37
|
manifest?: boolean | moduleFederationPlugin.PluginManifestOptions | undefined;
|
|
36
38
|
dev?: boolean | moduleFederationPlugin.PluginDevOptions | undefined;
|
package/dist/types/constant.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/modern-js",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20240625070454",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/",
|
|
6
6
|
"types.d.ts",
|
|
@@ -43,21 +43,21 @@
|
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@swc/helpers": "0.5.3",
|
|
46
|
-
"@modern-js/utils": "^2.
|
|
47
|
-
"@modern-js/node-bundle-require": "^2.
|
|
46
|
+
"@modern-js/utils": "^2.54.2",
|
|
47
|
+
"@modern-js/node-bundle-require": "^2.54.2",
|
|
48
48
|
"node-fetch": "~3.3.0",
|
|
49
49
|
"react-error-boundary": "4.0.13",
|
|
50
|
-
"@module-federation/sdk": "0.0.0-next-
|
|
51
|
-
"@module-federation/enhanced": "0.0.0-next-
|
|
52
|
-
"@module-federation/node": "0.0.0-next-
|
|
50
|
+
"@module-federation/sdk": "0.0.0-next-20240625070454",
|
|
51
|
+
"@module-federation/enhanced": "0.0.0-next-20240625070454",
|
|
52
|
+
"@module-federation/node": "0.0.0-next-20240625070454"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@modern-js/app-tools": "^2.
|
|
56
|
-
"@modern-js/core": "^2.
|
|
57
|
-
"@modern-js/runtime": "^2.
|
|
58
|
-
"@modern-js/module-tools": "^2.
|
|
59
|
-
"@modern-js/tsconfig": "^2.
|
|
60
|
-
"@module-federation/manifest": "0.0.0-next-
|
|
55
|
+
"@modern-js/app-tools": "^2.54.2",
|
|
56
|
+
"@modern-js/core": "^2.54.2",
|
|
57
|
+
"@modern-js/runtime": "^2.54.2",
|
|
58
|
+
"@modern-js/module-tools": "^2.54.2",
|
|
59
|
+
"@modern-js/tsconfig": "^2.54.2",
|
|
60
|
+
"@module-federation/manifest": "0.0.0-next-20240625070454"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"react": ">=17",
|