@modern-js/main-doc 2.54.6 → 2.56.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. package/docs/en/apis/app/hooks/src/entry.mdx +42 -0
  2. package/docs/en/apis/app/hooks/src/entry.server.mdx +52 -0
  3. package/docs/en/apis/app/hooks/src/index_.mdx +4 -0
  4. package/docs/en/apis/app/runtime/core/bootstrap.mdx +4 -0
  5. package/docs/en/apis/app/runtime/core/create-app.mdx +5 -1
  6. package/docs/en/apis/app/runtime/core/create-root.mdx +22 -0
  7. package/docs/en/apis/app/runtime/core/render.mdx +42 -0
  8. package/docs/en/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
  9. package/docs/en/apis/app/runtime/ssr/renderString.mdx +62 -0
  10. package/docs/en/apis/app/runtime/ssr/requestHandler.mdx +47 -0
  11. package/docs/en/components/debug-app.mdx +3 -3
  12. package/docs/en/configure/app/dev/live-reload.mdx +27 -0
  13. package/docs/en/configure/app/dev/setup-middlewares.mdx +69 -0
  14. package/docs/en/configure/app/dev/watch-files.mdx +59 -0
  15. package/docs/en/configure/app/dev/write-to-disk.mdx +38 -0
  16. package/docs/en/configure/app/output/ssg.mdx +4 -0
  17. package/docs/en/configure/app/source/enable-async-entry.mdx +4 -4
  18. package/docs/en/configure/app/source/enable-custom-entry.mdx +41 -0
  19. package/docs/en/guides/advanced-features/ssr/cache.mdx +7 -2
  20. package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -1
  21. package/docs/en/guides/basic-features/routes.mdx +1 -1
  22. package/docs/en/guides/concept/entries.mdx +50 -36
  23. package/docs/en/guides/get-started/quick-start.mdx +24 -8
  24. package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +30 -177
  25. package/docs/zh/apis/app/hooks/src/entry.mdx +42 -0
  26. package/docs/zh/apis/app/hooks/src/entry.server.mdx +52 -0
  27. package/docs/zh/apis/app/hooks/src/index_.mdx +4 -0
  28. package/docs/zh/apis/app/runtime/core/bootstrap.mdx +4 -0
  29. package/docs/zh/apis/app/runtime/core/create-app.mdx +5 -1
  30. package/docs/zh/apis/app/runtime/core/create-root.mdx +22 -0
  31. package/docs/zh/apis/app/runtime/core/render.mdx +43 -0
  32. package/docs/zh/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
  33. package/docs/zh/apis/app/runtime/ssr/renderString.mdx +62 -0
  34. package/docs/zh/apis/app/runtime/ssr/requestHandler.mdx +47 -0
  35. package/docs/zh/components/debug-app.mdx +3 -2
  36. package/docs/zh/configure/app/dev/client.mdx +1 -1
  37. package/docs/zh/configure/app/dev/live-reload.mdx +27 -0
  38. package/docs/zh/configure/app/dev/setup-middlewares.mdx +69 -0
  39. package/docs/zh/configure/app/dev/watch-files.mdx +59 -0
  40. package/docs/zh/configure/app/dev/write-to-disk.mdx +38 -0
  41. package/docs/zh/configure/app/output/ssg.mdx +4 -0
  42. package/docs/zh/configure/app/source/enable-async-entry.mdx +4 -4
  43. package/docs/zh/configure/app/source/enable-custom-entry.mdx +41 -0
  44. package/docs/zh/guides/advanced-features/ssr/cache.mdx +6 -2
  45. package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -1
  46. package/docs/zh/guides/basic-features/routes.mdx +1 -1
  47. package/docs/zh/guides/concept/entries.mdx +54 -41
  48. package/docs/zh/guides/get-started/quick-start.mdx +26 -10
  49. package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +29 -174
  50. package/package.json +7 -7
  51. package/docs/en/apis/app/hooks/src/pages.mdx +0 -186
  52. package/docs/zh/apis/app/hooks/src/pages.mdx +0 -187
  53. 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
+ ```
@@ -5,8 +5,9 @@ $ pnpm run dev
5
5
 
6
6
  > modern dev
7
7
 
8
- info Starting dev server...
9
- ready Client compiled in 50 ms
8
+ Modern.js Framework v2.55.0
9
+
10
+ ready Client compiled in 0.86 s
10
11
 
11
12
  > Local: http://localhost:8080/
12
13
  > Network: http://192.168.0.1:8080/
@@ -35,7 +35,7 @@ const defaultConfig = {
35
35
  port: '',
36
36
  host: location.hostname,
37
37
  protocol: location.protocol === 'https:' ? 'wss' : 'ws',
38
- overlay: true,
38
+ overlay: false,
39
39
  };
40
40
  ```
41
41
 
@@ -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
+ ```
@@ -9,6 +9,10 @@ sidebar_label: ssg
9
9
 
10
10
  开启**自控式路由**或**约定式路由** SSG 功能的配置。
11
11
 
12
+ :::info 开启 SSG 功能
13
+ 此配置需要在开启 SSG 功能情况下才会生效。请阅读 [静态站点生成](/guides/advanced-features/ssg) 文档了解如何开启 SSG 功能。
14
+ :::
15
+
12
16
  :::info 客户端路由
13
17
  相关内容可以查看[路由方案](/guides/basic-features/routes)。
14
18
 
@@ -35,15 +35,15 @@ export default defineConfig({
35
35
  node_modules
36
36
  └─ .modern-js
37
37
  └─ main
38
- ├─ bootstrap.jsx # 真正的入口代码
39
- ├─ index.js # 异步入口文件(asynchronous boundary)
38
+ ├─ bootstrap.jsx # 异步入口文件(asynchronous boundary)
39
+ ├─ index.js # 真正的入口代码
40
40
  └─ index.html
41
41
  ```
42
42
 
43
- 其中 `index.js` 的内容如下:
43
+ 其中 `bootstrap.js` 的内容如下:
44
44
 
45
45
  ```js
46
- import('./bootstrap.jsx');
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
@@ -247,7 +247,7 @@ export function UserLayout() {
247
247
  如果想获取 `entry1/routes/layout.tsx` 中 `loader` 返回的数据,`routeId` 的值就是 `entry1_layout`。
248
248
 
249
249
 
250
- ### (WIP)Loading UI
250
+ ### Loading UI (Experimental)
251
251
 
252
252
  :::info
253
253
  此功能目前是实验性质,后续 API 可能有调整。
@@ -296,7 +296,7 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
296
296
  </RootLayout>
297
297
  ```
298
298
 
299
- ### (WIP)Loading
299
+ ### Loading (Experimental)
300
300
 
301
301
  `routes/` 下每一层目录中,开发者可以创建 `loading.tsx` 文件,默认导出一个 `<Loading>` 组件。
302
302