-
-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
47 changed files
with
1,097 additions
and
178 deletions.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
apps/modernjs-ssr-data-loader/host/src/entry-one/routes/nested-routes/pathname/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Do not edit this file. It is a auto generated. | ||
// It will render sub's layout. | ||
// The layout pathname is: entry-one/nested-routes/pathname | ||
// The layout pathname is: /entry-one/nested-routes/pathname | ||
// The layout route id is: entry-one_nested-routes/pathname/layout |
2 changes: 1 addition & 1 deletion
2
apps/modernjs-ssr-data-loader/host/src/entry-two/routes/federation/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Do not edit this file. It is a auto generated. | ||
// It will render sub's layout. | ||
// The layout pathname is: entry-two/federation | ||
// The layout pathname is: /entry-two/federation | ||
// The layout route id is: entry-two_federation/layout |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion
16
apps/website-new/docs/zh/practice/frameworks/modern/_meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,15 @@ | ||
["index","dynamic-remote"] | ||
[ | ||
"index", | ||
{ | ||
"type": "dir", | ||
"name": "ssr", | ||
"label": "服务端渲染(SSR)", | ||
"collapsed": true | ||
}, | ||
{ | ||
"type": "dir", | ||
"name": "csr", | ||
"label": "客户端渲染(CSR)", | ||
"collapsed": true | ||
} | ||
] |
3 changes: 3 additions & 0 deletions
3
apps/website-new/docs/zh/practice/frameworks/modern/csr/_meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ | ||
"dynamic-remote" | ||
] |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
apps/website-new/docs/zh/practice/frameworks/modern/ssr/_meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[ | ||
"dynamic-remote", | ||
"route-component", | ||
{ | ||
"type": "dir", | ||
"name": "data-manager", | ||
"label": "数据管理", | ||
"collapsed": true | ||
}, | ||
"faq" | ||
] |
5 changes: 5 additions & 0 deletions
5
apps/website-new/docs/zh/practice/frameworks/modern/ssr/data-manager/_meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[ | ||
"index", | ||
"data-fetch", | ||
"data-write" | ||
] |
4 changes: 4 additions & 0 deletions
4
.../website-new/docs/zh/practice/frameworks/modern/ssr/data-manager/data-fetch.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
title: "数据获取" | ||
--- | ||
数据获取 |
4 changes: 4 additions & 0 deletions
4
.../website-new/docs/zh/practice/frameworks/modern/ssr/data-manager/data-write.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
title: "数据获取" | ||
--- | ||
数据获取 |
33 changes: 33 additions & 0 deletions
33
apps/website-new/docs/zh/practice/frameworks/modern/ssr/data-manager/index.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
title: "概览" | ||
--- | ||
|
||
# 介绍 | ||
|
||
此章节会介绍常见的数据请求方式及其弊端,并简述 Modern.js 是如何解决存在的问题。同时展示 Module Federation 如何使用此功能。 | ||
|
||
## 存在的问题 | ||
|
||
在过去,SSR 模式下,生产者组件无法直接在 Server 端获取数据,只能通过消费者透传或者使用 `Await/Suspense` 异步加载数据。 | ||
|
||
该解决方法会加载对应的页面 js 资源,然后发起网络请求,该过程是一个串行过程,这意味着如果有多层组件,那么首屏性能会较差。 | ||
|
||
![serial-request](@public/practice/modernjs/serial-request.jpeg) | ||
|
||
## Modern.js 解决方案 | ||
|
||
在 Modern.js 中,框架会对路由进行分片,并获取对应路由的静态资源和数据,随后会对静态资源和数据进行并行加载。 | ||
|
||
![parallel-request](@public/practice/modernjs/parallel-request.jpeg) | ||
|
||
## 在 Module Federation 中使用 | ||
|
||
根据调用场景有不同的使用方式。 | ||
|
||
### 消费者 | ||
|
||
如果是仅在消费页面使用 Data Loader,那么按照 Modern.js 官网中的[数据获取](https://modernjs.dev/guides/basic-features/data/data-fetch.html)和[数据写入](https://modernjs.dev/guides/basic-features/data/data-write.html)使用即可。 | ||
|
||
### 生产者 | ||
|
||
因为 Data Loader 需要和路由绑定,所以常规的生产者是无法使用此功能,需要该生产者为[路由组件](../route-component)。 |
195 changes: 195 additions & 0 deletions
195
apps/website-new/docs/zh/practice/frameworks/modern/ssr/dynamic-remote.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
--- | ||
title: "动态加载生产者" | ||
--- | ||
|
||
# 动态加载生产者 | ||
|
||
Modern.js 提供了 [Data Loader](https://modernjs.dev/guides/basic-features/data/data-fetch.html#data-loader%E6%8E%A8%E8%8D%90) 来帮助进行数据管理,`Data Loader` 仅在服务端执行,不会在客户端重复执行。 | ||
|
||
本章节将介绍如何利用 `Data Loader` 获取生产者信息并动态加载。 | ||
|
||
## 创建生产者 | ||
|
||
创建一个新的生产者,用于动态加载。 | ||
|
||
### 1. 创建配置文件 | ||
|
||
在项目根目录创建 `module-federation.config.ts` 文件,并写入下列内容: | ||
|
||
```ts title='module-federation.config.ts' | ||
import { createModuleFederationConfig } from '@module-federation/modern-js'; | ||
|
||
export default createModuleFederationConfig({ | ||
name: 'dynamic_provider', | ||
filename: 'remoteEntry.js', | ||
exposes: { | ||
'./Image': './src/components/Image.tsx', | ||
}, | ||
shared: { | ||
react: { singleton: true }, | ||
'react-dom': { singleton: true }, | ||
}, | ||
}); | ||
``` | ||
|
||
### 2. 应用插件 | ||
|
||
在 `modern.config.ts` 应用 `@module-federation/modern-js`: | ||
|
||
```ts title='modern.config.ts' | ||
import { appTools, defineConfig } from '@modern-js/app-tools'; | ||
import { moduleFederationPlugin } from '@module-federation/modern-js'; | ||
|
||
// https://modernjs.dev/en/configure/app/usage | ||
export default defineConfig({ | ||
runtime: { | ||
router: true, | ||
}, | ||
server: { | ||
ssr: { | ||
mode: 'stream', | ||
}, | ||
port: 3008, | ||
}, | ||
plugins: [appTools(), moduleFederationPlugin()], | ||
}); | ||
``` | ||
|
||
### 3. 创建导出组件 | ||
|
||
创建文件 `src/components/Image.tsx` ,内容如下: | ||
|
||
```tsx title='Image.tsx' | ||
import React from 'react'; | ||
import styles from './Image.module.css'; | ||
|
||
export default (): JSX.Element => ( | ||
<div | ||
id="remote-components" | ||
style={{ | ||
backgroundColor: '#c0e91e', | ||
color: 'lightgrey', | ||
padding: '1rem', | ||
}} | ||
> | ||
<h2> | ||
<strong>dynamic remote</strong> image | ||
</h2> | ||
<button | ||
id="dynamic-remote-components-button" | ||
style={{ marginBottom: '1rem' }} | ||
onClick={() => alert('[remote-components] Client side Javascript works!')} | ||
> | ||
Click me to test i'm interactive! | ||
</button> | ||
<img | ||
id="dynamic-remote-components-image" | ||
src="https://module-federation.io/module-federation-logo.svg" | ||
style={{ width: '100px' }} | ||
alt="serge" | ||
/> | ||
<button className={styles['button']}>Button from dynamic remote</button> | ||
</div> | ||
); | ||
``` | ||
并创建对应的样式文件,内容如下: | ||
```css title='Image.module.css' | ||
.button { | ||
background: red; | ||
} | ||
``` | ||
|
||
## 创建 loader | ||
|
||
在对应的路由文件创建同名的 `.data` 文件,以根目录 `src/routes/page.tsx` 为例,创建 `src/routes/page.data.ts`: | ||
|
||
```ts title='page.data.ts' | ||
import { LoaderFunctionArgs } from '@modern-js/runtime/router'; | ||
|
||
export type DataLoaderRes = { | ||
providerList: Array<{ | ||
name: string, | ||
entry: string, | ||
id: string; | ||
}> | ||
} | ||
|
||
const fetchProviderList = async () => { | ||
const res = await new Promise(resolve => { | ||
setTimeout(() => { | ||
resolve([ | ||
{ | ||
name: 'dynamic_provider', | ||
entry: 'http://localhost:3008/mf-manifest.json', | ||
id: 'dynamic_provider/Image' | ||
} | ||
]) | ||
}, 1000); | ||
}); | ||
|
||
return res as DataLoaderRes['providerList'] | ||
} | ||
|
||
export const loader = async ({ request }: LoaderFunctionArgs): Promise<DataLoaderRes> => { | ||
console.log('request params', request); | ||
const providerList = await fetchProviderList(); | ||
return { | ||
providerList | ||
} | ||
}; | ||
``` | ||
|
||
## 加载动态生产者 | ||
|
||
消费 loader 数据,并动态加载对应的生产者: | ||
|
||
```tsx | ||
import { createRemoteSSRComponent, loadRemote, registerRemotes } from '@modern-js/runtime/mf'; | ||
// 使用 import type ,仅获取类型 | ||
import type { DataLoaderRes } from './page.data'; | ||
import { useLoaderData } from '@modern-js/runtime/router'; | ||
|
||
import './index.css'; | ||
|
||
const RemoteSSRComponent = createRemoteSSRComponent({ | ||
loader: () => import('remote/Image'), | ||
loading: 'loading...', | ||
export: 'default', | ||
fallback: ({ error }) => { | ||
if (error instanceof Error && error.message.includes('not exist')) { | ||
return <div>fallback - not existed id</div>; | ||
} | ||
return <div>fallback</div>; | ||
}, | ||
}); | ||
|
||
const Index = () => { | ||
// 获取 data loader 数据 | ||
const dataLoader = useLoaderData() as DataLoaderRes; | ||
// 注册生产者信息 | ||
registerRemotes(dataLoader.providerList); | ||
|
||
const DynamicRemoteSSRComponents = dataLoader.providerList.map(item => { | ||
const { id } = item; | ||
const Com = createRemoteSSRComponent({ | ||
loader: () => loadRemote(id), | ||
loading: 'loading...', | ||
fallback: ({ error }) => { | ||
if (error instanceof Error && error.message.includes('not exist')) { | ||
return <div>fallback - not existed id</div>; | ||
} | ||
return <div>fallback</div>; | ||
}, | ||
}); | ||
return <Com /> | ||
}) | ||
return ( | ||
<div className="container-box"> | ||
<RemoteSSRComponent /> | ||
{DynamicRemoteSSRComponents} | ||
</div> | ||
); | ||
} | ||
|
||
export default Index; | ||
``` |
42 changes: 42 additions & 0 deletions
42
apps/website-new/docs/zh/practice/frameworks/modern/ssr/faq.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
title: "FAQ" | ||
--- | ||
|
||
# FAQ | ||
|
||
## CSS 闪烁问题 | ||
|
||
启动项目访问 `http://localhost:3007/`,发现SSR 正常工作,页面可以正常渲染,但是会有样式闪烁的问题。 | ||
|
||
这是因为生产者的样式文件无法注入到对应的 html 中。 | ||
|
||
此问题可以通过使用 `@module-federation/modern-js` 提供的 [createremotessrcomponent](../../../guide/framework/modernjs#createremotessrcomponent) 解决。 | ||
|
||
修改消费者引用生产者处的代码(`src/routes/page.tsx`): | ||
|
||
```tsx title='page.tsx' | ||
import { createRemoteSSRComponent } from '@modern-js/runtime/mf' | ||
import './index.css'; | ||
|
||
const RemoteSSRComponent = createRemoteSSRComponent({ | ||
loader: () => import('remote/Image'), | ||
loading: 'loading...', | ||
export: 'default', | ||
fallback: ({ error }) => { | ||
if (error instanceof Error && error.message.includes('not exist')) { | ||
return <div>fallback - not existed id</div>; | ||
} | ||
return <div>fallback</div>; | ||
}, | ||
}); | ||
|
||
const Index = () => ( | ||
<div className="container-box"> | ||
<RemoteSSRComponent /> | ||
</div> | ||
); | ||
|
||
export default Index; | ||
``` | ||
|
||
修改后重新访问页面,可以观测返回的 html 中会自动注入生产者的样式文件,从而解决 CSS 闪烁问题。 |
Oops, something went wrong.