@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.
Files changed (31) hide show
  1. package/docs/en/apis/app/hooks/src/routes.mdx +0 -70
  2. package/docs/en/configure/app/performance/transform-lodash.mdx +4 -1
  3. package/docs/en/configure/app/source/module-scopes.mdx +4 -1
  4. package/docs/en/configure/app/tools/terser.mdx +4 -2
  5. package/docs/en/configure/app/tools/ts-loader.mdx +4 -1
  6. package/docs/en/configure/app/tools/webpack-chain.mdx +4 -1
  7. package/docs/en/configure/app/tools/webpack.mdx +4 -1
  8. package/docs/en/guides/advanced-features/web-server.mdx +16 -4
  9. package/docs/en/guides/basic-features/data/data-cache.mdx +1 -1
  10. package/docs/en/guides/basic-features/render/ssr.mdx +1 -1
  11. package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -2
  12. package/docs/en/guides/basic-features/routes.mdx +72 -0
  13. package/docs/en/guides/basic-features/static-assets/wasm-assets.mdx +1 -1
  14. package/docs/en/guides/topic-detail/module-federation/deploy.mdx +83 -7
  15. package/docs/en/guides/topic-detail/module-federation/usage.mdx +2 -4
  16. package/docs/en/plugin/cli-plugins/api.mdx +1 -1
  17. package/docs/zh/configure/app/performance/transform-lodash.mdx +4 -1
  18. package/docs/zh/configure/app/source/module-scopes.mdx +4 -1
  19. package/docs/zh/configure/app/tools/terser.mdx +4 -2
  20. package/docs/zh/configure/app/tools/ts-loader.mdx +4 -1
  21. package/docs/zh/configure/app/tools/webpack-chain.mdx +4 -1
  22. package/docs/zh/configure/app/tools/webpack.mdx +4 -1
  23. package/docs/zh/guides/advanced-features/web-server.mdx +17 -4
  24. package/docs/zh/guides/basic-features/data/data-cache.mdx +1 -1
  25. package/docs/zh/guides/basic-features/render/ssr.mdx +1 -1
  26. package/docs/zh/guides/basic-features/render/streaming-ssr.mdx +1 -1
  27. package/docs/zh/guides/basic-features/static-assets/wasm-assets.mdx +1 -1
  28. package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +83 -7
  29. package/docs/zh/guides/topic-detail/module-federation/usage.mdx +2 -4
  30. package/docs/zh/plugin/cli-plugins/api.mdx +1 -1
  31. 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
- To start a custom web server, the following steps need to be taken:
16
- 1. Add and install the dependencies `@modern-js/server-runtime` and `ts-node` to `devDependencies`.
17
- 2. Add `server` to the `include` section of `tsconfig`.
18
- 3. Create a file `server/modern.server.ts` in the project directory, where you can write custom logic.
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-stats'); // Invalidates the cache for both getDashboardStats and getComplexStatistics functions
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 CSR to throw errors, even if you use environment variables to conditionally load the code. The side effects in the dependency will still execute.
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 directly in a JavaScript file:
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
- Typically, deploying a Module Federation application requires adjusting the remote module address on the consumer side to its online address.
3
+ In general, when deploying a Module Federation application, there are two key points to consider:
4
4
 
5
- For example, if the producer is deployed to the domain `https://my-remote-module`, you can modify the consumer's `module-federation.config.ts` file as follows:
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@http://my-remote-module/mf-manifest.json',
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 `remote` module in the production environment.
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
- ## Deployment via Platform
91
+ Modern.js provides the `modern deploy` command, which can easily generate products that can run in a Node.js environment.
25
92
 
26
- The above deployment method is merely the simplest practice. In real-world scenarios, there are many constraints, such as version management, release sequencing, and more. Within ByteDance, we have set up a deployment process for Module Federation applications on our deployment platform, which helps developers address these issues.
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
- We will continue to keep an eye on platforms with similar functionalities in the community and, in the future, enhance the documentation for deploying Modern.js + Module Federation on these types of platforms.
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: isLocal ? 'http://127.0.0.1:3051' : '/',
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 `IS_LOCAL=true modern build && modern serve`, and in the consumer, run `modern build && modern serve` to simulate the production environment locally and access the remote modules.
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
 
@@ -324,7 +324,7 @@ Modify the server routing configuration.
324
324
  ```typescript
325
325
  api.modifyServerRoutes(routes => {
326
326
  // Add a new API route
327
- routes.concat({
327
+ routes.push({
328
328
  urlPath: '/api',
329
329
  isApi: true,
330
330
  entryPath: '',
@@ -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: tsLoader
4
4
 
5
5
  # tools.tsLoader
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
  :::warning 废弃提示
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</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
- 开启自定义 Web Server 功能,需要执行以下步骤:
16
- 1. devDependencies 增加 `@modern-js/server-runtime` 及 `ts-node`依赖并安装。
17
- 2. `tsconfig` 的 `include` 中添加 `server`。
18
- 3. 项目目录下创建 `server/modern.server.ts` 文件,可以在这个文件中编写自定义逻辑。
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-stats'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
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
- 如果直接引用到组件中,会造成 CSR 加载报错,即使你已经使用环境变量进行判断,但仍然无法移除依赖中副作用的执行。
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 => {
@@ -12,7 +12,7 @@ WebAssembly(缩写为 wasm)是一种可移植、高性能的字节码格式
12
12
 
13
13
  ## 引用方式
14
14
 
15
- 你可以直接在 JavaScript 文件中引用一个 WebAssembly 模块:
15
+ 你可以在 JavaScript 文件中使用 named import 引用一个 WebAssembly 模块:
16
16
 
17
17
  ```js title="index.js"
18
18
  import { add } from './add.wasm';
@@ -1,8 +1,17 @@
1
1
  # 部署
2
2
 
3
- 通常情况下,部署 Module Federation 应用,需要在消费者上将远程模块地址,调整为其线上地址。
3
+ 通常情况下,部署 Module Federation 应用,需要注意两点:
4
4
 
5
- 例如已经将生产者部署到 `https://my-remote-module` 这个域名下,可以这样修改消费者的 `module-federation.config.ts` 文件:
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@http://my-remote-module/mf-manifest.json',
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
- 此时,消费者将加载生产环境的 `remote` 模块的 `manifest` 配置文件。
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
- 上述部署方式只是最简单的实践,在真实场景还有很多限制,例如版本管理、发布时序等。在字节跳动内部,我们在部署平台上搭建了 Module Federation 应用的部署流程,可以帮助开发者解决这些问题。
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
- 我们会持续关注社区里类似功能的平台,在未来完善 Modern.js + Module Federation 在这些类平台上的部署文档。
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: isLocal ? 'http://127.0.0.1:3051' : '/',
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
- 现在,在生产者中运行 `IS_LOCAL=true modern build && modern serve`,在消费者中运行 `modern build && modern serve`,即可在本地模拟生产环境,访问到远程模块。
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
 
@@ -324,7 +324,7 @@ api.modifyWebpackConfig((config, utils) => {
324
324
  ```typescript
325
325
  api.modifyServerRoutes(routes => {
326
326
  // 添加一个新的 API 路由
327
- routes.concat({
327
+ routes.push({
328
328
  urlPath: '/api',
329
329
  isApi: true,
330
330
  entryPath: '',
package/package.json CHANGED
@@ -15,14 +15,14 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.67.6",
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.6"
25
+ "@modern-js/sandpack-react": "2.67.7"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@rsbuild/plugin-sass": "1.3.1",