@modern-js/main-doc 2.60.1 → 2.60.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. package/docs/en/apis/app/commands.mdx +6 -21
  2. package/docs/en/components/deploy-command.mdx +14 -0
  3. package/docs/en/components/serve-command.mdx +22 -0
  4. package/docs/en/configure/app/dev/watch-files.mdx +13 -6
  5. package/docs/en/configure/app/output/copy.mdx +4 -1
  6. package/docs/en/configure/app/output/inline-scripts.mdx +1 -1
  7. package/docs/en/configure/app/output/inline-styles.mdx +1 -1
  8. package/docs/en/configure/app/runtime/router.mdx +11 -3
  9. package/docs/en/configure/app/runtime/state.mdx +0 -2
  10. package/docs/en/guides/concept/_meta.json +1 -1
  11. package/docs/en/guides/concept/server.mdx +35 -0
  12. package/docs/en/guides/topic-detail/_meta.json +6 -0
  13. package/docs/en/guides/topic-detail/module-federation/_meta.json +1 -0
  14. package/docs/en/guides/topic-detail/module-federation/application.mdx +112 -0
  15. package/docs/en/guides/topic-detail/module-federation/deploy.mdx +28 -0
  16. package/docs/en/guides/topic-detail/module-federation/introduce.mdx +35 -0
  17. package/docs/en/guides/topic-detail/module-federation/ssr.mdx +31 -0
  18. package/docs/en/guides/topic-detail/module-federation/usage.mdx +180 -0
  19. package/docs/zh/apis/app/commands.mdx +6 -21
  20. package/docs/zh/components/deploy-command.mdx +14 -0
  21. package/docs/zh/components/serve-command.mdx +22 -0
  22. package/docs/zh/configure/app/dev/watch-files.mdx +13 -6
  23. package/docs/zh/configure/app/output/copy.mdx +4 -2
  24. package/docs/zh/configure/app/output/inline-scripts.mdx +1 -1
  25. package/docs/zh/configure/app/output/inline-styles.mdx +1 -1
  26. package/docs/zh/configure/app/runtime/router.mdx +10 -4
  27. package/docs/zh/configure/app/runtime/state.mdx +0 -2
  28. package/docs/zh/guides/concept/_meta.json +1 -1
  29. package/docs/zh/guides/concept/server.mdx +35 -0
  30. package/docs/zh/guides/topic-detail/_meta.json +6 -0
  31. package/docs/zh/guides/topic-detail/module-federation/_meta.json +1 -0
  32. package/docs/zh/guides/topic-detail/module-federation/application.mdx +112 -0
  33. package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +28 -0
  34. package/docs/zh/guides/topic-detail/module-federation/introduce.mdx +35 -0
  35. package/docs/zh/guides/topic-detail/module-federation/ssr.mdx +31 -0
  36. package/docs/zh/guides/topic-detail/module-federation/usage.mdx +181 -0
  37. package/docs/zh/plugin/introduction.mdx +4 -4
  38. package/i18n.json +4 -0
  39. package/package.json +4 -4
@@ -0,0 +1,14 @@
1
+ ## modern deploy
2
+
3
+ `modern deploy` 命令,用于生成部署平台需要的产物。
4
+
5
+ ```bash
6
+ Usage: modern deploy [options]
7
+
8
+ Options:
9
+ -c --config <config> 指定配置文件路径,可以为相对路径或绝对路径
10
+ -s --skip-build 跳过构建阶段
11
+ -h, --help 显示命令帮助
12
+ ```
13
+
14
+ 详细内容可以参考 [部署应用](/guides/basic-features/deploy)。
@@ -0,0 +1,22 @@
1
+ ## modern serve
2
+
3
+ `modern serve` 命令用于在生产环境下启动 Modern.js 工程, 也可以用于在本地预览生产环境构建的产物。注意你需要提前执行 [`build`](/apis/app/commands#modern-build) 命令构建出对应产物。
4
+
5
+ ```bash
6
+ Usage: modern serve [options]
7
+
8
+ Options:
9
+ -c --config <config> 指定配置文件路径,可以为相对路径或绝对路径
10
+ -h, --help 显示命令帮助
11
+ --api-only 仅启动 API 接口服务
12
+ ```
13
+
14
+ 默认情况下,应用将会在 `localhost:8080` 启动,可以通过 `server.port` 修改 Server 端口号:
15
+
16
+ ```js
17
+ export default defineConfig({
18
+ server: {
19
+ port: 8081,
20
+ },
21
+ });
22
+ ```
@@ -8,12 +8,19 @@ configName: dev.watchFiles
8
8
  - **类型:**
9
9
 
10
10
  ```ts
11
- type WatchFiles = {
12
- paths: string | string[];
13
- type?: 'reload-page' | 'reload-server';
14
- // chokidar 选项
15
- options?: WatchOptions;
16
- };
11
+ type WatchFiles =
12
+ | {
13
+ paths: string | string[];
14
+ type?: 'reload-page';
15
+ // chokidar 选项
16
+ options?: WatchOptions;
17
+ }
18
+ | {
19
+ paths: string | string[];
20
+ type?: 'reload-server';
21
+ };
22
+
23
+ type WatchFilesConfig = WatchFiles | WatchFiles[];
17
24
  ```
18
25
 
19
26
  - **默认值:** `undefined`
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: copy
3
+ configName: output.copy
3
4
  ---
4
5
 
5
6
  # output.copy
@@ -7,7 +8,8 @@ title: copy
7
8
  - **类型:** `Rspack.CopyRspackPluginOptions | Rspack.CopyRspackPluginOptions['patterns']`
8
9
  - **默认值:** `undefined`
9
10
 
10
-
11
11
  将指定的文件或目录拷贝到构建输出目录中,基于 [rspack.CopyRspackPlugin](https://rspack.dev/zh/plugins/rspack/copy-rspack-plugin) 实现。
12
12
 
13
- 更详细的配置项请参考:[rspack.CopyRspackPlugin](https://rspack.dev/zh/plugins/rspack/copy-rspack-plugin)文档。
13
+ import RsbuildConig from '@site-docs/components/rsbuild-config-tooltip';
14
+
15
+ <RsbuildConig />
@@ -26,7 +26,7 @@ type InlineScripts =
26
26
  用来控制是否用 `<script>` 标签将产物中的 script 文件(.js 文件)inline 到 HTML 中。
27
27
 
28
28
  :::tip
29
- 当使用约定式路由时,如果开启了这个选项,需要将 [output.splitRouteChunks](https://modernjs.dev/configure/app/output/splitRouteChunks.html) 设置为 false。
29
+ 当使用约定式路由时,如果开启了这个选项,需要将 [output.splitRouteChunks](/configure/app/output/split-route-chunks) 设置为 false。
30
30
  :::
31
31
 
32
32
  import RsbuildConig from '@site-docs/components/rsbuild-config-tooltip';
@@ -26,7 +26,7 @@ type InlineStyles =
26
26
  用来控制是否用 `<style>` 标签将产物中的 style 文件(.css 文件)inline 到 HTML 中。
27
27
 
28
28
  :::tip
29
- 当使用约定式路由时,如果开启了这个选项,需要将 [output.splitRouteChunks](https://modernjs.dev/configure/app/output/splitRouteChunks.html) 设置为 false。
29
+ 当使用约定式路由时,如果开启了这个选项,需要将 [output.splitRouteChunks](/configure/app/output/split-route-chunks) 设置为 false。
30
30
  :::
31
31
 
32
32
  import RsbuildConig from '@site-docs/components/rsbuild-config-tooltip';
@@ -8,14 +8,16 @@ import RouterLegacyTip from "@site-docs/components/router-legacy-tip"
8
8
 
9
9
  <RouterLegacyTip />
10
10
 
11
- # runtime.router
12
-
13
11
  - **类型:** `boolean | Object`
14
12
  - **默认值:** `false`
15
13
 
16
- 开启 `router` 之后,支持使用 Modern.js 默认提供的约定式路由进行路由管理。Modern.js 的路由模块基于 [React Router 6](https://reactrouter.com/) 实现。
14
+ 该值在项目创建时被设置为 `true`,支持使用 Modern.js 默认提供的[约定式路由](/guides/concept/entries.html#约定式路由)进行路由管理。
15
+
16
+ 如果希望使用[自控式路由](/guides/concept/entries.html#自控式路由),请移除该值,或将该值设置为 `false`。
17
17
 
18
- 具体配置如下:
18
+ :::note
19
+ `router` 的所有子配置都只会在使用约定式路由时生效。
20
+ :::
19
21
 
20
22
  ## basename
21
23
 
@@ -24,6 +26,10 @@ import RouterLegacyTip from "@site-docs/components/router-legacy-tip"
24
26
 
25
27
  设置客户端路由的 `basename`,通常用于应用需要部署在域名非根路径下的场景。
26
28
 
29
+ :::tip
30
+ 推荐使用 [`server.baseUrl`](/configure/app/server/base-url) 进行配置。
31
+ :::
32
+
27
33
  ## supportHtml5History
28
34
 
29
35
  - **类型:** `boolean`
@@ -9,8 +9,6 @@ title: state
9
9
 
10
10
  开启 `state` 后就可以使用 [Model](/guides/topic-detail/model/quick-start) 来做状态管理。
11
11
 
12
- 具体配置项如下:
13
-
14
12
  ## models
15
13
 
16
14
  - **类型:** `Array<Model>`
@@ -1 +1 @@
1
- ["entries", "builder"]
1
+ ["entries", "builder", "server"]
@@ -0,0 +1,35 @@
1
+ # Web 服务器
2
+
3
+ Modern.js 为应用提供了内置的 Web 服务器,可以被运行在任何拥有 Node.js 的容器环境中。无论是在本地开发环境中执行 `dev` 命令,或是执行 `build && serve` 命令运行生成环境产物,或是官方的部署方案,都是通过这个 Web 服务器来托管应用。
4
+
5
+ ## 底层依赖
6
+
7
+ Modern.js 基于 [Hono 框架](https://hono.dev/) 搭建了自己的 Web 服务器。Hono 是一个小型、简单且超快速的基于 Web 标准的框架,它能在任何 JavaScript 运行时上运行。
8
+
9
+ ## 开发 & 生产
10
+
11
+ Modern.js 开发环境和生产环境的 Web 服务器流程是完全同构的,你无需担心开发环境和生产环境的差异。
12
+
13
+ 在 [构建工具](/guides/concept/builder) 一节我们提到,Modern.js 底层构建能力由 Rsbuild 提供,而部分开发环境的服务端能力是与构建工具耦合的,例如 HMR。Modern.js 需要复用 Rsbuild Dev Server 的能力。
14
+
15
+ 在开发环境,Modern.js 直接使用了 Rsbuild 提供的中间件,包含 HMR、Proxy 等开发阶段需要的能力。同时,Modern.js 在这之上提供了 Mock、路由、渲染等能力:
16
+
17
+ ![Server](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/web-server-modern.jpeg)
18
+
19
+ 因此,在 Modern.js 中开发环境只是在生产环境上增加了中间件。生产环境的所有能力,在开发环境中也同样适用,两者不会产生割裂。
20
+
21
+ :::tip
22
+ 静态资源文件能够直接被 Modern.js 的服务器托管,但在生产环境中,强烈推荐将这些内容上传到 CDN。
23
+ :::
24
+
25
+ ## 在 CI 环境中运行
26
+
27
+ Modern.js 支持在任何 Node.js 环境运行构建产物。在 CI 环境中,通常情况下已经安装了应用全部的依赖。
28
+
29
+ 你可以执行 [`modern build`](/apis/app/commands#modern-build) 来构建应用,执行 [`modern serve`](/apis/app/commands#modern-serve) 命令来运行 Web 服务器,启动 Modern.js 应用。
30
+
31
+ ## 在生产环境中运行
32
+
33
+ 在部署到生产环境时,产物体积应该尽可能小,而上述在 CI 中运行的方案,会保留原项目的所有产物。因此在生产环境,不推荐通过上述命令运行应用。
34
+
35
+ Modern.js 提供了独立的部署方案,当运行 [`modern deploy`](/apis/app/commands#modern-deploy) 命令时,产物中会包含可运行 Web 服务器的入口文件。
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "type": "dir",
4
+ "name": "module-federation",
5
+ "label": "module-federation",
6
+ "collapsed": true
7
+ },
2
8
  {
3
9
  "type": "dir",
4
10
  "name": "micro-frontend",
@@ -0,0 +1 @@
1
+ ["introduce", "usage", "application", "ssr", "deploy"]
@@ -0,0 +1,112 @@
1
+ # 应用级别模块
2
+
3
+ Modern.js 提供了运行时 API,支持快速从应用中导出应用级别的 Module Federation 模块。
4
+
5
+ 我们以 [使用模块联邦](/guides/topic-detail/module-federation/usage) 创建的应用为例,进一步说明如何导入应用级别模块。
6
+
7
+ ## 安装依赖
8
+
9
+ 在原本应用的基础上,我们需要安装 `@module-federation/bridge-react` 依赖,用于使用 Bridge 加载应用级别模块。
10
+
11
+ import { PackageManagerTabs } from '@theme';
12
+
13
+ <PackageManagerTabs command="add @module-federation/bridge-react" />
14
+
15
+ ## 生产者导出模块
16
+
17
+ 和直接导出组件级别的模块不同,我们需要为应用级别模块创建一个独立的入口来作为 `Module Federation` 的导出。
18
+
19
+ 我们创建 `src/export-App.tsx` 文件:
20
+
21
+ :::note
22
+ 这里可以是任意的文件名,Modern.js 没有做强制约定。
23
+ :::
24
+
25
+ ```ts title="src/export-App.tsx"
26
+ import '@modern-js/runtime/registry/main'; // 这一行必须引入,它会默认导入微前端运行时依赖
27
+ import { render } from '@modern-js/runtime/browser';
28
+ import { createRoot } from '@modern-js/runtime/react';
29
+ import { createBridgeComponent } from '@module-federation/bridge-react';
30
+
31
+ const ModernRoot = createRoot();
32
+ export const provider = createBridgeComponent({
33
+ rootComponent: ModernRoot,
34
+ render: (Component, dom) => render(Component, dom),
35
+ });
36
+
37
+ export default provider;
38
+ ```
39
+
40
+ 该文件会将 `main` 入口的应用根组件传递给 Bridge API,并通过 Bridge 将调用渲染函数将其渲染到指定的节点上。
41
+
42
+ 接下来,我们配置 `module-federation.config.ts`,将导出修改为 `src/export-App.tsx`:
43
+
44
+ ```ts title="module-federation.config.ts"
45
+ import { createModuleFederationConfig } from '@module-federation/modern-js';
46
+
47
+ export default createModuleFederationConfig({
48
+ name: 'remote',
49
+ filename: 'remoteEntry.js',
50
+ exposes: {
51
+ './app': './src/export-App.tsx',
52
+ },
53
+ shared: {
54
+ react: { singleton: true },
55
+ 'react-dom': { singleton: true },
56
+ },
57
+ });
58
+ ```
59
+
60
+ :::info
61
+ [`createBridgeComponent`](https://module-federation.io/zh/practice/bridge/react-bridge.html#createbridgecomponent) 用于导出应用级别模块,Modern.js 相关 API 可以查看 [createRoot](/apis/app/runtime/core/create-root)、[render](/apis/app/runtime/core/render)。
62
+ :::
63
+
64
+ ## 消费者使用模块
65
+
66
+ 然后我们修改消费者配置,移除之前创建的的路由文件 `src/routes/remote/page.tsx`。
67
+
68
+ 我们希望所有访问到 `/remote` 的路由都能被进入上述应用级别模块中,因此我们重新添加 `src/routes/remote/$.tsx`。
69
+
70
+ :::note
71
+ 如果你还不了解 `$.tsx` 的能力,可以阅读 [通配路由](/guides/basic-features/routes.html#通配路由)。
72
+ :::
73
+
74
+ ```tsx title="src/routes/remote/$.tsx"
75
+ import { createRemoteComponent } from '@module-federation/bridge-react';
76
+ import { loadRemote } from '@module-federation/modern-js/runtime';
77
+
78
+ const ErrorBoundary = (info?: { error: { message: string } }) => {
79
+ return (
80
+ <div>
81
+ <h2>This is ErrorBoundary Component, Something went wrong:</h2>
82
+ <pre style={{ color: 'red' }}>{info?.error.message}</pre>
83
+ </div>
84
+ );
85
+ };
86
+ const Loading = <div>loading...</div>;
87
+ const RemoteApp = createRemoteComponent({
88
+ loader: () => loadRemote('remote/app'),
89
+ fallback: ErrorBoundary,
90
+ loading: Loading,
91
+ });
92
+
93
+ export default RemoteApp;
94
+ ```
95
+
96
+ :::info
97
+ [`createRemoteComponent`](https://module-federation.io/zh/practice/bridge/react-bridge.html#createremotecomponent) 用于加载应用级别模块。
98
+ :::
99
+
100
+ ## 启动应用
101
+
102
+ 现在,生产者应用和消费者应用都已经搭建完毕,我们可以在本地运行 `modern dev` 启动两个应用。
103
+
104
+ 启动后,消费者应用访问 `/remote` 路由时,会进入生产者应用中。访问 `http://localhost:8080/remote`,可以看到页面中已经包含了生产者的远程模块的完整页面。
105
+
106
+ 你可以在生产者应用中,创建新的路由文件,并在代码中添加路由导航,可以发现这些功能也能够正常运行。
107
+
108
+ 上述用例可以参考:[Modern.js & Module Federation 应用级别模块](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/module-federation/app-export)。
109
+
110
+ ## 相关文档
111
+
112
+ - [Module Federation Bridge](https://module-federation.io/zh/practice/bridge/index.html)
@@ -0,0 +1,28 @@
1
+ # 部署
2
+
3
+ 通常情况下,部署 Module Federation 应用,需要在消费者上将远程模块地址,调整为其线上地址。
4
+
5
+ 例如已经将生产者部署到 `https://my-remote-module` 这个域名下,可以这样修改消费者的 `module-federation.config.ts` 文件:
6
+
7
+ ```ts title="module-federation.config.ts"
8
+ import { createModuleFederationConfig } from '@module-federation/modern-js';
9
+
10
+ export default createModuleFederationConfig({
11
+ name: 'host',
12
+ remotes: {
13
+ remote: 'remote@http://my-remote-module/mf-manifest.json',
14
+ },
15
+ shared: {
16
+ react: { singleton: true },
17
+ 'react-dom': { singleton: true },
18
+ },
19
+ });
20
+ ```
21
+
22
+ 此时,消费者将加载生产环境的 `remote` 模块的 `manifest` 配置文件。
23
+
24
+ ## 通过平台部署
25
+
26
+ 上述部署方式只是最简单的实践,在真实场景还有很多限制,例如版本管理、发布时序等。在字节跳动内部,我们在部署平台上搭建了 Module Federation 应用的部署流程,可以帮助开发者解决这些问题。
27
+
28
+ 我们会持续关注社区里类似功能的平台,在未来完善 Modern.js + Module Federation 在这些类平台上的部署文档。
@@ -0,0 +1,35 @@
1
+ # 简介
2
+
3
+ 模块联邦(Module Federation)是一种 JavaScript 应用分治的架构模式,它允许你在多个 JavaScript 应用之间共享代码和资源。
4
+
5
+ 在这种分治的模式下,可以帮助你提升应用程序的性能,增强代码可维护性等。
6
+
7
+ ## Module Federation 2.0
8
+
9
+ Module Federation 作为 Webpack 5 推出的重磅功能,自发布以来已经三年有余。在今年,字节跳动与 Module Federation 的作者 [@Zack Jackson](https://github.com/ScriptedAlchemy) 以及社区成员共同推出了 **Module Federation 2.0**。
10
+
11
+ Module Federation 2.0 基于字节跳动内部实践以及 Module Federation 原有社区生态,解决了原先版本中的诸多问题。
12
+
13
+ 在字节跳动内部,基于 Modern.js 的框架已经与 Module Federation 2.0 进行了深度集成。我们正在逐步将这些功能集成到 Modern.js 中,希望与社区开发者共同探索未来。
14
+
15
+ :::info
16
+ 参考 [Module Federation 2.0 发布](https://module-federation.io/zh/blog/announcement.html) 获取更多相关内容。
17
+ :::
18
+
19
+ ## Modern.js MF 插件
20
+
21
+ 基于字节跳动内部实践,Module Federation 团队官方提供了 [Modern.js 插件](https://www.npmjs.com/package/@module-federation/modern-js),帮助开发者更方便的使用 Module Federation。
22
+
23
+ 插件会识别当前构建引擎(Webpack 或 Rspack),在 Modern.js 应用中注入 Module Federation 对应插件,并自动处理构建配置、添加运行时代码等。
24
+
25
+ 同时,插件还支持在 Modern.js SSR 应用中使用 Module Federation,提供更好的性能体验。
26
+
27
+ 详细内容可以参考 [使用 Module Federation](/guides/topic-detail/module-federation/usage)、[Module Federation 服务端渲染](/guides/topic-detail/module-federation/ssr)。
28
+
29
+ ## 应用维度模块
30
+
31
+ **应用级别模块**是具备应用的框架渲染能力及路由能力,能像应用一样运行的模块。应用级别模块是在**微前端框架**中非常重要的能力,提供跨应用框架(React、Vue)加载和渲染的能力,支持加载带路由的模块。
32
+
33
+ Module Federation 2.0 提供了 [Bridge](https://module-federation.io/zh/practice/bridge/index.html) 的能力,用于加载应用级别模块。
34
+
35
+ Modern.js 基于 Brdige 和自身内部实现提供了 API,可以非常简单的导出应用级别模块。详细内容可以参考 [应用级别模块](/guides/topic-detail/module-federation/application)。
@@ -0,0 +1,31 @@
1
+ # 服务端渲染
2
+
3
+ `@module-federation/modern-js` 提供了非常强大的能力,开发者可以非常方便的在 Modern.js 应用中,组合使用 Module Federation 和服务端渲染(SSR)的能力。
4
+
5
+ ## 开启 SSR
6
+
7
+ 我们以 [使用模块联邦](/guides/topic-detail/module-federation/usage) 创建的应用为例,只需要在生产者和消费者上,都添加 `server.ssr` 配置即可:
8
+
9
+ ```ts title="modern.config.ts"
10
+ import { appTools, defineConfig } from '@modern-js/app-tools';
11
+
12
+ export default defineConfig({
13
+ server: {
14
+ ssr: {
15
+ mode: 'stream',
16
+ },
17
+ },
18
+ }
19
+ ```
20
+
21
+ 为更好的性能体验,我们仅支持 Streaming SSR 情况使用这种能力组合。
22
+
23
+ :::warning
24
+ 目前 `@module-federation/bridge-react` 未兼容 Node 环境,你必须从依赖中移除它,才能正常使用 Module Federation 和服务端渲染。这意味着 Bridge 无法和服务端渲染配合使用。
25
+ :::
26
+
27
+ ## 数据获取
28
+
29
+ :::note
30
+ 敬请期待
31
+ :::
@@ -0,0 +1,181 @@
1
+ # 开始使用
2
+
3
+ 在 Modern.js 中使用 Module Federation 我们推荐使用官方插件 `@module-federation/modern-js`。
4
+
5
+ 本章节将会介绍如何通过官方插件搭含生产者应用与消费者应用,我们首先根据 [Modern.js 快速上手](/guides/get-started/quick-start) 创建两个应用。
6
+
7
+ ## 安装插件
8
+
9
+ 完成应用创建后,我们分别为两个项目安装插件:
10
+
11
+ import { PackageManagerTabs } from '@theme';
12
+
13
+ <PackageManagerTabs command="add @module-federation/modern-js" />
14
+
15
+ ## 注册插件
16
+
17
+ 安装插件后,你需要在 `modern.config.js` 中注册插件:
18
+
19
+ ```ts
20
+ import { appTools, defineConfig } from '@modern-js/app-tools';
21
+ import { moduleFederationPlugin } from '@module-federation/modern-js';
22
+
23
+ export default defineConfig({
24
+ runtime: {
25
+ router: true,
26
+ },
27
+ plugins: [
28
+ appTools({
29
+ bundler: 'rspack',
30
+ }),
31
+ moduleFederationPlugin(),
32
+ ],
33
+ });
34
+
35
+ ```
36
+
37
+ ## 生产者导出模块
38
+
39
+ 接下来,我们先修改生产者的代码,导出 Module Federation 模块。
40
+
41
+ 我们创建 `src/components/Button.tsx` 文件,导出一个 Button 组件:
42
+
43
+ ```tsx title="src/components/Button.tsx"
44
+ import React from 'react';
45
+
46
+ export const Button = () => {
47
+ return <button type="button">Remote Button</button>;
48
+ };
49
+ ```
50
+
51
+ 随后,在项目根目录添加 `module-federation.config.ts`,配置 Module Federation 模块的名称、共享依赖和导出内容:
52
+
53
+ ```ts title="module-federation.config.ts"
54
+ import { createModuleFederationConfig } from '@module-federation/modern-js';
55
+
56
+ export default createModuleFederationConfig({
57
+ name: 'remote',
58
+ filename: 'remoteEntry.js',
59
+ exposes: {
60
+ './Button': './src/components/Button.tsx',
61
+ },
62
+ shared: {
63
+ react: { singleton: true },
64
+ 'react-dom': { singleton: true },
65
+ },
66
+ });
67
+ ```
68
+
69
+ 另外,我们还需要修改 `modern.config.ts`,为生产者提供一个开发环境的端口,让消费者可以通过此端口访问生产者的资源:
70
+
71
+ ```ts title="modern.config.ts"
72
+ import { appTools, defineConfig } from '@modern-js/app-tools';
73
+ import { moduleFederationPlugin } from '@module-federation/modern-js';
74
+
75
+ export default defineConfig({
76
+ dev: {
77
+ port: 3051,
78
+ },
79
+ runtime: {
80
+ router: true,
81
+ },
82
+ plugins: [
83
+ appTools({
84
+ bundler: 'rspack',
85
+ }),
86
+ moduleFederationPlugin(),
87
+ ],
88
+ });
89
+ ```
90
+
91
+ ## 消费者使用模块
92
+
93
+ 现在,我们修改消费者的代码,使用生产者导出的模块。
94
+
95
+ 在项目根目录添加 `module-federation.config.ts`,配置 Module Federation 模块的名称、共享依赖和使用的远程模块:
96
+
97
+ ```ts title="module-federation.config.ts"
98
+ import { createModuleFederationConfig } from '@module-federation/modern-js';
99
+
100
+ export default createModuleFederationConfig({
101
+ name: 'host',
102
+ remotes: {
103
+ remote: 'remote@http://localhost:3051/mf-manifest.json',
104
+ },
105
+ shared: {
106
+ react: { singleton: true },
107
+ 'react-dom': { singleton: true },
108
+ },
109
+ });
110
+ ```
111
+
112
+ `mf-manifest.json` 是生产者在打包后产出的文件,包含了生产者导出的所有模块信息。
113
+
114
+ 我们创建新的路由文件 `src/routes/remote/page.tsx`,引入生产者模块:
115
+
116
+ ```tsx title="src/routes/remote/page.tsx"
117
+ import React, { useState, Suspense } from 'react';
118
+ import { Button } from 'remote/Button';
119
+
120
+ const Index = (): JSX.Element => {
121
+ return (
122
+ <div>
123
+ <Suspense fallback={<div>Loading...</div>}>
124
+ <Button />
125
+ </Suspense>
126
+ </div>
127
+ );
128
+ };
129
+
130
+ export default Index;
131
+ ```
132
+
133
+ 此时 `remote/Button` 引入会出现类型错误,这是因为本地没有远程模块的类型。Module Federation 2.0 提供了 [类型提示](https://module-federation.io/zh/guide/basic/type-prompt.html) 的能力,会在生产者构建时自动生成远程模块的类型定义,在消费者构建时自动下载。
134
+
135
+ 为此我们需要在 `tsconfig.json` 中添加新的 `path`,保证类型生效:
136
+
137
+ ```json title="tsconfig.json"
138
+ {
139
+ "compilerOptions": {
140
+ "paths": {
141
+ "*": ["./@mf-types/*"]
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ :::tip
148
+ 在消费者中,我们通过 `remote/Button` 来引用远程模块。这里简单介绍下这个路径具体代表了什么,可以先将它抽象成 `[remoteAlias]/[remoteExpose]`。
149
+
150
+ 第一段 `remoteAlias` 是生产者在消费者中的别名,它是消费者 `module-federation.config.ts` 中配置的 `remotes` 字段的 `key`:
151
+
152
+ ```ts
153
+ {
154
+ remotes: {
155
+ [remoteAlias]: '[remoteModuleName]@[URL_ADDRESS]',
156
+ }
157
+ }
158
+ ```
159
+
160
+ 这里我们也将远程地址抽象为 `[remoteModuleName]@[URL_ADDRESS]`,`@` 前的部分必须对应生产者的模块名。
161
+
162
+ 第二段 `remoteExpose` 是生产者在 `module-federation.config.ts` 中配置的 `exposes` 字段的 `key`。
163
+ :::
164
+
165
+ ## 启动应用
166
+
167
+ 现在,生产者应用和消费者应用都已经搭建完毕,我们可以在本地运行 `modern dev` 启动两个应用。
168
+
169
+ 启动后,消费者中对生产者模块的引入,不会再出现抛错,类型已经下载到消费者应用中。
170
+
171
+ :::note
172
+ 修改生产者代码后,消费者会自动拉取生产者的类型。
173
+ :::
174
+
175
+ 访问 `http://localhost:8080/remote`,可以看到页面中已经包含了生产者的远程模块 `Button` 组件。
176
+
177
+ 上述用例可以参考:[Modern.js & Module Federation 基础用法示例](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/module-federation/base)。
178
+
179
+ ## 相关文档
180
+
181
+ - [Module Federation 官方文档](https://module-federation.io/zh/guide/framework/modernjs.html)
@@ -6,7 +6,7 @@
6
6
 
7
7
  Modern.js 拥有自己的框架插件系统,你可以通过在 `modern.config.ts` 中配置 [`plugins`](/configure/app/plugins) 字段来使用 Modern.js 插件。
8
8
 
9
- ### 插件类型
9
+ ### 插件类型
10
10
 
11
11
  框架插件可以细分成三类,分别是:
12
12
 
@@ -62,8 +62,8 @@ Modern.js 从 `MAJOR_VERSION.46.0` 起开始将底层的构建工具升级为 [R
62
62
  | [CSS Minimizer 插件](https://github.com/rspack-contrib/rsbuild-plugin-css-minimizer) | 用于自定义 CSS 压缩工具,切换到 [cssnano](https://cssnano.co/) 或其他工具进行 CSS 压缩。 | [tools.minifyCss](/configure/app/tools/minify-css.html) |
63
63
  | [Pug 插件](https://github.com/rspack-contrib/rsbuild-plugin-pug) | 提供对 Pug 模板引擎的支持 | [tools.pug](/configure/app/tools/pug.html) |
64
64
  | [Rem 插件](https://github.com/rspack-contrib/rsbuild-plugin-rem) | 用于实现移动端页面的 rem 自适应布局 | [output.convertToRem](/configure/app/output/convert-to-rem.html) |
65
- | [YAML 插件](https://github.com/rspack-contrib/rsbuild-plugin-yaml) | 用于引用 YAML 文件,并将其转换为 JavaScript 对象 | [TOML 文件](/guides/basic-features/static-assets/json-files.html#toml-文件) |
66
- | [TOML 插件](https://github.com/rspack-contrib/rsbuild-plugin-toml) | 用于引用 TOML 文件,并将其转换为 JavaScript 对象 | [YAML 文件](/guides/basic-features/static-assets/json-files.html#yaml-文件) |
65
+ | [YAML 插件](https://github.com/rspack-contrib/rsbuild-plugin-yaml) | 用于引用 YAML 文件,并将其转换为 JavaScript 对象 | [YAML 文件](/guides/basic-features/static-assets/json-files.html#yaml-文件) |
66
+ | [TOML 插件](https://github.com/rspack-contrib/rsbuild-plugin-toml) | 用于引用 TOML 文件,并将其转换为 JavaScript 对象 | [TOML 文件](/guides/basic-features/static-assets/json-files.html#toml-文件) |
67
67
 
68
68
  #### 未内置的插件
69
69
 
@@ -75,4 +75,4 @@ Modern.js 从 `MAJOR_VERSION.46.0` 起开始将底层的构建工具升级为 [R
75
75
 
76
76
  import OtherPlugins from '@site-docs/components/other-plugins.mdx';
77
77
 
78
- <OtherPlugins />
78
+ <OtherPlugins />
package/i18n.json CHANGED
@@ -107,6 +107,10 @@
107
107
  "zh": "Reduck 状态管理",
108
108
  "en": "Reduck State Manager"
109
109
  },
110
+ "module-federation": {
111
+ "zh": "模块联邦",
112
+ "en": "Module Federation"
113
+ },
110
114
  "generator": {
111
115
  "zh": "项目生成器",
112
116
  "en": "Project Generator"
package/package.json CHANGED
@@ -15,17 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.60.1",
18
+ "version": "2.60.3",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
24
  "dependencies": {
25
- "@modern-js/sandpack-react": "2.60.1"
25
+ "@modern-js/sandpack-react": "2.60.3"
26
26
  },
27
27
  "devDependencies": {
28
- "@rspress/shared": "1.31.0",
28
+ "@rspress/shared": "1.31.1",
29
29
  "@types/fs-extra": "9.0.13",
30
30
  "@types/node": "^16",
31
31
  "classnames": "^2",
@@ -33,7 +33,7 @@
33
33
  "fs-extra": "^10",
34
34
  "react": "^18",
35
35
  "react-dom": "^18",
36
- "rspress": "1.31.0",
36
+ "rspress": "1.31.1",
37
37
  "ts-node": "^10.9.1",
38
38
  "typescript": "^5"
39
39
  },