@modern-js/main-doc 2.54.6 → 2.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/en/apis/app/hooks/src/entry.mdx +42 -0
- package/docs/en/apis/app/hooks/src/entry.server.mdx +52 -0
- package/docs/en/apis/app/hooks/src/index_.mdx +4 -0
- package/docs/en/apis/app/runtime/core/bootstrap.mdx +4 -0
- package/docs/en/apis/app/runtime/core/create-app.mdx +5 -1
- package/docs/en/apis/app/runtime/core/create-root.mdx +22 -0
- package/docs/en/apis/app/runtime/core/render.mdx +42 -0
- package/docs/en/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
- package/docs/en/apis/app/runtime/ssr/renderString.mdx +62 -0
- package/docs/en/apis/app/runtime/ssr/requestHandler.mdx +47 -0
- package/docs/en/components/debug-app.mdx +3 -3
- package/docs/en/configure/app/dev/live-reload.mdx +27 -0
- package/docs/en/configure/app/dev/setup-middlewares.mdx +69 -0
- package/docs/en/configure/app/dev/watch-files.mdx +59 -0
- package/docs/en/configure/app/dev/write-to-disk.mdx +38 -0
- package/docs/en/configure/app/output/ssg.mdx +4 -0
- package/docs/en/configure/app/source/enable-async-entry.mdx +4 -4
- package/docs/en/configure/app/source/enable-custom-entry.mdx +41 -0
- package/docs/en/guides/advanced-features/ssr/cache.mdx +7 -2
- package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -1
- package/docs/en/guides/basic-features/routes.mdx +1 -1
- package/docs/en/guides/concept/entries.mdx +50 -36
- package/docs/en/guides/get-started/quick-start.mdx +24 -8
- package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +30 -177
- package/docs/zh/apis/app/hooks/src/entry.mdx +42 -0
- package/docs/zh/apis/app/hooks/src/entry.server.mdx +52 -0
- package/docs/zh/apis/app/hooks/src/index_.mdx +4 -0
- package/docs/zh/apis/app/runtime/core/bootstrap.mdx +4 -0
- package/docs/zh/apis/app/runtime/core/create-app.mdx +5 -1
- package/docs/zh/apis/app/runtime/core/create-root.mdx +22 -0
- package/docs/zh/apis/app/runtime/core/render.mdx +43 -0
- package/docs/zh/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
- package/docs/zh/apis/app/runtime/ssr/renderString.mdx +62 -0
- package/docs/zh/apis/app/runtime/ssr/requestHandler.mdx +47 -0
- package/docs/zh/components/debug-app.mdx +3 -2
- package/docs/zh/configure/app/dev/client.mdx +1 -1
- package/docs/zh/configure/app/dev/live-reload.mdx +27 -0
- package/docs/zh/configure/app/dev/setup-middlewares.mdx +69 -0
- package/docs/zh/configure/app/dev/watch-files.mdx +59 -0
- package/docs/zh/configure/app/dev/write-to-disk.mdx +38 -0
- package/docs/zh/configure/app/output/ssg.mdx +4 -0
- package/docs/zh/configure/app/source/enable-async-entry.mdx +4 -4
- package/docs/zh/configure/app/source/enable-custom-entry.mdx +41 -0
- package/docs/zh/guides/advanced-features/ssr/cache.mdx +6 -2
- package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -1
- package/docs/zh/guides/basic-features/routes.mdx +1 -1
- package/docs/zh/guides/concept/entries.mdx +54 -41
- package/docs/zh/guides/get-started/quick-start.mdx +26 -10
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +29 -174
- package/package.json +7 -7
- package/docs/en/apis/app/hooks/src/pages.mdx +0 -186
- package/docs/zh/apis/app/hooks/src/pages.mdx +0 -187
- package/docs/zh/apis/monorepo/commands/deploy.mdx +0 -38
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
title: render
|
3
|
+
---
|
4
|
+
# render
|
5
|
+
|
6
|
+
用于渲染项目组件。
|
7
|
+
|
8
|
+
## 使用姿势
|
9
|
+
|
10
|
+
```ts
|
11
|
+
import { render } from '@modern-js/runtime/browser';
|
12
|
+
|
13
|
+
render(<ModernRoot />);
|
14
|
+
```
|
15
|
+
|
16
|
+
## 函数签名
|
17
|
+
|
18
|
+
```ts
|
19
|
+
export function render(App: React.ReactElement, id?: HTMLElement | string): Promise<any>;
|
20
|
+
```
|
21
|
+
|
22
|
+
### 参数
|
23
|
+
|
24
|
+
- `App`:通过 [`createRoot`](./create-root) 创建的 ReactElement 实例。
|
25
|
+
- `id`:要挂载的 DOM 根元素 id,如 `"root"`。
|
26
|
+
|
27
|
+
## 示例
|
28
|
+
|
29
|
+
```tsx
|
30
|
+
import { createRoot } from '@modern-js/runtime/react';
|
31
|
+
import { render } from '@modern-js/runtime/browser';
|
32
|
+
|
33
|
+
const ModernRoot = createRoot();
|
34
|
+
|
35
|
+
async function beforeRender() {
|
36
|
+
// todo
|
37
|
+
}
|
38
|
+
|
39
|
+
beforeRender().then(() => {
|
40
|
+
render(<ModernRoot />);
|
41
|
+
});
|
42
|
+
```
|
43
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
---
|
2
|
+
title: renderStreaming
|
3
|
+
---
|
4
|
+
|
5
|
+
# renderStreaming
|
6
|
+
|
7
|
+
用于 React v18+ Streaming SSR 渲染出可读流, 配合 `createRequestHandler` 使用
|
8
|
+
|
9
|
+
## 使用
|
10
|
+
|
11
|
+
```tsx title="src/entry.server.tsx"
|
12
|
+
import {
|
13
|
+
renderStreaming,
|
14
|
+
createRequestHandler,
|
15
|
+
} from '@modern-js/runtime/ssr/server';
|
16
|
+
|
17
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
18
|
+
const stream = await renderStreaming(request, <ServerRoot />, options);
|
19
|
+
|
20
|
+
return new Response(stream, {
|
21
|
+
headers: {
|
22
|
+
'content-type': 'text/html; charset=utf-8',
|
23
|
+
},
|
24
|
+
});
|
25
|
+
};
|
26
|
+
|
27
|
+
export default createRequestHandler(handleRequest);
|
28
|
+
```
|
29
|
+
|
30
|
+
## 函数签名
|
31
|
+
|
32
|
+
```ts
|
33
|
+
export type RenderStreaming = (
|
34
|
+
request: Request,
|
35
|
+
serverRoot: React.ReactElement,
|
36
|
+
optinos: RenderOptions,
|
37
|
+
) => Promise<ReadableStream>;
|
38
|
+
```
|
39
|
+
|
40
|
+
## 示例
|
41
|
+
|
42
|
+
```tsx title="src/entry.server.tsx"
|
43
|
+
import {
|
44
|
+
renderStreaming,
|
45
|
+
createRequestHandler,
|
46
|
+
} from '@modern-js/runtime/ssr/server';
|
47
|
+
|
48
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
49
|
+
// do something before render
|
50
|
+
const stream = await renderStreaming(request, <ServerRoot />, options);
|
51
|
+
|
52
|
+
// docs: https://developer.mozilla.org/en-US/docs/Web/API/TransformStream
|
53
|
+
const transformStream = new TransformStream({
|
54
|
+
transform(chunk, controller) {
|
55
|
+
// do some transform
|
56
|
+
},
|
57
|
+
});
|
58
|
+
|
59
|
+
stream.pipeThrough(transformStream);
|
60
|
+
|
61
|
+
return new Response(transformStream.readable, {
|
62
|
+
headers: {
|
63
|
+
'content-type': 'text/html; charset=utf-8',
|
64
|
+
},
|
65
|
+
});
|
66
|
+
};
|
67
|
+
|
68
|
+
export default createRequestHandler(handleRequest);
|
69
|
+
```
|
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
title: renderString
|
3
|
+
---
|
4
|
+
|
5
|
+
# renderString
|
6
|
+
|
7
|
+
用于 React String SSR 渲染出字符串,配合 `createRequestHandler` 使用
|
8
|
+
|
9
|
+
## 使用
|
10
|
+
|
11
|
+
```tsx title="src/entry.server.tsx"
|
12
|
+
import {
|
13
|
+
renderString,
|
14
|
+
createRequestHandler,
|
15
|
+
} from '@modern-js/runtime/ssr/server';
|
16
|
+
|
17
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
18
|
+
const body = await renderString(request, <ServerRoot />, options);
|
19
|
+
|
20
|
+
return new Response(body, {
|
21
|
+
headers: {
|
22
|
+
'content-type': 'text/html; charset=utf-8',
|
23
|
+
},
|
24
|
+
});
|
25
|
+
};
|
26
|
+
|
27
|
+
export default createRequestHandler(handleRequest);
|
28
|
+
```
|
29
|
+
|
30
|
+
## 函数签名
|
31
|
+
|
32
|
+
```ts
|
33
|
+
export type RenderString = (
|
34
|
+
request: Request,
|
35
|
+
serverRoot: React.ReactElement,
|
36
|
+
optinos: RenderOptions,
|
37
|
+
) => Promise<string>;
|
38
|
+
```
|
39
|
+
|
40
|
+
## 示例
|
41
|
+
|
42
|
+
```tsx title="src/entry.server.tsx"
|
43
|
+
import {
|
44
|
+
renderString,
|
45
|
+
createRequestHandler,
|
46
|
+
} from '@modern-js/runtime/ssr/server';
|
47
|
+
|
48
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
49
|
+
// do something before render
|
50
|
+
const body = await renderString(request, <ServerRoot />, options);
|
51
|
+
|
52
|
+
const newBody = body + '<div>Byte-Dance</div>';
|
53
|
+
|
54
|
+
return new Response(newBody, {
|
55
|
+
headers: {
|
56
|
+
'content-type': 'text/html; charset=utf-8',
|
57
|
+
},
|
58
|
+
});
|
59
|
+
};
|
60
|
+
|
61
|
+
export default createRequestHandler(handleRequest);
|
62
|
+
```
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
title: createRequestHandler
|
3
|
+
---
|
4
|
+
|
5
|
+
# createRequestHandler
|
6
|
+
|
7
|
+
用于自定义 Server-Side Rendering 入口返回 requestHandler
|
8
|
+
|
9
|
+
## 使用
|
10
|
+
|
11
|
+
```tsx title="src/entry.server.tsx"
|
12
|
+
import {
|
13
|
+
renderString,
|
14
|
+
createRequestHandler,
|
15
|
+
} from '@modern-js/runtime/ssr/server';
|
16
|
+
|
17
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
18
|
+
const body = await renderString(request, <ServerRoot />, options);
|
19
|
+
|
20
|
+
return new Response(body, {
|
21
|
+
headers: {
|
22
|
+
'content-type': 'text/html; charset=utf-8',
|
23
|
+
},
|
24
|
+
});
|
25
|
+
};
|
26
|
+
|
27
|
+
export default createRequestHandler(handleRequest);
|
28
|
+
```
|
29
|
+
|
30
|
+
## 函数签名
|
31
|
+
|
32
|
+
```ts
|
33
|
+
export type HandleRequest = (
|
34
|
+
request: Request,
|
35
|
+
ServerRoot: React.ComponentType
|
36
|
+
options: HandleRequestOptions,
|
37
|
+
) => Promise<Response>;
|
38
|
+
|
39
|
+
export type RequestHandler = (
|
40
|
+
request: Request,
|
41
|
+
options: RequestHandlerOptions,
|
42
|
+
) => Promise<Response>;
|
43
|
+
|
44
|
+
export type CreateRequestHandler = (
|
45
|
+
handleRequest: HandleRequest,
|
46
|
+
) => Promise<RequestHandler>;
|
47
|
+
```
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: liveReload
|
3
|
+
---
|
4
|
+
|
5
|
+
# dev.liveReload
|
6
|
+
|
7
|
+
- **类型:** `boolean`
|
8
|
+
- **默认值:** `true`
|
9
|
+
|
10
|
+
是否在源文件变更时自动刷新页面。
|
11
|
+
|
12
|
+
默认情况下,Modern.js 会优先使用 HMR 来更新模块。当 HMR 功能被禁用,或者某些场景 HMR 无法生效时,会自动降级到 liveReload。
|
13
|
+
|
14
|
+
请查看 [模块热更新](https://rsbuild.dev/zh/guide/advanced/hmr) 来了解更多内容。
|
15
|
+
|
16
|
+
## 禁用 liveReload
|
17
|
+
|
18
|
+
如果你需要禁用 liveReload,可以将 `dev.hmr` 和 `dev.liveReload` 同时设置为 `false`,此时页面上不会发起 Web Socket 请求到 dev server,也不会在文件变更时自动刷新页面。
|
19
|
+
|
20
|
+
```js
|
21
|
+
export default {
|
22
|
+
dev: {
|
23
|
+
hmr: false,
|
24
|
+
liveReload: false,
|
25
|
+
},
|
26
|
+
};
|
27
|
+
```
|
@@ -0,0 +1,69 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: setupMiddlewares
|
3
|
+
---
|
4
|
+
|
5
|
+
# dev.setupMiddlewares
|
6
|
+
|
7
|
+
- **类型:**
|
8
|
+
|
9
|
+
```ts
|
10
|
+
type ServerAPIs = {
|
11
|
+
sockWrite: (
|
12
|
+
type: string,
|
13
|
+
data?: string | boolean | Record<string, any>,
|
14
|
+
) => void;
|
15
|
+
};
|
16
|
+
|
17
|
+
type SetupMiddlewares = Array<
|
18
|
+
(
|
19
|
+
middlewares: {
|
20
|
+
unshift: (...handlers: RequestHandler[]) => void;
|
21
|
+
push: (...handlers: RequestHandler[]) => void;
|
22
|
+
},
|
23
|
+
server: ServerAPIs,
|
24
|
+
) => void
|
25
|
+
>;
|
26
|
+
```
|
27
|
+
|
28
|
+
- **默认值:** `undefined`
|
29
|
+
|
30
|
+
提供执行自定义函数和应用自定义中间件的能力。
|
31
|
+
|
32
|
+
中间件的执行顺序是: `unshift` => 内置中间件 => `push`。
|
33
|
+
|
34
|
+
```js
|
35
|
+
export default {
|
36
|
+
dev: {
|
37
|
+
setupMiddlewares: [
|
38
|
+
(middlewares, server) => {
|
39
|
+
middlewares.unshift((req, res, next) => {
|
40
|
+
next();
|
41
|
+
});
|
42
|
+
|
43
|
+
middlewares.push((req, res, next) => {
|
44
|
+
next();
|
45
|
+
});
|
46
|
+
},
|
47
|
+
],
|
48
|
+
},
|
49
|
+
};
|
50
|
+
```
|
51
|
+
|
52
|
+
一些特殊场景需求可能需要使用服务器 API:
|
53
|
+
|
54
|
+
- sockWrite。允许向 HMR 客户端传递一些消息,HMR 客户端将根据接收到的消息类型进行不同的处理。如果你发送一个 "content-changed " 的消息,页面将会重新加载。
|
55
|
+
|
56
|
+
```js
|
57
|
+
export default {
|
58
|
+
dev: {
|
59
|
+
setupMiddlewares: [
|
60
|
+
(middlewares, server) => {
|
61
|
+
// 添加自定义 watcher 并在文件更新时触发页面刷新
|
62
|
+
watcher.on('change', (changed) => {
|
63
|
+
server.sockWrite('content-changed');
|
64
|
+
});
|
65
|
+
},
|
66
|
+
],
|
67
|
+
},
|
68
|
+
};
|
69
|
+
```
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: watchFiles
|
3
|
+
---
|
4
|
+
|
5
|
+
# dev.watchFiles
|
6
|
+
|
7
|
+
- **类型:**
|
8
|
+
|
9
|
+
```ts
|
10
|
+
type WatchFiles = {
|
11
|
+
paths: string | string[];
|
12
|
+
// chokidar 选项
|
13
|
+
options?: WatchOptions;
|
14
|
+
};
|
15
|
+
```
|
16
|
+
|
17
|
+
- **默认值:** `undefined`
|
18
|
+
|
19
|
+
监视指定文件和目录的变化。当文件发生变化时,页面将重新加载。
|
20
|
+
|
21
|
+
如果 `dev.hmr` 和 `dev.liveReload` 都设置为 false,则 `watchFiles` 将被忽略。
|
22
|
+
|
23
|
+
:::tip
|
24
|
+
WatchFiles 中文件发生变化时,不会触发配置文件的重新加载及重新编译。
|
25
|
+
:::
|
26
|
+
|
27
|
+
### 示例
|
28
|
+
|
29
|
+
你可以配置一个 glob 模式 / 目录 / 文件的列表,用于监视文件变化。
|
30
|
+
|
31
|
+
```js
|
32
|
+
export default {
|
33
|
+
dev: {
|
34
|
+
watchFiles: {
|
35
|
+
// 监视单个文件
|
36
|
+
paths: 'public/demo.txt',
|
37
|
+
// 使用 glob 模式
|
38
|
+
paths: 'src/**/*.txt',
|
39
|
+
// 监视多个文件路径
|
40
|
+
paths: ['src/**/*.txt', 'public/**/*'],
|
41
|
+
},
|
42
|
+
},
|
43
|
+
};
|
44
|
+
```
|
45
|
+
|
46
|
+
你也可以通过传入一个包含 `paths` 和 `options` 属性的对象,来指定 [chokidar](https://github.com/paulmillr/chokidar#api) 选项。
|
47
|
+
|
48
|
+
```js
|
49
|
+
export default {
|
50
|
+
dev: {
|
51
|
+
watchFiles: {
|
52
|
+
paths: 'src/**/*.txt',
|
53
|
+
options: {
|
54
|
+
usePolling: false,
|
55
|
+
},
|
56
|
+
},
|
57
|
+
},
|
58
|
+
};
|
59
|
+
```
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: writeToDisk
|
3
|
+
---
|
4
|
+
|
5
|
+
# dev.writeToDisk
|
6
|
+
|
7
|
+
- **类型:** `boolean | ((filename: string) => boolean)`
|
8
|
+
- **默认值:** `(file: string) => !file.includes('.hot-update.')`
|
9
|
+
|
10
|
+
用于控制是否将开发环境的构建产物写入到磁盘上。
|
11
|
+
|
12
|
+
## 写入内存
|
13
|
+
|
14
|
+
你可以选择将构建产物构建产物保存在 dev server 的内存中,从而减少文件操作产生的开销。
|
15
|
+
|
16
|
+
只需要将 `dev.writeToDisk` 配置项设置为 `false` 即可:
|
17
|
+
|
18
|
+
```ts
|
19
|
+
export default {
|
20
|
+
dev: {
|
21
|
+
writeToDisk: false,
|
22
|
+
},
|
23
|
+
};
|
24
|
+
```
|
25
|
+
|
26
|
+
## 匹配部分文件
|
27
|
+
|
28
|
+
你也可以将 `dev.writeToDisk` 设置为函数来匹配一部分文件,函数返回 `false` 时不会写入文件,返回值 `true` 时会将文件写入磁盘。
|
29
|
+
|
30
|
+
例如,Modern.js 会默认将文件写入磁盘,并排除热更新临时文件:
|
31
|
+
|
32
|
+
```ts
|
33
|
+
export default {
|
34
|
+
dev: {
|
35
|
+
writeToDisk: (file) => !file.includes('.hot-update.'),
|
36
|
+
},
|
37
|
+
};
|
38
|
+
```
|
@@ -35,15 +35,15 @@ export default defineConfig({
|
|
35
35
|
node_modules
|
36
36
|
└─ .modern-js
|
37
37
|
└─ main
|
38
|
-
├─ bootstrap.jsx #
|
39
|
-
├─ index.js #
|
38
|
+
├─ bootstrap.jsx # 异步入口文件(asynchronous boundary)
|
39
|
+
├─ index.js # 真正的入口代码
|
40
40
|
└─ index.html
|
41
41
|
```
|
42
42
|
|
43
|
-
其中 `
|
43
|
+
其中 `bootstrap.js` 的内容如下:
|
44
44
|
|
45
45
|
```js
|
46
|
-
import('./
|
46
|
+
import('./index.jsx');
|
47
47
|
```
|
48
48
|
|
49
49
|
此时,就可以在当前页面中消费任意的远程模块了。
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: enableCustomEntry
|
3
|
+
---
|
4
|
+
|
5
|
+
# source.enableCustomEntry
|
6
|
+
|
7
|
+
- **类型:** `boolean`
|
8
|
+
- **默认值:** `false`
|
9
|
+
|
10
|
+
该选项用于使用 Modern.js 自定义入口场景。
|
11
|
+
|
12
|
+
开启此选项后,Modern.js 将使用 `src/entry.[jt]sx` 文件作为项目的入口, 具体使用姿势可参考[页面入口](/guides/concept/entries.html)。
|
13
|
+
|
14
|
+
## 示例
|
15
|
+
|
16
|
+
首先,在配置文件中开启此选项:
|
17
|
+
|
18
|
+
```ts title="modern.config.ts"
|
19
|
+
export default defineConfig({
|
20
|
+
source: {
|
21
|
+
enableCustomEntry: true,
|
22
|
+
},
|
23
|
+
});
|
24
|
+
```
|
25
|
+
|
26
|
+
创建 `src/entry.tsx` 文件:
|
27
|
+
|
28
|
+
```tsx
|
29
|
+
import { createRoot } from '@modern-js/runtime/react';
|
30
|
+
import { render } from '@modern-js/runtime/browser';
|
31
|
+
|
32
|
+
const ModernRoot = createRoot();
|
33
|
+
|
34
|
+
async function beforeRender() {
|
35
|
+
// todo
|
36
|
+
}
|
37
|
+
|
38
|
+
beforeRender().then(() => {
|
39
|
+
render(<ModernRoot />);
|
40
|
+
});
|
41
|
+
```
|
@@ -55,10 +55,10 @@ export interface CacheControl {
|
|
55
55
|
```ts
|
56
56
|
export type CacheOptionProvider = (
|
57
57
|
req: IncomingMessage,
|
58
|
-
) => Promise<CacheControl> | CacheControl;
|
58
|
+
) => Promise<CacheControl | false> | CacheControl | false;
|
59
59
|
```
|
60
60
|
|
61
|
-
有时开发者需要通过 req 来自定义缓存 key
|
61
|
+
有时开发者需要通过 req 来自定义缓存 key,或者特定 url 时缓存不生效,可以配置为函数的形式进行处理, 例如以下代码:
|
62
62
|
|
63
63
|
```ts title="server/cache.ts"
|
64
64
|
|
@@ -69,6 +69,10 @@ const provider: CacheOptionProvider = (req) => {
|
|
69
69
|
|
70
70
|
const key = computedKey(url, headers, ...);
|
71
71
|
|
72
|
+
if(url.includes('no-cache=1')) {
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
|
72
76
|
return {
|
73
77
|
maxAge: 500, // ms
|
74
78
|
staleWhileRevalidate: 1000, // ms
|