@modern-js/main-doc 2.67.6 → 2.67.7
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/docs/en/apis/app/hooks/src/routes.mdx +0 -70
- package/docs/en/configure/app/performance/transform-lodash.mdx +4 -1
- package/docs/en/configure/app/source/module-scopes.mdx +4 -1
- package/docs/en/configure/app/tools/terser.mdx +4 -2
- package/docs/en/configure/app/tools/ts-loader.mdx +4 -1
- package/docs/en/configure/app/tools/webpack-chain.mdx +4 -1
- package/docs/en/configure/app/tools/webpack.mdx +4 -1
- package/docs/en/guides/advanced-features/web-server.mdx +16 -4
- package/docs/en/guides/basic-features/data/data-cache.mdx +1 -1
- package/docs/en/guides/basic-features/render/ssr.mdx +1 -1
- package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -2
- package/docs/en/guides/basic-features/routes.mdx +72 -0
- package/docs/en/guides/basic-features/static-assets/wasm-assets.mdx +1 -1
- package/docs/en/guides/topic-detail/module-federation/deploy.mdx +83 -7
- package/docs/en/guides/topic-detail/module-federation/usage.mdx +2 -4
- package/docs/en/plugin/cli-plugins/api.mdx +1 -1
- package/docs/zh/configure/app/performance/transform-lodash.mdx +4 -1
- package/docs/zh/configure/app/source/module-scopes.mdx +4 -1
- package/docs/zh/configure/app/tools/terser.mdx +4 -2
- package/docs/zh/configure/app/tools/ts-loader.mdx +4 -1
- package/docs/zh/configure/app/tools/webpack-chain.mdx +4 -1
- package/docs/zh/configure/app/tools/webpack.mdx +4 -1
- package/docs/zh/guides/advanced-features/web-server.mdx +17 -4
- package/docs/zh/guides/basic-features/data/data-cache.mdx +1 -1
- package/docs/zh/guides/basic-features/render/ssr.mdx +1 -1
- package/docs/zh/guides/basic-features/render/streaming-ssr.mdx +1 -1
- package/docs/zh/guides/basic-features/static-assets/wasm-assets.mdx +1 -1
- package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +83 -7
- package/docs/zh/guides/topic-detail/module-federation/usage.mdx +2 -4
- package/docs/zh/plugin/cli-plugins/api.mdx +1 -1
- package/package.json +2 -2
@@ -88,73 +88,3 @@ export default () => {
|
|
88
88
|
`<Outlet>` is a new API in React Router 6. For details, see [Outlet](https://reactrouter.com/en/main/components/outlet#outlet).
|
89
89
|
|
90
90
|
:::
|
91
|
-
|
92
|
-
## Upgrading to React Router v7
|
93
|
-
|
94
|
-
React Router v7 reduces bundle size (approximately 15% smaller) compared to React Router v6, provides a more efficient route matching algorithm, and offers better support for React 19 and TypeScript. There are very few breaking changes compared to React Router v6, and Modern.js has made both versions compatible, allowing for a seamless upgrade by simply installing and registering the appropriate plugin.
|
95
|
-
|
96
|
-
:::info
|
97
|
-
|
98
|
-
For more changes from React Router v6 to React Router v7, check the [documentation](https://reactrouter.com/upgrading/v6#upgrade-to-v7)
|
99
|
-
|
100
|
-
:::
|
101
|
-
|
102
|
-
### Requirements
|
103
|
-
|
104
|
-
React Router v7 has certain environment requirements:
|
105
|
-
|
106
|
-
- Node.js 20+
|
107
|
-
- React 18+
|
108
|
-
- React DOM 18+
|
109
|
-
|
110
|
-
### Install the Plugin
|
111
|
-
|
112
|
-
First, install the Modern.js React Router v7 plugin:
|
113
|
-
|
114
|
-
```bash
|
115
|
-
pnpm add @modern-js/plugin-router-v7
|
116
|
-
```
|
117
|
-
|
118
|
-
### Configure the Plugin
|
119
|
-
|
120
|
-
Register the plugin in `modern.config.ts`:
|
121
|
-
|
122
|
-
```ts title="modern.config.ts"
|
123
|
-
import { routerPlugin } from '@modern-js/plugin-router-v7';
|
124
|
-
|
125
|
-
export default {
|
126
|
-
runtime: {
|
127
|
-
router: true,
|
128
|
-
},
|
129
|
-
plugins: [routerPlugin()],
|
130
|
-
};
|
131
|
-
```
|
132
|
-
|
133
|
-
### Code Changes
|
134
|
-
|
135
|
-
In React Router v7, you no longer need to use the `defer` API; you can directly return data in the data loader:
|
136
|
-
|
137
|
-
```ts title="routes/page.data.ts"
|
138
|
-
import { defer } from '@modern-js/runtime/router';
|
139
|
-
|
140
|
-
export const loader = async ({ params }) => {
|
141
|
-
// Recommended v7 style
|
142
|
-
const user = fetchUser(params.id)
|
143
|
-
return { user };
|
144
|
-
|
145
|
-
// v6 style, still compatible with Modern.js
|
146
|
-
return defer({ data: 'hello' });
|
147
|
-
};
|
148
|
-
```
|
149
|
-
|
150
|
-
React Router v7 has also deprecated the `json` API:
|
151
|
-
|
152
|
-
```ts title="routes/page.data.ts"
|
153
|
-
export const loader = async ({ params }) => {
|
154
|
-
// Recommended v7 style
|
155
|
-
return { data: 'hello' };
|
156
|
-
|
157
|
-
// v6 style, still compatible with Modern.js
|
158
|
-
return json({ data: 'hello' });
|
159
|
-
};
|
160
|
-
```
|
@@ -4,9 +4,12 @@ title: transformLodash
|
|
4
4
|
|
5
5
|
# performance.transformLodash
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `boolean`
|
8
12
|
- **Default:** `true`
|
9
|
-
- **Bundler:** `only support webpack`
|
10
13
|
|
11
14
|
Specifies whether to modularize the import of [lodash](https://www.npmjs.com/package/lodash) and remove unused lodash modules to reduce the code size of lodash.
|
12
15
|
|
@@ -4,9 +4,12 @@ title: moduleScopes
|
|
4
4
|
|
5
5
|
# source.moduleScopes
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `Array<string | Regexp> | Function`
|
8
12
|
- **Default:** `undefined`
|
9
|
-
- **Bundler:** `only support webpack`
|
10
13
|
|
11
14
|
Restrict importing paths. After configuring this option, all source files can only import code from the specific paths, and import code from other paths is not allowed.
|
12
15
|
|
@@ -4,6 +4,10 @@ title: terser
|
|
4
4
|
|
5
5
|
# tools.terser
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `Object | Function | undefined`
|
8
12
|
- **Default:**
|
9
13
|
|
@@ -17,8 +21,6 @@ const defaultTerserOptions = {
|
|
17
21
|
};
|
18
22
|
```
|
19
23
|
|
20
|
-
- **Bundler:** `only support webpack`
|
21
|
-
|
22
24
|
When building for production, Modern.js will minimize the JavaScript code through [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin). The config of [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) can be modified via `tools.terser`.
|
23
25
|
|
24
26
|
### Object Type
|
@@ -4,9 +4,12 @@ title: tsLoader
|
|
4
4
|
|
5
5
|
# tools.tsLoader
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `Object | Function | undefined`
|
8
12
|
- **Default:** `undefined`
|
9
|
-
- **Bundler:** `only support webpack`
|
10
13
|
|
11
14
|
:::warning Deprecated
|
12
15
|
|
@@ -4,9 +4,12 @@ title: webpackChain
|
|
4
4
|
|
5
5
|
# tools.webpackChain
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `Function | undefined`
|
8
12
|
- **Default:** `undefined`
|
9
|
-
- **Bundler:** `only support webpack`
|
10
13
|
|
11
14
|
You can modify the webpack configuration by configuring `tools.webpackChain` which is type of `Function`. The function receives two parameters, the first is the original webpack chain object, and the second is an object containing some utils.
|
12
15
|
|
@@ -4,9 +4,12 @@ title: webpack
|
|
4
4
|
|
5
5
|
# tools.webpack
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >Webpack Only</Badge>
|
10
|
+
|
7
11
|
- **Type:** `Object | Function | undefined`
|
8
12
|
- **Default:** `undefined`
|
9
|
-
- **Bundler:** `only support webpack`
|
10
13
|
|
11
14
|
`tools.webpack` is used to configure [webpack](https://webpack.js.org/).
|
12
15
|
|
@@ -12,10 +12,15 @@ Modern.js encapsulates most server-side capabilities required by projects, typic
|
|
12
12
|
You must ensure that the Modern.js version is x.67.5 or above.
|
13
13
|
:::
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
Developers can execute the `pnpm run new` command in the project root directory to start the "Custom Web Server" feature:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
? Select operation: Create project element
|
19
|
+
? Select element type: Create "Custom Web Server" source directory
|
20
|
+
```
|
21
|
+
|
22
|
+
After executing the command, a `server/modern.server.ts` file will be automatically created in the project directory, where you can write custom logic.
|
23
|
+
|
19
24
|
|
20
25
|
## Capabilities of the Custom Web Server
|
21
26
|
|
@@ -230,6 +235,13 @@ export default () => {
|
|
230
235
|
The legacy API is compatible but no longer recommended. For extending server capabilities, please refer to [Custom Web Server](/guides/advanced-features/web-server.html#custom-web-server). For migration guidelines, see [Migrating to the New Version of Custom Web Server](/guides/advanced-features/web-server.html#migrate-to-the-new-version-of-custom-web-server).
|
231
236
|
:::
|
232
237
|
|
238
|
+
### Enable
|
239
|
+
To enable the custom Web Server feature, follow these steps:
|
240
|
+
1. Add `@modern-js/plugin-server`、`tsconfig-paths` and `ts-node` to `devDependencies` and install them.
|
241
|
+
2. Add `server` to the `include` section of `tsconfig`.
|
242
|
+
3. Register the `@modern-js/plugin-server` plugin in `modern.config.ts`.
|
243
|
+
4. Create a `server/index.ts` file in the project directory, where you can write custom logic.
|
244
|
+
|
233
245
|
### Unstable Middleware
|
234
246
|
|
235
247
|
Modern.js supports adding rendering middleware to the Web Server, allowing custom logic execution before and after processing page routes.
|
@@ -166,7 +166,7 @@ const getComplexStatistics = cache(
|
|
166
166
|
}
|
167
167
|
);
|
168
168
|
|
169
|
-
revalidateTag('dashboard
|
169
|
+
revalidateTag('dashboard'); // Invalidates the cache for both getDashboardStats and getComplexStatistics functions
|
170
170
|
```
|
171
171
|
|
172
172
|
|
@@ -217,7 +217,7 @@ document.addEventListener('load', () => {
|
|
217
217
|
export const doSomething = () => {}
|
218
218
|
```
|
219
219
|
|
220
|
-
Directly referencing this in a component will cause
|
220
|
+
Directly referencing this in a component will cause SSR to throw errors, even if you use environment variables to conditionally load the code. The side effects in the dependency will still execute.
|
221
221
|
|
222
222
|
```tsx title="routes/page.tsx"
|
223
223
|
import { doSomething } from 'packageA';
|
@@ -68,7 +68,7 @@ Here, `user` is a Promise object representing asynchronously fetched data, proce
|
|
68
68
|
Additionally, `defer` can receive both asynchronous and synchronous data. In the example below, short-duration requests are returned using object data, while longer-duration requests are returned using a Promise:
|
69
69
|
|
70
70
|
```ts title="user/[id]/page.data.ts"
|
71
|
-
export const loader = ({ params }: LoaderFunctionArgs) => {
|
71
|
+
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
72
72
|
const userId = params.id;
|
73
73
|
|
74
74
|
const user = new Promise<User>(resolve => {
|
@@ -227,4 +227,4 @@ import StreamSSRPerformance from '@site-docs-en/components/stream-ssr-performanc
|
|
227
227
|
## Related Documentation
|
228
228
|
|
229
229
|
1. [Deferred Data](https://reactrouter.com/en/main/guides/deferred)
|
230
|
-
2. [New Suspense SSR Architecture in React 18](https://github.com/reactwg/react-18/discussions/37)
|
230
|
+
2. [New Suspense SSR Architecture in React 18](https://github.com/reactwg/react-18/discussions/37)
|
@@ -490,6 +490,76 @@ import Motivation from '@site-docs-en/components/convention-routing-motivation';
|
|
490
490
|
|
491
491
|
<Motivation />
|
492
492
|
|
493
|
+
## Upgrading to React Router v7
|
494
|
+
|
495
|
+
React Router v7 reduces bundle size (approximately 15% smaller) compared to React Router v6, provides a more efficient route matching algorithm, and offers better support for React 19 and TypeScript. There are very few breaking changes compared to React Router v6, and Modern.js has made both versions compatible, allowing for a seamless upgrade by simply installing and registering the appropriate plugin.
|
496
|
+
|
497
|
+
:::info
|
498
|
+
|
499
|
+
For more changes from React Router v6 to React Router v7, check the [documentation](https://reactrouter.com/upgrading/v6#upgrade-to-v7)
|
500
|
+
|
501
|
+
:::
|
502
|
+
|
503
|
+
### Requirements
|
504
|
+
|
505
|
+
React Router v7 has certain environment requirements:
|
506
|
+
|
507
|
+
- Node.js 20+
|
508
|
+
- React 18+
|
509
|
+
- React DOM 18+
|
510
|
+
|
511
|
+
### Install the Plugin
|
512
|
+
|
513
|
+
First, install the Modern.js React Router v7 plugin:
|
514
|
+
|
515
|
+
```bash
|
516
|
+
pnpm add @modern-js/plugin-router-v7
|
517
|
+
```
|
518
|
+
|
519
|
+
### Configure the Plugin
|
520
|
+
|
521
|
+
Register the plugin in `modern.config.ts`:
|
522
|
+
|
523
|
+
```ts title="modern.config.ts"
|
524
|
+
import { routerPlugin } from '@modern-js/plugin-router-v7';
|
525
|
+
|
526
|
+
export default {
|
527
|
+
runtime: {
|
528
|
+
router: true,
|
529
|
+
},
|
530
|
+
plugins: [routerPlugin()],
|
531
|
+
};
|
532
|
+
```
|
533
|
+
|
534
|
+
### Code Changes
|
535
|
+
|
536
|
+
In React Router v7, you no longer need to use the `defer` API; you can directly return data in the data loader:
|
537
|
+
|
538
|
+
```ts title="routes/page.data.ts"
|
539
|
+
import { defer } from '@modern-js/runtime/router';
|
540
|
+
|
541
|
+
export const loader = async ({ params }) => {
|
542
|
+
// Recommended v7 style
|
543
|
+
const user = fetchUser(params.id)
|
544
|
+
return { user };
|
545
|
+
|
546
|
+
// v6 style, still compatible with Modern.js
|
547
|
+
return defer({ data: 'hello' });
|
548
|
+
};
|
549
|
+
```
|
550
|
+
|
551
|
+
React Router v7 has also deprecated the `json` API:
|
552
|
+
|
553
|
+
```ts title="routes/page.data.ts"
|
554
|
+
export const loader = async ({ params }) => {
|
555
|
+
// Recommended v7 style
|
556
|
+
return { data: 'hello' };
|
557
|
+
|
558
|
+
// v6 style, still compatible with Modern.js
|
559
|
+
return json({ data: 'hello' });
|
560
|
+
};
|
561
|
+
```
|
562
|
+
|
493
563
|
## FAQ
|
494
564
|
|
495
565
|
1. Why there is `@modern-js/runtime/router` to re-export React Router API
|
@@ -535,3 +605,5 @@ export const init = () => {
|
|
535
605
|
// initialization logic
|
536
606
|
};
|
537
607
|
```
|
608
|
+
|
609
|
+
|
@@ -12,7 +12,7 @@ WebAssembly (Wasm) is a portable, high-performance binary format designed to exe
|
|
12
12
|
|
13
13
|
## Import
|
14
14
|
|
15
|
-
You can import a WebAssembly module
|
15
|
+
You can import a WebAssembly module via named import in a JavaScript file:
|
16
16
|
|
17
17
|
```js title="index.js"
|
18
18
|
import { add } from './add.wasm';
|
@@ -1,8 +1,17 @@
|
|
1
1
|
# Deployment
|
2
2
|
|
3
|
-
|
3
|
+
In general, when deploying a Module Federation application, there are two key points to consider:
|
4
4
|
|
5
|
-
|
5
|
+
1. Ensure that the remote module addresses in the consumer's configuration file are correct, and that the consumer can correctly access the producer's `manifest` file.
|
6
|
+
2. Ensure that all resources in the producer's `manifest` file can be accessed correctly.
|
7
|
+
|
8
|
+
We recommend using Modern.js's [Node Server](/guides/basic-features/deploy.html#using-modernjs-built-in-nodejs-server) to deploy Module Federation applications for an out-of-the-box experience.
|
9
|
+
|
10
|
+
## Consumer
|
11
|
+
|
12
|
+
For the consumer of Module Federation, its connection with the producer is the remote module address in the configuration file.
|
13
|
+
|
14
|
+
For example, if the producer is deployed under the domain `https://my-remote-module`, the developer needs to modify the consumer's configuration file:
|
6
15
|
|
7
16
|
```ts title="module-federation.config.ts"
|
8
17
|
import { createModuleFederationConfig } from '@module-federation/modern-js';
|
@@ -10,7 +19,7 @@ import { createModuleFederationConfig } from '@module-federation/modern-js';
|
|
10
19
|
export default createModuleFederationConfig({
|
11
20
|
name: 'host',
|
12
21
|
remotes: {
|
13
|
-
remote: 'remote@
|
22
|
+
remote: 'remote@https://my-remote-module/static/mf-manifest.json',
|
14
23
|
},
|
15
24
|
shared: {
|
16
25
|
react: { singleton: true },
|
@@ -19,10 +28,77 @@ export default createModuleFederationConfig({
|
|
19
28
|
});
|
20
29
|
```
|
21
30
|
|
22
|
-
At this point, the consumer will load the `manifest` configuration file of the
|
31
|
+
At this point, the consumer will load the `manifest` configuration file of the remote module production environment.
|
32
|
+
|
33
|
+
:::note
|
34
|
+
In the above code, the address of the remote module is `/static/mf-manifest.json`, which is just an example using the default output path of Modern.js. In actual projects, developers need to configure according to the actual access path.
|
35
|
+
:::
|
36
|
+
|
37
|
+
## Producer
|
38
|
+
|
39
|
+
For the producer of Module Federation, developers need to correctly configure the [`output.assetPrefix`](/configure/app/output/asset-prefix) configuration, which affects:
|
40
|
+
|
41
|
+
1. The `publicPath` defined in `mf-manifest.json`, which determines the access path of other resources of the remote module.
|
42
|
+
2. The access path of the `mf-manifest.json` file when hosted directly by the Modern.js server.
|
43
|
+
|
44
|
+
In the production environment, developers need to configure `output.assetPrefix` as the access path of the production environment. For example, if we deploy the producer under the domain `https://my-remote-module`, we need to configure `output.assetPrefix` as `https://my-remote-module`.
|
45
|
+
|
46
|
+
```ts title="modern.config.ts"
|
47
|
+
import { defineConfig } from '@modern-js/app-tools';
|
48
|
+
|
49
|
+
export default defineConfig({
|
50
|
+
output: {
|
51
|
+
assetPrefix: 'https://my-remote-module',
|
52
|
+
},
|
53
|
+
});
|
54
|
+
```
|
55
|
+
|
56
|
+
At this point, the `publicPath` defined in the producer's build output `mf-manifest.json` is `https://my-remote-module`, for example:
|
57
|
+
|
58
|
+
```json
|
59
|
+
{
|
60
|
+
"id": "remote",
|
61
|
+
"name": "remote",
|
62
|
+
"metaData": {
|
63
|
+
"name": "remote",
|
64
|
+
"publicPath": "https://my-remote-module/"
|
65
|
+
},
|
66
|
+
"shared": [ /* xxx */ ],
|
67
|
+
"remotes": [],
|
68
|
+
"exposes": [ /* xxx */ ]
|
69
|
+
}
|
70
|
+
```
|
71
|
+
|
72
|
+
When the consumer accesses the remote module, it will automatically prepend the `publicPath` to the resource path of the remote module.
|
73
|
+
|
74
|
+
This configuration will also affect the access path of the producer's `mf-manifest.json`. For example, if this value is set to `MyDomain/module-a`, the hosting path of `mf-manifest.json` becomes `MyDomain/module-a/static/mf-manifest.json`.
|
75
|
+
|
76
|
+
At this point, the consumer needs to configure the following address when configuring the remote module:
|
77
|
+
|
78
|
+
```ts title="module-federation.config.ts"
|
79
|
+
import { createModuleFederationConfig } from '@module-federation/modern-js';
|
80
|
+
|
81
|
+
export default createModuleFederationConfig({
|
82
|
+
name: 'host',
|
83
|
+
remotes: {
|
84
|
+
remote: 'remote@MyDomain/module-a/static/mf-manifest.json',
|
85
|
+
},
|
86
|
+
});
|
87
|
+
```
|
88
|
+
|
89
|
+
## Local Deployment Verification
|
23
90
|
|
24
|
-
|
91
|
+
Modern.js provides the `modern deploy` command, which can easily generate products that can run in a Node.js environment.
|
25
92
|
|
26
|
-
|
93
|
+
```bash
|
94
|
+
modern deploy
|
95
|
+
```
|
96
|
+
|
97
|
+
After executing the command, you can see the following output in the console:
|
98
|
+
|
99
|
+
```bash
|
100
|
+
Static directory: .output/static
|
101
|
+
You can preview this build by node .output/index
|
102
|
+
```
|
27
103
|
|
28
|
-
|
104
|
+
At this point, the developer only needs to run `node .output/index` to preview the effect locally. Whether it is a CSR or an SSR application, all Module Federation files can be accessed correctly.
|
@@ -190,8 +190,6 @@ If we want to simulate the production environment in local, but not configure `o
|
|
190
190
|
import { appTools, defineConfig } from '@modern-js/app-tools';
|
191
191
|
import { moduleFederationPlugin } from '@module-federation/modern-js';
|
192
192
|
|
193
|
-
const isLocal = process.env.IS_LOCAL === 'true';
|
194
|
-
|
195
193
|
// https://modernjs.dev/en/configure/app/usage
|
196
194
|
export default defineConfig({
|
197
195
|
server: {
|
@@ -204,7 +202,7 @@ export default defineConfig({
|
|
204
202
|
// Now this configuration is only used in the local when you run modern serve command.
|
205
203
|
// If you want to deploy the application to the platform, use your own domain name.
|
206
204
|
// Module federation will automatically write it to mf-manifest.json, which influences consumer to fetch remoteEntry.js.
|
207
|
-
assetPrefix:
|
205
|
+
assetPrefix: 'http://127.0.0.1:3051',
|
208
206
|
},
|
209
207
|
plugins: [
|
210
208
|
appTools({
|
@@ -215,7 +213,7 @@ export default defineConfig({
|
|
215
213
|
});
|
216
214
|
```
|
217
215
|
|
218
|
-
Now, in the producer, run `
|
216
|
+
Now, in the producer, run `modern build && modern serve`, and in the consumer, run `modern build && modern serve` to simulate the production environment locally and access the remote modules.
|
219
217
|
|
220
218
|
You can refer to this example: [Modern.js & Module Federation Basic Example](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/module-federation/base).
|
221
219
|
|
@@ -4,9 +4,12 @@ title: transformLodash
|
|
4
4
|
|
5
5
|
# performance.transformLodash
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" ><div>仅支持 Webpack</div></Badge>
|
10
|
+
|
7
11
|
- **类型:** `boolean`
|
8
12
|
- **默认值:** `true`
|
9
|
-
- **打包工具:** `仅支持 webpack`
|
10
13
|
|
11
14
|
是否模块化 [lodash](https://www.npmjs.com/package/lodash) 的导入,删除未使用的 lodash 模块,从而减少 lodash 代码体积。
|
12
15
|
|
@@ -4,9 +4,12 @@ title: moduleScopes
|
|
4
4
|
|
5
5
|
# source.moduleScopes
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >仅支持 Webpack</Badge>
|
10
|
+
|
7
11
|
- **类型:** `Array<string | Regexp> | Function`
|
8
12
|
- **默认值:** `undefined`
|
9
|
-
- **打包工具:** `仅支持 webpack`
|
10
13
|
|
11
14
|
限制源代码的引用路径。配置该选项后,所有源文件只能从约定的目录下引用代码,从其他目录引用代码会产生对应的报错提示。
|
12
15
|
|
@@ -4,6 +4,10 @@ title: terser
|
|
4
4
|
|
5
5
|
# tools.terser
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >仅支持 Webpack</Badge>
|
10
|
+
|
7
11
|
- **类型:** `Object | Function | undefined`
|
8
12
|
- **默认值:**
|
9
13
|
|
@@ -17,8 +21,6 @@ const defaultTerserOptions = {
|
|
17
21
|
};
|
18
22
|
```
|
19
23
|
|
20
|
-
- **打包工具:** `仅支持 webpack`
|
21
|
-
|
22
24
|
在生产环境构建时,Modern.js 会通过 [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) 对 JavaScript 代码进行压缩优化。可以通过 `tools.terser` 修改 [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) 的配置。
|
23
25
|
|
24
26
|
### Object 类型
|
@@ -4,9 +4,12 @@ title: webpackChain
|
|
4
4
|
|
5
5
|
# tools.webpackChain
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >仅支持 Webpack</Badge>
|
10
|
+
|
7
11
|
- **类型:** `Function | undefined`
|
8
12
|
- **默认值:** `undefined`
|
9
|
-
- **打包工具:** `仅支持 webpack`
|
10
13
|
|
11
14
|
你可以通过 `tools.webpackChain` 来修改默认的 webpack 配置,它的值为 `Function` 类型,接收两个参数:
|
12
15
|
|
@@ -4,9 +4,12 @@ title: webpack
|
|
4
4
|
|
5
5
|
# tools.webpack
|
6
6
|
|
7
|
+
import { Badge } from '@theme';
|
8
|
+
|
9
|
+
<Badge type="danger" >仅支持 Webpack</Badge>
|
10
|
+
|
7
11
|
- **类型:** `Object | Function | undefined`
|
8
12
|
- **默认值:** `undefined`
|
9
|
-
- **打包工具:** `仅支持 webpack`
|
10
13
|
|
11
14
|
`tools.webpack` 选项用于配置原生的 [webpack](https://webpack.js.org/)。
|
12
15
|
|
@@ -12,10 +12,15 @@ Modern.js 将大部分项目需要的服务端能力都进行了封装,通常
|
|
12
12
|
必须确保 Modern.js 版本是 x.67.5 及以上。
|
13
13
|
:::
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
开发者可以在项目根目录执行 `pnpm run new` 命令,开启「自定义 Web Server」功能:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
? 请选择你想要的操作 创建工程元素
|
19
|
+
? 请选择创建元素类型 新建「自定义 Web Server」源码目录
|
20
|
+
```
|
21
|
+
|
22
|
+
执行命令后,项目目录下会自动创建 `server/modern.server.ts` 文件,可以在这个文件中编写自定义逻辑。
|
23
|
+
|
19
24
|
|
20
25
|
## 自定义 Web Server 能力
|
21
26
|
|
@@ -227,6 +232,14 @@ export default () => {
|
|
227
232
|
旧版 API 兼容但不再推荐使用,扩展 Server 能力请移步 [自定义 Web Server](/guides/advanced-features/web-server.html),迁移指南参考 [迁移至新版自定义 Web Server](/guides/advanced-features/web-server.html#迁移至新版自定义-web-server)。
|
228
233
|
:::
|
229
234
|
|
235
|
+
### 开启
|
236
|
+
开启自定义 Web Server 功能,需要执行以下步骤:
|
237
|
+
1. devDependencies 增加 `@modern-js/plugin-server`、`tsconfig-paths` 及 `ts-node`依赖并安装。
|
238
|
+
2. `tsconfig` 的 `include` 中添加 `server`。
|
239
|
+
3. `modern.config.ts` 中注册 `@modern-js/plugin-server` 插件。
|
240
|
+
4. 项目目录下创建 `server/index.ts` 文件,可以在这个文件中编写自定义逻辑。
|
241
|
+
|
242
|
+
|
230
243
|
### Unstable Middleware
|
231
244
|
|
232
245
|
Modern.js 支持为 Web Server 添加渲染中间件,支持在处理页面路由的前后执行自定义逻辑。
|
@@ -159,7 +159,7 @@ const getComplexStatistics = cache(
|
|
159
159
|
}
|
160
160
|
);
|
161
161
|
|
162
|
-
revalidateTag('dashboard
|
162
|
+
revalidateTag('dashboard'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
|
163
163
|
```
|
164
164
|
|
165
165
|
#### `getKey` 参数
|
@@ -222,7 +222,7 @@ document.addEventListener('load', () => {
|
|
222
222
|
export const doSomething = () => {}
|
223
223
|
```
|
224
224
|
|
225
|
-
如果直接引用到组件中,会造成
|
225
|
+
如果直接引用到组件中,会造成 SSR 加载报错,即使你已经使用环境变量进行判断,但仍然无法移除依赖中副作用的执行。
|
226
226
|
|
227
227
|
```tsx title="routes/page.tsx"
|
228
228
|
import { doSomething } from 'packageA';
|
@@ -72,7 +72,7 @@ export const loader = ({ params }: LoaderFunctionArgs) => {
|
|
72
72
|
另外,`defer` 还可以同时接收异步数据和同步数据。在下述例子中,我们等待部分耗时较短的请求,在响应后通过对象数据返回,而耗时较长时间的请求,则通过 Promise 返回:
|
73
73
|
|
74
74
|
```ts title="user/[id]/page.data.ts"
|
75
|
-
export const loader = ({ params }: LoaderFunctionArgs) => {
|
75
|
+
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
76
76
|
const userId = params.id;
|
77
77
|
|
78
78
|
const user = new Promise<User>(resolve => {
|
@@ -1,8 +1,17 @@
|
|
1
1
|
# 部署
|
2
2
|
|
3
|
-
通常情况下,部署 Module Federation
|
3
|
+
通常情况下,部署 Module Federation 应用,需要注意两点:
|
4
4
|
|
5
|
-
|
5
|
+
1. 保证消费者配置文件中的远程模块地址无误,消费者能够正确访问到生产者的 `manifest` 文件。
|
6
|
+
2. 保证生产者 `manifest` 文件中各个资源能被正确访问到。
|
7
|
+
|
8
|
+
我们推荐使用 Modern.js 的 [Node 服务](/guides/basic-features/deploy.html#modernjs-内置-nodejs-服务器)来部署 Module Federation 应用,以获得开箱即用的体验。
|
9
|
+
|
10
|
+
## 消费者
|
11
|
+
|
12
|
+
对于 Module Federation 的消费者来说,它与生产者的联系就是在配置文件中的远程模块地址。
|
13
|
+
|
14
|
+
例如生产者部署在 `https://my-remote-module` 这个域名下,开发者需要修改消费者的配置文件:
|
6
15
|
|
7
16
|
```ts title="module-federation.config.ts"
|
8
17
|
import { createModuleFederationConfig } from '@module-federation/modern-js';
|
@@ -10,7 +19,7 @@ import { createModuleFederationConfig } from '@module-federation/modern-js';
|
|
10
19
|
export default createModuleFederationConfig({
|
11
20
|
name: 'host',
|
12
21
|
remotes: {
|
13
|
-
remote: 'remote@
|
22
|
+
remote: 'remote@https://my-remote-module/static/mf-manifest.json',
|
14
23
|
},
|
15
24
|
shared: {
|
16
25
|
react: { singleton: true },
|
@@ -19,10 +28,77 @@ export default createModuleFederationConfig({
|
|
19
28
|
});
|
20
29
|
```
|
21
30
|
|
22
|
-
|
31
|
+
此时,消费者将加载远程模块生产环境的 `manifest` 配置文件。
|
32
|
+
|
33
|
+
:::note
|
34
|
+
上述代码中,远程模块的地址是 `/static/mf-manifest.json`,这只是以 Modern.js 默认的产物路径举例。在实际项目中,开发者需要根据实际的访问路径进行配置。
|
35
|
+
:::
|
36
|
+
|
37
|
+
## 生产者
|
38
|
+
|
39
|
+
对于 Module Federation 的生产者,开发者需要正确的配置 [`output.assetPrefix`](/configure/app/output/asset-prefix) 配置,它会影响到:
|
40
|
+
|
41
|
+
1. `mf-manifest.json` 中定义的 `publicPath`,它决定了远程模块其他资源的访问路径。
|
42
|
+
2. 通过 Modern.js 服务直接托管产物时,`mf-manifest.json` 文件的访问路径。
|
43
|
+
|
44
|
+
在生产环境,开发者需要将 `output.assetPrefix` 配置为生产环境的访问路径。例如我们将生产者部署在 `https://my-remote-module` 这个域名下,需要将 `output.assetPrefix` 配置为 `https://my-remote-module`。
|
45
|
+
|
46
|
+
```ts title="modern.config.ts"
|
47
|
+
import { defineConfig } from '@modern-js/app-tools';
|
48
|
+
|
49
|
+
export default defineConfig({
|
50
|
+
output: {
|
51
|
+
assetPrefix: 'https://my-remote-module',
|
52
|
+
},
|
53
|
+
});
|
54
|
+
```
|
55
|
+
|
56
|
+
此时,生产者构建产物 `mf-manifest.json` 中定义的 `publicPath` 为 `https://my-remote-module`,例如:
|
57
|
+
|
58
|
+
```json
|
59
|
+
{
|
60
|
+
"id": "remote",
|
61
|
+
"name": "remote",
|
62
|
+
"metaData": {
|
63
|
+
"name": "remote",
|
64
|
+
"publicPath": "https://my-remote-module/"
|
65
|
+
},
|
66
|
+
"shared": [ /* xxx */ ],
|
67
|
+
"remotes": [],
|
68
|
+
"exposes": [ /* xxx */ ]
|
69
|
+
}
|
70
|
+
```
|
71
|
+
|
72
|
+
消费者在访问远程模块时,会自动将 `publicPath` 拼接在远程模块的资源路径前。
|
73
|
+
|
74
|
+
该配置也会影响到生产者 `mf-manifest.json` 的访问路径。例如将这个值设置为 `MyDomain/module-a` 时,`mf-manifest.json` 的托管路径变为 `MyDomain/module-a/static/mf-manifest.json`。
|
75
|
+
|
76
|
+
此时,消费者在配置远程模块时,需要配置以下地址:
|
77
|
+
|
78
|
+
```ts title="module-federation.config.ts"
|
79
|
+
import { createModuleFederationConfig } from '@module-federation/modern-js';
|
80
|
+
|
81
|
+
export default createModuleFederationConfig({
|
82
|
+
name: 'host',
|
83
|
+
remotes: {
|
84
|
+
remote: 'remote@MyDomain/module-a/static/mf-manifest.json',
|
85
|
+
},
|
86
|
+
});
|
87
|
+
```
|
88
|
+
|
89
|
+
## 本地验证部署
|
23
90
|
|
24
|
-
|
91
|
+
Modern.js 提供了 `modern deploy` 命令,可以方便生成可运行在 Node.js 环境的产物。
|
25
92
|
|
26
|
-
|
93
|
+
```bash
|
94
|
+
modern deploy
|
95
|
+
```
|
96
|
+
|
97
|
+
执行命令后,可以在控制台看到以下输出:
|
98
|
+
|
99
|
+
```bash
|
100
|
+
Static directory: .output/static
|
101
|
+
You can preview this build by node .output/index
|
102
|
+
```
|
27
103
|
|
28
|
-
|
104
|
+
此时,开发者只需要运行 `node .output/index` 即可在本地预览部署后的效果。无论是 CSR 应用或是 SSR 应用,所有的 Module Federation 产物都能够被正确的访问。
|
@@ -189,8 +189,6 @@ export default Index;
|
|
189
189
|
import { appTools, defineConfig } from '@modern-js/app-tools';
|
190
190
|
import { moduleFederationPlugin } from '@module-federation/modern-js';
|
191
191
|
|
192
|
-
const isLocal = process.env.IS_LOCAL === 'true';
|
193
|
-
|
194
192
|
// https://modernjs.dev/en/configure/app/usage
|
195
193
|
export default defineConfig({
|
196
194
|
server: {
|
@@ -203,7 +201,7 @@ export default defineConfig({
|
|
203
201
|
// Now this configuration is only used in the local when you run modern serve command.
|
204
202
|
// If you want to deploy the application to the platform, use your own domain name.
|
205
203
|
// Module federation will automatically write it to mf-manifest.json, which influences consumer to fetch remoteEntry.js.
|
206
|
-
assetPrefix:
|
204
|
+
assetPrefix: 'http://127.0.0.1:3051',
|
207
205
|
},
|
208
206
|
plugins: [
|
209
207
|
appTools({
|
@@ -214,7 +212,7 @@ export default defineConfig({
|
|
214
212
|
});
|
215
213
|
```
|
216
214
|
|
217
|
-
现在,在生产者中运行 `
|
215
|
+
现在,在生产者中运行 `modern build && modern serve`,在消费者中运行 `modern build && modern serve`,即可在本地模拟生产环境,访问到远程模块。
|
218
216
|
|
219
217
|
上述用例可以参考:[Modern.js & Module Federation 基础用法示例](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/module-federation/base)。
|
220
218
|
|
package/package.json
CHANGED
@@ -15,14 +15,14 @@
|
|
15
15
|
"modern",
|
16
16
|
"modern.js"
|
17
17
|
],
|
18
|
-
"version": "2.67.
|
18
|
+
"version": "2.67.7",
|
19
19
|
"publishConfig": {
|
20
20
|
"registry": "https://registry.npmjs.org/",
|
21
21
|
"access": "public"
|
22
22
|
},
|
23
23
|
"dependencies": {
|
24
24
|
"mermaid": "^11.4.1",
|
25
|
-
"@modern-js/sandpack-react": "2.67.
|
25
|
+
"@modern-js/sandpack-react": "2.67.7"
|
26
26
|
},
|
27
27
|
"devDependencies": {
|
28
28
|
"@rsbuild/plugin-sass": "1.3.1",
|