@modern-js/main-doc 2.54.6 → 2.55.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.
Files changed (41) 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/output/ssg.mdx +4 -0
  13. package/docs/en/configure/app/source/enable-async-entry.mdx +4 -4
  14. package/docs/en/configure/app/source/enable-custom-entry.mdx +41 -0
  15. package/docs/en/guides/advanced-features/ssr/cache.mdx +7 -2
  16. package/docs/en/guides/concept/entries.mdx +50 -36
  17. package/docs/en/guides/get-started/quick-start.mdx +24 -8
  18. package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +30 -177
  19. package/docs/zh/apis/app/hooks/src/entry.mdx +42 -0
  20. package/docs/zh/apis/app/hooks/src/entry.server.mdx +52 -0
  21. package/docs/zh/apis/app/hooks/src/index_.mdx +4 -0
  22. package/docs/zh/apis/app/runtime/core/bootstrap.mdx +4 -0
  23. package/docs/zh/apis/app/runtime/core/create-app.mdx +5 -1
  24. package/docs/zh/apis/app/runtime/core/create-root.mdx +22 -0
  25. package/docs/zh/apis/app/runtime/core/render.mdx +43 -0
  26. package/docs/zh/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
  27. package/docs/zh/apis/app/runtime/ssr/renderString.mdx +62 -0
  28. package/docs/zh/apis/app/runtime/ssr/requestHandler.mdx +47 -0
  29. package/docs/zh/components/debug-app.mdx +3 -2
  30. package/docs/zh/configure/app/dev/client.mdx +1 -1
  31. package/docs/zh/configure/app/output/ssg.mdx +4 -0
  32. package/docs/zh/configure/app/source/enable-async-entry.mdx +4 -4
  33. package/docs/zh/configure/app/source/enable-custom-entry.mdx +41 -0
  34. package/docs/zh/guides/advanced-features/ssr/cache.mdx +6 -2
  35. package/docs/zh/guides/concept/entries.mdx +54 -41
  36. package/docs/zh/guides/get-started/quick-start.mdx +26 -10
  37. package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +29 -174
  38. package/package.json +5 -5
  39. package/docs/en/apis/app/hooks/src/pages.mdx +0 -186
  40. package/docs/zh/apis/app/hooks/src/pages.mdx +0 -187
  41. package/docs/zh/apis/monorepo/commands/deploy.mdx +0 -38
@@ -420,13 +420,13 @@ export const myPlugin = (): CliPlugin<AppTools> => ({
420
420
  },
421
421
  });
422
422
  ```
423
+ {/*
424
+ ### `checkEntryPoint`
423
425
 
424
- ### `modifyEntryImports`
425
-
426
- - Function: Used for modifying or adding `import` statements in the generated entry files.
426
+ - Function: Used for increasing entry types.
427
427
  - Execution stage: Executed before generating the entry files, triggered during the [`prepare`](#prepare) stage.
428
428
  - Hook model: `AsyncWaterfall`
429
- - Type: `AsyncWaterfall<{ imports: ImportStatement[]; entrypoint: Entrypoint; }>`
429
+ - Type: `AsyncWaterfall<{ path: string; entry: false | string; }>`
430
430
  - Example:
431
431
 
432
432
  ```ts
@@ -435,57 +435,20 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
435
435
  export const myPlugin = (): CliPlugin<AppTools> => ({
436
436
  setup(api) {
437
437
  return {
438
- modifyEntryImports({ entrypoint, imports }) {
439
- // add `import React from 'React'`
440
- imports.push({
441
- value: 'react',
442
- specifiers: [
443
- {
444
- imported: 'unmountComponentAtNode',
445
- },
446
- ],
447
- });
448
-
449
- return { entrypoint, imports };
450
- },
438
+ checkEntryPoint({ path, entry }) {
439
+ return { path, entry: entry || isNewEntry(path) };
440
+ }
451
441
  };
452
442
  },
453
443
  });
454
444
  ```
455
445
 
456
- ### `modifyEntryExport`
446
+ ### `modifyEntrypoints`
457
447
 
458
- - Function: used to modify the `export` statement in the generated entry file
448
+ - Function: Used for modifying the entry information, for the newly added entries of the plugin, the corresponding entrypoint information can be modified through this hook.
459
449
  - Execution stage: Before the entry file is generated, the [`prepare`](#prepare) phase triggers
460
450
  - Hook model: `AsyncWaterfall`
461
- - Type: `AsyncWaterfall<{ entrypoint: Entrypoint; exportStatement: string; }>`
462
- - Example:
463
-
464
- ```ts
465
- import type { CliPlugin, AppTools } from '@modern-js/app-tools';
466
-
467
- export const myPlugin = (): CliPlugin<AppTools> => ({
468
- setup(api) {
469
- return {
470
- modifyEntryExport({ entrypoint, exportStatement }) {
471
- return {
472
- entrypoint,
473
- exportStatement: [`export const foo = 'test'`, exportStatement].join(
474
- '\n',
475
- ),
476
- };
477
- },
478
- };
479
- },
480
- });
481
- ```
482
-
483
- ### `modifyEntryRuntimePlugins`
484
-
485
- - Function: Used for adding or modifying [Runtime plugins](#Runtime) in the generated entry files.
486
- - Execution stage: Executed before generating the entry files, triggered during the [`prepare`](#prepare) stage.
487
- - Hook model: `AsyncWaterfall`
488
- - Type: `AsyncWaterfall<{ entrypoint: Entrypoint; plugins: RuntimePlugin[]; }>`
451
+ - Type: `AsyncWaterfall<{ entrypoints: Entrypoint[]; }>`
489
452
  - Example:
490
453
 
491
454
  ```ts
@@ -494,33 +457,23 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
494
457
  export const myPlugin = (): CliPlugin<AppTools> => ({
495
458
  setup(api) {
496
459
  return {
497
- modifyEntryRuntimePlugins({ entrypoint, plugins }) {
498
- const name = 'customPlugin';
499
- const options = {
500
- /** serializable content */
501
- };
502
-
503
- return {
504
- plugins: [
505
- ...plugins,
506
- {
507
- name,
508
- options: JSON.stringify(options),
509
- },
510
- ],
511
- };
460
+ async modifyEntrypoints({ entrypoints }) {
461
+ const newEntryPoints = entrypoints.map(entrypoint => {
462
+ ...
463
+ });
464
+ return { entrypoints: newEntryPoints };
512
465
  },
513
466
  };
514
467
  },
515
468
  });
516
469
  ```
517
470
 
518
- ### `modifyEntryRenderFunction`
471
+ ### `generateEntryCode`
519
472
 
520
- - Function: Used for modifying the `render` function in the generated entry files.
521
- - Execution stage: Executed before generating the entry files, triggered during the [`prepare`](#prepare) stage.
473
+ - Function: Used for modifying the generated entry file
474
+ - Execution stage: After generating the entry file and before creating the builder.
522
475
  - Hook model: `AsyncWaterfall`
523
- - Type: `AsyncWaterfall<{ entrypoint: Entrypoint; code: string; }>`
476
+ - Type: `AsyncWorkflow<{ entrypoints: Entrypoint[] }, void>`
524
477
  - Example:
525
478
 
526
479
  ```ts
@@ -529,18 +482,18 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
529
482
  export const myPlugin = (): CliPlugin<AppTools> => ({
530
483
  setup(api) {
531
484
  return {
532
- modifyEntryRenderFunction({ entrypoint, code }) {
533
- const customRender = `/** render function body */`;
534
- return {
535
- entrypoint,
536
- code: customRender,
537
- };
485
+ async generateEntryCode({ entrypoints }) {
486
+ await Promise.all(
487
+ entrypoints.map(async entrypoint => {
488
+ ...
489
+ })
490
+ );
538
491
  },
539
492
  };
540
493
  },
541
494
  });
542
495
  ```
543
-
496
+ */}
544
497
  ### `modifyFileSystemRoutes`
545
498
 
546
499
  - Function: Used for modifying the content of the generated front-end page routing files, which must be serializable.
@@ -608,32 +561,6 @@ export const myPlugin = (): CliPlugin<AppTools> => ({
608
561
  });
609
562
  ```
610
563
 
611
- ### `modifyAsyncEntry`
612
-
613
- - Function: Used for modifying the asynchronous module that wraps the entry file, see [source.enableAsyncEntry](/configure/app/source/enable-async-entry).
614
- - Execution stage: Executed before generating the entry files, triggered during the [`prepare`](#prepare) stage.
615
- - Hook model: `AsyncWaterfall`
616
- - Type: `AsyncWaterfall<{ entrypoint: Entrypoint; code: string; }>`
617
- - Example:
618
-
619
- ```ts
620
- import type { CliPlugin, AppTools } from '@modern-js/app-tools';
621
-
622
- export const myPlugin = (): CliPlugin<AppTools> => ({
623
- setup(api) {
624
- return {
625
- modifyAsyncEntry({ entrypoint, code }) {
626
- const customCode = `console.log('hello');`;
627
- return {
628
- entrypoint,
629
- code: `${customCode}${code}`,
630
- };
631
- },
632
- };
633
- },
634
- });
635
- ```
636
-
637
564
  ### `htmlPartials`
638
565
 
639
566
  - Function: Used for customizing the generated HTML page template.
@@ -780,7 +707,7 @@ export const myPlugin = (): Plugin => ({
780
707
  - Function: Modifies the components that need to be rendered.
781
708
  - Execution stage: Rendering (SSR/CSR).
782
709
  - Hook model: `Pipeline`
783
- - Type: `Pipeline<{ App: React.ComponentType<any>; }, React.ComponentType<any>>`
710
+ - Type: `Pipeline<{ App: React.ComponentType<any>;config: Record<string, any>; },React.ComponentType<any>>`
784
711
  - Example:
785
712
 
786
713
  :::note
@@ -790,13 +717,12 @@ When using the hoc hook, you need to copy the static properties of the original
790
717
  ```ts
791
718
  import { createContext } from 'react';
792
719
  import type { Plugin } from '@modern-js/runtime';
793
- import hoistNonReactStatics from 'hoist-non-react-statics';
794
720
 
795
721
  export const myPlugin = (): Plugin => ({
796
722
  setup(api) {
797
723
  const FooContext = createContext('');
798
724
  return {
799
- hoc({ App }, next) {
725
+ hoc({ App, config }, next) {
800
726
  const AppWrapper = (props: any) => {
801
727
  return (
802
728
  <FooContext.Provider store={'test'}>
@@ -805,84 +731,11 @@ export const myPlugin = (): Plugin => ({
805
731
  );
806
732
  };
807
733
  return next({
808
- App: hoistNonReactStatics(AppWrapper, App),
734
+ App: AppWrapper,
735
+ config
809
736
  });
810
737
  },
811
738
  };
812
739
  },
813
740
  });
814
741
  ```
815
-
816
- {/* ### `provide`
817
-
818
- - Function: Modifies the Elements that need to be rendered.
819
- - Execution stage: Rendering (SSR/CSR).
820
- - Hook model: `Pipeline`
821
- - Type: `Pipeline<{ element: JSX.Element; props: AppProps; context: RuntimeContext }, JSX.Element>`
822
- - Example:
823
-
824
- ```ts
825
- import { createContext } from 'react';
826
- import type { Plugin } from '@modern-js/runtime';
827
-
828
- export const myPlugin = (): Plugin => ({
829
- setup(api) {
830
- const FooContext = createContext('');
831
-
832
- return {
833
- provide: ({ element }) => <div>{element}</div>,
834
- };
835
- },
836
- });
837
- ```
838
-
839
- ### `client`
840
-
841
- - Function: Customizes the client-side rendering process.
842
- - Execution stage: Client-side rendering in the browser.
843
- - Hook model: `AsyncPipeline`
844
- - Type: `AsyncPipeline<{ App: React.ComponentType<any>; context?: RuntimeContext; rootElement: HTMLElement; }, void>`
845
- - Example:
846
-
847
- ```ts
848
- import ReactDOM from 'react-dom';
849
- import type { Plugin } from '@modern-js/runtime';
850
-
851
- export const myPlugin = (): Plugin => ({
852
- setup(api) {
853
- return {
854
- client: async ({ App, rootElement }) => {
855
- ReactDOM.render(
856
- React.createElement(App, { context: { foo: 'test' } }),
857
- rootElement,
858
- );
859
- },
860
- };
861
- },
862
- });
863
- ```
864
-
865
- ### `server`
866
-
867
- - Function: Customize the server-side rendering process.
868
- - Execution Phase: SSR
869
- - Hook model: `AsyncPipeline`
870
- - Type: `AsyncPipeline<{ App: React.ComponentType<any>; context?: RuntimeContext; }, string>`
871
- - Example:
872
-
873
- ```ts
874
- import ReactDomServer from 'react-dom/server';
875
- import type { Plugin } from '@modern-js/runtime';
876
-
877
- export const myPlugin = (): Plugin => ({
878
- setup(api) {
879
- return {
880
- server({ App, context }) {
881
- return ReactDomServer.renderToString(
882
- React.createElement(App, { context: { foo: 'test' } }),
883
- );
884
- },
885
- };
886
- },
887
- });
888
- ``` */}
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: entry.[tj]s
3
+ sidebar_position: 4
4
+ ---
5
+ # entry.[tj]s
6
+
7
+ 通常情况下[`routes/`](/apis/app/hooks/src/routes.html) 和 [`App.[tj]sx`](/apis/app/hooks/src/app) 钩子文件已经能满足我们的需求,当我们需要在组件渲染之前添加自定义行为或者完全接管 webpack 打包入口时,可以在 `src` 或者入口目录下放置 `entry.[tj]s`。 下面有分两种情况进行讨论:
8
+
9
+ :::info
10
+ 使用该文件需要开启 [source.enableCustomEntry](/configure/app/source/enable-custom-entry)。
11
+ :::
12
+
13
+ ## 在组件渲染前添加自定义行为
14
+
15
+ 在 `src/entry.[tj]s` 中这样实现:
16
+
17
+ ```js title=src/entry.tsx
18
+ import { createRoot } from '@modern-js/runtime/react';
19
+ import { render } from '@modern-js/runtime/browser';
20
+
21
+ const ModernRoot = createRoot();
22
+
23
+ async function beforeRender() {
24
+ // todo
25
+ }
26
+
27
+ beforeRender().then(() => {
28
+ render(<ModernRoot />);
29
+ });
30
+ ```
31
+
32
+ ## 完全接管 webpack 入口
33
+
34
+ 当项目未安装 `@modern-js/runtime` 依赖时, `src/entry.[tj]sx?` 即为真正的 webpack 打包入口文件, 可以直接像使用 create-react-app 等脚手架一样组织代码:
35
+
36
+ ```js title=src/entry.jsx
37
+ import React from 'react';
38
+ import ReactDOM from 'react-dom/client';
39
+ import App from './App';
40
+
41
+ ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
42
+ ```
@@ -0,0 +1,52 @@
1
+ ---
2
+ title: entry.server.[tj]sx
3
+ sidebar_position: 5
4
+ ---
5
+
6
+ # entry.server.[tj]sx
7
+
8
+ 当项目开启 `server.ssr` 时,Modern.js 生成一个默认的 Server-Side 入口。示例代码如下:
9
+
10
+ ```tsx title="entry.server.tsx"
11
+ import {
12
+ renderString,
13
+ createRequestHandler,
14
+ } from '@modern-js/runtime/ssr/server';
15
+
16
+ const handleRequest = async (request, ServerRoot, options) => {
17
+ const body = await renderString(request, <ServerRoot />, options);
18
+
19
+ return new Response(body, {
20
+ headers: {
21
+ 'content-type': 'text/html; charset=utf-8',
22
+ },
23
+ });
24
+ };
25
+
26
+ export default createRequestHandler(handleRequest);
27
+ ```
28
+
29
+ ## 添加自定义行为
30
+
31
+ 如果用户需自定义 Server-Side Rendering 入口,可以在 `src/entry.server.ts`、`src/{entryName}/entry.server.ts` 中自定义 server 入口
32
+
33
+ ```tsx title="src/entry.server.tsx"
34
+ import { renderString, createRequestHandler } from '@edenx/runtime/ssr/server';
35
+ import type { HandleRequest } from '@edenx/runtime/ssr/server';
36
+
37
+ const handleRequest: HandleRequest = async (request, ServerRoot, options) => {
38
+ // do something before rendering
39
+ const body = await renderString(request, <ServerRoot />, options);
40
+
41
+ const newBody = body + '<div>Byte-Dance</div>';
42
+
43
+ return new Response(newBody, {
44
+ headers: {
45
+ 'content-type': 'text/html; charset=UTF-8',
46
+ 'x-custom-header': 'abc',
47
+ },
48
+ });
49
+ };
50
+
51
+ export default createRequestHandler(handleRequest);
52
+ ```
@@ -4,6 +4,10 @@ sidebar_position: 4
4
4
  ---
5
5
  # index.[tj]s
6
6
 
7
+ :::warning
8
+ 即将废弃,推荐使用 [`entry.[tj]s`](/apis/app/hooks/src/entry)。
9
+ :::
10
+
7
11
  应用使用自定义 `bootstrap` 时的入口标识。
8
12
 
9
13
  通常情况下 [`App.[tj]sx`](/apis/app/hooks/src/app) 钩子文件已经能满足我们的需求,当我们需要在 `bootstrap` 之前添加自定义行为或者完全接管 webpack 打包入口时,可以在 `src` 或者入口目录下放置 `index.[tj]s`。 下面有分两种情况进行讨论:
@@ -3,6 +3,10 @@ title: bootstrap
3
3
  ---
4
4
  # bootstrap
5
5
 
6
+ :::warning
7
+ 即将废弃,推荐使用 [`render`](/apis/app/runtime/core/render)。
8
+ :::
9
+
6
10
  用于启动和挂载应用,通常情况下不做手动调用。只有在使用[自定义 Bootstrap](/guides/concept/entries#自定义-bootstrap) 时,才需要使用该 API。
7
11
 
8
12
  ## 使用姿势
@@ -3,7 +3,11 @@ title: createApp
3
3
  ---
4
4
  # createApp
5
5
 
6
- 用于创建自定义入口,定制运行时插件。只有在使用[自定义 App](/guides/concept/entries#自定义-app) 时,才需要使用该 API。
6
+ :::warning
7
+ 即将废弃,推荐使用 [`createRoot`](/apis/app/runtime/core/create-root)。
8
+ :::
9
+
10
+ 用于创建自定义入口,定制运行时插件。
7
11
 
8
12
  ## 使用姿势
9
13
 
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: createRoot
3
+ ---
4
+ # createRoot
5
+
6
+ 用于创建 Modern.js 提供的根组件,该根组件会自动注册 Runtime 插件,并完成 Runtime 插件初始化。
7
+
8
+ ## 使用姿势
9
+
10
+ ```ts
11
+ import { createRoot } from '@modern-js/runtime/react';
12
+ ```
13
+
14
+ ## 函数签名
15
+
16
+ ```ts
17
+ export function createRoot(UserApp?: React.ComponentType | null): React.ComponentType<any>;
18
+ ```
19
+
20
+ ### 参数
21
+
22
+ - `UserApp` 可选参数,默认为 `App.tsx` 导出的组件
@@ -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