From 1d1097c518417f7a9d2b2d7a23049370e2feeda7 Mon Sep 17 00:00:00 2001
From: zero <68810266+zllkjc@users.noreply.github.com>
Date: Mon, 23 Sep 2024 16:17:12 +0800
Subject: [PATCH] docs: add module federation zh docs (#6236)
---
.../docs/en/guides/topic-detail/_meta.json | 6 +
.../topic-detail/module-federation/_meta.json | 1 +
.../module-federation/application.mdx | 112 ++++++++++++
.../topic-detail/module-federation/deploy.mdx | 28 +++
.../module-federation/introduce.mdx | 35 ++++
.../topic-detail/module-federation/ssr.mdx | 31 ++++
.../topic-detail/module-federation/usage.mdx | 162 +++++++++++++++++
.../docs/zh/guides/topic-detail/_meta.json | 6 +
.../topic-detail/module-federation/_meta.json | 1 +
.../module-federation/application.mdx | 112 ++++++++++++
.../topic-detail/module-federation/deploy.mdx | 28 +++
.../module-federation/introduce.mdx | 35 ++++
.../topic-detail/module-federation/ssr.mdx | 31 ++++
.../topic-detail/module-federation/usage.mdx | 163 ++++++++++++++++++
packages/document/main-doc/i18n.json | 4 +
15 files changed, 755 insertions(+)
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/_meta.json
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/application.mdx
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/deploy.mdx
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/introduce.mdx
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/ssr.mdx
create mode 100644 packages/document/main-doc/docs/en/guides/topic-detail/module-federation/usage.mdx
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/_meta.json
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/application.mdx
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/deploy.mdx
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/introduce.mdx
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/ssr.mdx
create mode 100644 packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/usage.mdx
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/_meta.json b/packages/document/main-doc/docs/en/guides/topic-detail/_meta.json
index d0990071f43d..011a74f53888 100644
--- a/packages/document/main-doc/docs/en/guides/topic-detail/_meta.json
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/_meta.json
@@ -1,4 +1,10 @@
[
+ {
+ "type": "dir",
+ "name": "module-federation",
+ "label": "module-federation",
+ "collapsed": true
+ },
{
"type": "dir",
"name": "micro-frontend",
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/_meta.json b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/_meta.json
new file mode 100644
index 000000000000..85c2e67808dd
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/_meta.json
@@ -0,0 +1 @@
+["introduce", "usage", "application", "ssr", "deploy"]
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/application.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/application.mdx
new file mode 100644
index 000000000000..343cd430722e
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/application.mdx
@@ -0,0 +1,112 @@
+# Application-Level Modules
+
+Modern.js provides runtime APIs to quickly export application-level Module Federation modules from your application.
+
+We use the application created in [Using Module Federation](/guides/topic-detail/module-federation/usage) as an example to further explain how to import application-level modules.
+
+## Install Dependencies
+
+Building on the existing application, we need to install the `@module-federation/bridge-react` dependency to use Bridge for loading application-level modules.
+
+import { PackageManagerTabs } from '@theme';
+
+
+
+## Exporting Modules from Producer
+
+Unlike directly exporting component-level modules, we need to create a separate entry for application-level modules to be exported via `Module Federation`.
+
+We create the `src/export-App.tsx` file:
+
+:::note
+The filename can be arbitrary; Modern.js does not enforce a specific naming convention.
+:::
+
+```ts title="src/export-App.tsx"
+import '@modern-js/runtime/registry/main'; // This line must be included, it will import micro frontend runtime dependencies by default
+import { render } from '@modern-js/runtime/browser';
+import { createRoot } from '@modern-js/runtime/react';
+import { createBridgeComponent } from '@module-federation/bridge-react';
+
+const ModernRoot = createRoot();
+export const provider = createBridgeComponent({
+ rootComponent: ModernRoot,
+ render: (Component, dom) => render(Component, dom),
+});
+
+export default provider;
+```
+
+This file will pass the root component of the `main` entry application to the Bridge API and render it to the specified node via Bridge's render function.
+
+Next, we configure `module-federation.config.ts` to modify the export to `src/export-App.tsx`:
+
+```ts title="module-federation.config.ts"
+import { createModuleFederationConfig } from '@module-federation/modern-js';
+
+export default createModuleFederationConfig({
+ name: 'remote',
+ filename: 'remoteEntry.js',
+ exposes: {
+ './remote': './src/export-App.tsx',
+ },
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true },
+ },
+});
+```
+
+:::info
+[`createBridgeComponent`](https://module-federation.io/zh/practice/bridge/react-bridge.html#createbridgecomponent) is used to export application-level modules. Modern.js related APIs can be found at [createRoot](/apis/app/runtime/core/create-root) and [render](/apis/app/runtime/core/render).
+:::
+
+## Using Modules in Consumer
+
+We then modify the consumer configuration by removing the previously created `src/routes/remote/page.tsx` route file.
+
+We want all routes that access `/remote` to enter the aforementioned application-level module, so we add `src/routes/remote/$.tsx` instead.
+
+:::note
+If you are not familiar with the capabilities of `$.tsx`, please read [Wildcard Routes](/guides/basic-features/routes.html#通配路由).
+:::
+
+```tsx title="src/routes/remote/$.tsx"
+import { createRemoteComponent } from '@module-federation/bridge-react';
+import { loadRemote } from '@module-federation/modern-js/runtime';
+
+const ErrorBoundary = (info?: { error: { message: string } }) => {
+ return (
+
+
This is ErrorBoundary Component, Something went wrong:
+
{info?.error.message}
+
+ );
+};
+const Loading =
loading...
;
+const RemoteApp = createRemoteComponent({
+ loader: () => loadRemote('remote/remote'),
+ fallback: ErrorBoundary,
+ loading: Loading,
+});
+
+export default RemoteApp;
+```
+
+:::info
+[`createRemoteComponent`](https://module-federation.io/zh/practice/bridge/react-bridge.html#createremotecomponent) is used to load application-level modules.
+:::
+
+## Start the Application
+
+Now, both the producer and consumer applications are set up. We can run `modern dev` locally to start both applications.
+
+After startup, when the consumer application accesses the `/remote` route, it will enter the producer application. Accessing `http://localhost:8080/remote` will display a complete page of the producer's remote module in the browser.
+
+You can create new route files in the producer application and add route navigation in the code. These functionalities will also work as expected.
+
+You can refer to the example here: [Modern.js & Module Federation Application-Level Modules](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/module-federation/app-export).
+
+## Related Documentation
+
+- [Module Federation Bridge](https://module-federation.io/zh/practice/bridge/index.html)
\ No newline at end of file
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/deploy.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/deploy.mdx
new file mode 100644
index 000000000000..3b433f69441d
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/deploy.mdx
@@ -0,0 +1,28 @@
+# Deployment
+
+Typically, deploying a Module Federation application requires adjusting the remote module address on the consumer side to its online address.
+
+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:
+
+```ts title="module-federation.config.ts"
+import { createModuleFederationConfig } from '@module-federation/modern-js';
+
+export default createModuleFederationConfig({
+ name: 'host',
+ remotes: {
+ remote: 'remote@http://my-remote-module/mf-manifest.json',
+ },
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true },
+ },
+});
+```
+
+At this point, the consumer will load the `manifest` configuration file of the `remote` module in the production environment.
+
+## Deployment via Platform
+
+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.
+
+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.
\ No newline at end of file
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/introduce.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/introduce.mdx
new file mode 100644
index 000000000000..1dc4b705c243
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/introduce.mdx
@@ -0,0 +1,35 @@
+# Introduction
+
+Module Federation is an architectural pattern for dividing JavaScript applications, allowing you to share code and resources among multiple JavaScript applications.
+
+In this divided model, it can help improve application performance, enhance code maintainability, and more.
+
+## Module Federation 2.0
+
+Module Federation, a highlight feature introduced with Webpack 5, has been around for more than three years. This year, ByteDance, along with the author of Module Federation, [@Zack Jackson](https://github.com/ScriptedAlchemy), and community members jointly launched **Module Federation 2.0**.
+
+Module Federation 2.0 is based on internal practices at ByteDance and the existing community ecosystem of Module Federation, addressing many issues in the previous version.
+
+Within ByteDance, frameworks based on Modern.js have already deeply integrated with Module Federation 2.0. We are gradually integrating these features into Modern.js and hope to explore the future together with community developers.
+
+:::info
+Refer to [Module Federation 2.0 Announcement](https://module-federation.io/zh/blog/announcement.html) for more related content.
+:::
+
+## Modern.js MF Plugin
+
+Based on internal practices at ByteDance, the Module Federation team officially provides the [Modern.js Plugin](https://www.npmjs.com/package/@module-federation/modern-js) to help developers use Module Federation more easily.
+
+The plugin recognizes the current build engine (Webpack or Rspack), injects the corresponding Module Federation plugin into Modern.js applications, and automatically handles build configurations and adds runtime code.
+
+Moreover, the plugin also supports the use of Module Federation in Modern.js SSR applications, providing a better performance experience.
+
+For more details, refer to [Using Module Federation](/guides/topic-detail/module-federation/usage) and [Module Federation Server-Side Rendering](/guides/topic-detail/module-federation/ssr).
+
+## Application-Level Modules
+
+**Application-level modules** possess the application's framework rendering capabilities and routing capabilities, allowing them to operate like applications. Application-level modules are a crucial capability in **micro-frontend frameworks**, providing the ability to load and render across application frameworks (React, Vue) and supporting the loading of modules with routing.
+
+Module Federation 2.0 offers the [Bridge](https://module-federation.io/zh/practice/bridge/index.html) capability to load application-level modules.
+
+Modern.js, based on Bridge and its internal implementation, provides APIs to easily export application-level modules. For more details, refer to [Application-Level Modules](/guides/topic-detail/module-federation/application).
\ No newline at end of file
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/ssr.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/ssr.mdx
new file mode 100644
index 000000000000..26422f73afac
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/ssr.mdx
@@ -0,0 +1,31 @@
+# Server-Side Rendering
+
+`@module-federation/modern-js` offers powerful capabilities, enabling developers to easily combine Module Federation with server-side rendering (SSR) in Modern.js applications.
+
+## Enable SSR
+
+Using the application created in [Using Module Federation](/guides/topic-detail/module-federation/usage) as an example, you only need to add the `server.ssr` configuration to both the producer and the consumer:
+
+```ts title="modern.config.ts"
+import { appTools, defineConfig } from '@modern-js/app-tools';
+
+export default defineConfig({
+ server: {
+ ssr: {
+ mode: 'stream',
+ },
+ },
+});
+```
+
+For better performance, we only support using this capability combination in Streaming SSR scenarios.
+
+:::warning
+Currently, `@module-federation/bridge-react` is not compatible with the Node environment. You must remove it from the dependencies to use Module Federation and server-side rendering correctly. This means Bridge cannot work with server-side rendering.
+:::
+
+## Data Fetching
+
+:::note
+Stay tuned
+:::
\ No newline at end of file
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/usage.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/usage.mdx
new file mode 100644
index 000000000000..72ae421cf7bf
--- /dev/null
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/module-federation/usage.mdx
@@ -0,0 +1,162 @@
+# Getting Started
+
+To use Module Federation in Modern.js, we recommend using the official plugin `@module-federation/modern-js`.
+
+This section will introduce how to set up both producer and consumer applications using the official plugin. First, create two applications by following the [Modern.js Quick Start](/guides/get-started/quick-start).
+
+## Install the Plugin
+
+After creating the applications, install the plugin for both projects:
+
+import { PackageManagerTabs } from '@theme';
+
+
+
+## Register the Plugin
+
+After installing the plugin, you need to register it in the `modern.config.js` file:
+
+```ts
+import { appTools, defineConfig } from '@modern-js/app-tools';
+import { moduleFederationPlugin } from '@module-federation/modern-js';
+
+export default defineConfig({
+ runtime: {
+ router: true,
+ },
+ plugins: [
+ appTools({
+ bundler: 'rspack',
+ }),
+ moduleFederationPlugin(),
+ ],
+});
+```
+
+## Export Modules from Producer
+
+Next, modify the producer's code to export the Module Federation module.
+
+Create the `src/components/Button.tsx` file and export a Button component:
+
+```tsx title="src/components/Button.tsx"
+import React from 'react';
+
+export const Button = () => {
+ return ;
+};
+```
+
+Then, add the `module-federation.config.ts` file at the project root to configure the Module Federation module's name, shared dependencies, and exports:
+
+```ts title="module-federation.config.ts"
+import { createModuleFederationConfig } from '@module-federation/modern-js';
+
+export default createModuleFederationConfig({
+ name: 'remote',
+ filename: 'remoteEntry.js',
+ exposes: {
+ './Button': './src/components/Button.tsx',
+ },
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true },
+ },
+});
+```
+
+Additionally, modify `modern.config.ts` to provide a development environment port for the producer, allowing the consumer to access the producer's resources through this port:
+
+```ts title="modern.config.ts"
+import { appTools, defineConfig } from '@modern-js/app-tools';
+import { moduleFederationPlugin } from '@module-federation/modern-js';
+
+export default defineConfig({
+ dev: {
+ port: 3051,
+ },
+ runtime: {
+ router: true,
+ },
+ plugins: [
+ appTools({
+ bundler: 'rspack',
+ }),
+ moduleFederationPlugin(),
+ ],
+});
+```
+
+## Use Modules in Consumer
+
+Now, modify the consumer's code to use the module exported by the producer.
+
+Add the `module-federation.config.ts` file at the project root to configure the Module Federation module's name, shared dependencies, and the remote module to use:
+
+```ts title="module-federation.config.ts"
+import { createModuleFederationConfig } from '@module-federation/modern-js';
+
+export default createModuleFederationConfig({
+ name: 'host',
+ remotes: {
+ remote: 'remote@http://localhost:3051/mf-manifest.json',
+ },
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true },
+ },
+});
+```
+
+`mf-manifest.json` is the file produced by the producer after packaging, containing all the information about the modules exported by the producer.
+
+Create a new route file `src/routes/remote/page.tsx` and import the producer module:
+
+```tsx title="src/routes/remote/page.tsx"
+import React, { useState, Suspense } from 'react';
+import { Button } from 'remote/Button';
+
+const Index = (): JSX.Element => {
+ return (
+
+ Loading...
}>
+
+
+
+ );
+};
+
+export default Index;
+```
+
+At this point, importing `remote/Button` will result in a type error because the local environment doesn't have the type for the remote module. Module Federation 2.0 provides [type hints](https://module-federation.io/zh/guide/basic/type-prompt.html), which will automatically generate type definitions for remote modules during the producer's build and download them during the consumer's build.
+
+To ensure the types take effect, add a new `path` in `tsconfig.json`:
+
+```json title="tsconfig.json"
+{
+ "compilerOptions": {
+ "paths": {
+ "*": ["./@mf-types/*"]
+ }
+ }
+}
+```
+
+## Start the Applications
+
+Now, both the producer and consumer applications are set up. You can run `modern dev` locally to start both applications.
+
+Once started, the imports of the producer's modules in the consumer will no longer throw errors, and the types will be downloaded to the consumer application.
+
+:::note
+After modifying the producer's code, the consumer will automatically fetch the producer's types.
+:::
+
+Access `http://localhost:8080/remote`, and you will see that the page includes the `Button` component from the producer's remote module.
+
+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).
+
+## Related Documentation
+
+- [Module Federation Official Documentation](https://module-federation.io/zh/guide/framework/modernjs.html)
\ No newline at end of file
diff --git a/packages/document/main-doc/docs/zh/guides/topic-detail/_meta.json b/packages/document/main-doc/docs/zh/guides/topic-detail/_meta.json
index d0990071f43d..011a74f53888 100644
--- a/packages/document/main-doc/docs/zh/guides/topic-detail/_meta.json
+++ b/packages/document/main-doc/docs/zh/guides/topic-detail/_meta.json
@@ -1,4 +1,10 @@
[
+ {
+ "type": "dir",
+ "name": "module-federation",
+ "label": "module-federation",
+ "collapsed": true
+ },
{
"type": "dir",
"name": "micro-frontend",
diff --git a/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/_meta.json b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/_meta.json
new file mode 100644
index 000000000000..85c2e67808dd
--- /dev/null
+++ b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/_meta.json
@@ -0,0 +1 @@
+["introduce", "usage", "application", "ssr", "deploy"]
diff --git a/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/application.mdx b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/application.mdx
new file mode 100644
index 000000000000..a717df1e4f5d
--- /dev/null
+++ b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/application.mdx
@@ -0,0 +1,112 @@
+# 应用级别模块
+
+Modern.js 提供了运行时 API,支持快速从应用中导出应用级别的 Module Federation 模块。
+
+我们以 [使用模块联邦](/guides/topic-detail/module-federation/usage) 创建的应用为例,进一步说明如何导入应用级别模块。
+
+## 安装依赖
+
+在原本应用的基础上,我们需要安装 `@module-federation/bridge-react` 依赖,用于使用 Bridge 加载应用级别模块。
+
+import { PackageManagerTabs } from '@theme';
+
+
+
+## 生产者导出模块
+
+和直接导出组件级别的模块不同,我们需要为应用级别模块创建一个独立的入口来作为 `Module Federation` 的导出。
+
+我们创建 `src/export-App.tsx` 文件:
+
+:::note
+这里可以是任意的文件名,Modern.js 没有做强制约定。
+:::
+
+```ts title="src/export-App.tsx"
+import '@modern-js/runtime/registry/main'; // 这一行必须引入,它会默认导入微前端运行时依赖
+import { render } from '@modern-js/runtime/browser';
+import { createRoot } from '@modern-js/runtime/react';
+import { createBridgeComponent } from '@module-federation/bridge-react';
+
+const ModernRoot = createRoot();
+export const provider = createBridgeComponent({
+ rootComponent: ModernRoot,
+ render: (Component, dom) => render(Component, dom),
+});
+
+export default provider;
+```
+
+该文件会将 `main` 入口的应用根组件传递给 Bridge API,并通过 Bridge 将调用渲染函数将其渲染到指定的节点上。
+
+接下来,我们配置 `module-federation.config.ts`,将导出修改为 `src/export-App.tsx`:
+
+```ts title="module-federation.config.ts"
+import { createModuleFederationConfig } from '@module-federation/modern-js';
+
+export default createModuleFederationConfig({
+ name: 'remote',
+ filename: 'remoteEntry.js',
+ exposes: {
+ './remote': './src/export-App.tsx',
+ },
+ shared: {
+ react: { singleton: true },
+ 'react-dom': { singleton: true },
+ },
+});
+```
+
+:::info
+[`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)。
+:::
+
+## 消费者使用模块
+
+然后我们修改消费者配置,移除之前创建的的路由文件 `src/routes/remote/page.tsx`。
+
+我们希望所有访问到 `/remote` 的路由都能被进入上述应用级别模块中,因此我们重新添加 `src/routes/remote/$.tsx`。
+
+:::note
+如果你还不了解 `$.tsx` 的能力,可以阅读 [通配路由](/guides/basic-features/routes.html#通配路由)。
+:::
+
+```tsx title="src/routes/remote/$.tsx"
+import { createRemoteComponent } from '@module-federation/bridge-react';
+import { loadRemote } from '@module-federation/modern-js/runtime';
+
+const ErrorBoundary = (info?: { error: { message: string } }) => {
+ return (
+
+
This is ErrorBoundary Component, Something went wrong: