@modern-js/main-doc 2.44.0 → 2.46.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -31,6 +31,7 @@ When the value type is `Object`, the following properties can be configured:
31
31
  - `disablePrerender`: `boolean = fasle`, To ensure compatibility with the old data request method (`useLoader`), by default, Modern.js performs pre-rendering of components.
32
32
  However, if developers want to reduce one rendering when there is no use of the useLoader API in your project, you can set the configuration `disablePrerender=true`.
33
33
  - `unsafeHeaders`: `string[] = []`, For safety reasons, Modern.js does not add excessive content to SSR_DATA. Developers can use this configuration to specify the headers that need to be injected.
34
+ - `scriptLoading`: `'defer' | 'blocking' | 'module' | 'async'`, The configuration is the same as [html.scriptLoading](/configure/app/html/script-loading), supporting SSR injected script set to `async` loading. The priority is `ssr.scriptLoading` > `html.scriptLoading`.
34
35
 
35
36
  ```ts title="modern.config.ts"
36
37
  export default defineConfig({
@@ -40,6 +41,7 @@ export default defineConfig({
40
41
  mode: 'stream',
41
42
  inlineScript: false,
42
43
  unsafeHeaders: ['User-Agent'],
44
+ scriptLoading: 'async',
43
45
  },
44
46
  },
45
47
  });
@@ -25,27 +25,18 @@ After the project is created, you can experience the project by running `pnpm ru
25
25
  :::tip
26
26
  When using Rspack as the bundler, the following Features are temporarily unavailable as some of the capabilities are still under development and we will provide support in the future.
27
27
 
28
- - Storybook Devtool
29
28
  - The usage of [useLoader](/guides/basic-features/data/data-fetch.html) in Client Side Rendering
30
29
 
31
30
  :::
32
31
 
33
32
  ## Enable Rspack build
34
33
 
35
- You can enable Rspack build by running `pnpm run new`:
36
-
37
- ```bash
38
- $ pnpm run new
39
- ? Please select the operation you want: Enable features
40
- ? Please select the feature name: Enable Rspack Build
41
- ```
42
-
43
- After executing the command, enable the Rspack build in `modern.config.ts`:
34
+ Since Modern.js MAJOR_VERSION.46.0, you can enable Rspack build by add the following configuration in `modern.config.ts`:
44
35
 
45
36
  ```diff title=modern.config.ts
46
37
  import { appTools, defineConfig } from '@modern-js/app-tools';
47
38
 
48
- + export default defineConfig<'rspack'>({
39
+ export default defineConfig({
49
40
  plugins: [
50
41
  appTools({
51
42
  + bundler: 'experimental-rspack',
@@ -54,6 +45,10 @@ import { appTools, defineConfig } from '@modern-js/app-tools';
54
45
  });
55
46
  ```
56
47
 
48
+ :::tip
49
+ If your current version is lower than MAJOR_VERSION.46.0, you can upgrade by executing `npx modern upgrade`.
50
+ :::
51
+
57
52
  import RspackPrecautions from '@modern-js/builder-doc/docs/en/shared/rspackPrecautions.md';
58
53
 
59
54
  <RspackPrecautions />
@@ -62,15 +57,69 @@ import RspackPrecautions from '@modern-js/builder-doc/docs/en/shared/rspackPreca
62
57
 
63
58
  After enabling Rspack building capability, further configuration migration is needed by referring to the [Configuration Differences](https://modernjs.dev/builder/en/guide/advanced/rspack-start.html#migrating-from-webpack-to-rspack).
64
59
 
60
+ In Modern.js, the [tools.webpack](/configure/app/tools/webpack) and [tools.webpackChain](/configure/app/tools/webpack-chain) configurations only take effect in webpack mode, after turning on the Rspack build, you can modify it to [tools.rspack](/configure/app/tools/rspack) and [tools.bundlerChain](/configure/app/tools/bundler-chain).
61
+
62
+ ```diff
63
+ export default {
64
+ tools: {
65
+ - webppack: (config, { env }) => {
66
+ + rspack: (config, { env }) => {
67
+ if (env === 'development') {
68
+ config.devtool = 'cheap-module-eval-source-map';
69
+ }
70
+ return config;
71
+ },
72
+ - webpackChain: (chain, { env }) => {
73
+ + bundlerChain: (chain, { env }) => {
74
+ if (env === 'development') {
75
+ chain.devtool('cheap-module-eval-source-map');
76
+ }
77
+ },
78
+ },
79
+ };
80
+ ```
81
+
82
+ :::tip
83
+ After turning on the Rspack build capability, there are currently a small number of configurations that are not supported in Rspack, such as [source.moduleScopes](/configure/app/source/module-scopes), [security.sri](/configure/app/security/sri) etc.
84
+
85
+ For unsupported configurations, we have marked `Bundler: only support webpack` or `Bundler: only support Rspack` in the document. Please refer to the specific configuration introduction.
86
+ :::
87
+
88
+ ## Modify transpile configuration
89
+
90
+ Modern.js uses Rspack [builtin:swc-loader](https://www.rspack.dev/guide/builtin-swc-loader.html) for code translation in Rspack mode.
91
+
92
+ Modern.js has provided a more convenient configuration for the common configuration of `builtin:swc-loader`, such as: configuring the component library to import it on demand through [source.transformImport](/configure/app/source/transform-import). If you have custom configuration requirements for `builtin:swc-loader`, you can refer to the following code:
93
+
94
+ ```ts
95
+ export default {
96
+ tools: {
97
+ bundlerChain: (chain, { CHAIN_ID }) => {
98
+ chain.module
99
+ .rule(CHAIN_ID.RULE.JS)
100
+ .use(CHAIN_ID.USE.SWC)
101
+ .tap(options => {
102
+ options.xxx = '';
103
+ return options;
104
+ });
105
+ },
106
+ }
107
+ };
108
+ ```
109
+
110
+ :::tip
111
+ When Rspack build is enabled, `babel-loader` is not enabled by default. If you need to add some babel plugins, you can configure it through [tools.babel](/configure/app/tools/babel). This will generate additional compilation overhead and slow down the Rspack build speed to a certain extent.
112
+ :::
113
+
65
114
  ## The relationship between Rspack and Modern.js versions
66
115
 
67
116
  Usually, the latest version of Rspack will be integrated into Modern.js. You can update the Modern.js-related dependencies and built-in Rspack to the latest version by using `npx modern upgrade` in your project.
68
117
 
69
118
  However, Modern.js uses a locked version dependency method (non-automatic upgrade) for Rspack. Due to differences in release cycles, the version of Rspack integrated into Modern.js may be behind the latest version of Rspack.
70
119
 
71
- When Rspack is enabled for building through dev / build, the current version of Rspack used in the framework will be printed automatically:
120
+ When Rspack is enabled for building through dev / build, the current version of Rspack used in the framework will be printed automatically when debugging mode is turned on:
72
121
 
73
- ![rspack_version_log](https://lf3-static.bytednsdoc.com/obj/eden-cn/6221eh7uhbfvhn/modern/img_v2_dfcf051f-21db-4741-a108-d9f7a82c3abg.png)
122
+ ![rspack_version_log](https://lf3-static.bytednsdoc.com/obj/eden-cn/6221eh7uhbfvhn/modern/20240110-155444.png)
74
123
 
75
124
  ### Override the Built-in Rspack Version
76
125
 
@@ -84,7 +133,6 @@ For example, if you are using pnpm, you can update the Rspack version with `over
84
133
  "overrides": {
85
134
  "@rspack/core": "nightly",
86
135
  "@rspack/plugin-react-refresh": "nightly",
87
- "@rspack/plugin-html": "nightly"
88
136
  }
89
137
  }
90
138
  }
@@ -228,9 +228,21 @@ function ErrorElement() {
228
228
  }
229
229
  ```
230
230
 
231
+ ## Waiting for all content to load for spiders
232
+
233
+ Streaming offers a better user experience because the user can see the content as it becomes available.
234
+
235
+ However, when a spider visits your page, you might want to let all of the content load first and then produce the final HTML output instead of revealing it progressively.
236
+
237
+ Modern.js uses [isbot](https://www.npmjs.com/package/isbot) to examine the user-agent of requests, determining whether they come from a crawler.
238
+
231
239
  :::info More
232
240
 
233
241
  1. [Deferred Data](https://reactrouter.com/en/main/guides/deferred)
234
242
  2. [New Suspense SSR Architecture in React 18](https://github.com/reactwg/react-18/discussions/37)
235
243
 
236
244
  :::
245
+
246
+ import StreamSSRPerformance from '@site-docs/components/stream-ssr-performance';
247
+
248
+ <StreamSSRPerformance />
@@ -306,6 +306,10 @@ If you define the [`shouldRevalidate`](#/shouldrevalidate) function on the route
306
306
 
307
307
  ### `shouldRevalidate`
308
308
 
309
+ :::warning
310
+ Currently `shouldRevalidate` works under csr and streaming ssr.
311
+ :::
312
+
309
313
  In each routing component (`layout.tsx`, `page.tsx`, `$.tsx`), we can export a `shouldRevalidate` function, which is triggered each time a route changes in the project. This function controls which routes' data are reloaded, and when it returns true, the data for the corresponding route is reloaded. data of the corresponding route will be reloaded.
310
314
 
311
315
  ```ts title="routes/user/layout.tsx"
@@ -330,6 +334,37 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
330
334
  For more details about the `shouldRevalidate` function, please refer to [react-router](https://reactrouter.com/en/main/route/should-revalidate)
331
335
  :::
332
336
 
337
+ ### Client Loader
338
+
339
+ :::info
340
+ 1. This feature requires version x.36.0 or above, and it‘s recommended to use the latest version of the framework.
341
+ 2. Only SSR projects have Client Loaders, while in CSR projects, it can be considered as the default Client Loader.
342
+ 3. This feature can be used progressively and not every project needs it. For specific information, please refer to the explanation of applicable scenarios in the document below.
343
+
344
+ :::
345
+
346
+ #### Applicable scenarios
347
+
348
+ In the SSR project, the code in Data Loader will only be executed on the server side when the client performs SPA navigation.
349
+ The framework will send an HTTP request to the SSR service to trigger the execution of Data Loader.
350
+ However, in some scenarios, we may expect that requests sent by clients do not go through the SSR service and directly request data sources.
351
+
352
+ :::info
353
+ Why the Data Loader is only executed server-side in SSR projects can be found in [FAQ](#faq)
354
+
355
+ :::
356
+
357
+ For example, the following scenarios:
358
+
359
+ 1. During SSR degradation, it is not desired for the framework to send requests to the SSR service to obtain data. Instead, direct requests to the data source are preferred.
360
+ 2. There is some cache on the client side, and we don't want to request SSR service to fetch data.
361
+
362
+ In these scenarios, we can use Client Loader. After adding the Client Loader, in the following scenarios, the code in the Client Loader will be called instead of sending requests to SSR services:
363
+
364
+ 1. After SSR is downgraded to CSR, when fetch data on the client side, Client Loader will be executed instead of the framework sending requests to Data Loader (Server) to fetch data.
365
+ 2. When performing SPA navigation in SSR projects and fetch data, Client Loader will be executed.
366
+
367
+
333
368
  ### Incorrect usage
334
369
 
335
370
  1. The `loader` can only return serializable data. In the SSR environment, the return value of the `loader` function will be serialized as a JSON string and then deserialized into an object on the client side. Therefore, the `loader` function cannot return non-serializable data (such as functions).
@@ -403,6 +438,16 @@ In CSR projects, `loader` is executed on the client side, and the BFF function c
403
438
 
404
439
  In SSR projects, each `loader` is also a server-side interface. We recommend using the `loader` instead of the BFF function with an http method of `get` as the interface layer to avoid an extra layer of forwarding and execution.
405
440
 
441
+ 2. Why is the Data Loader only executed on the server-side in SSR projects?
442
+
443
+ The Data Loader in our SSR project is designed to only run on the server side. The main reasons for sending requests from the client to the server during client-side rendering are as follows:
444
+
445
+ - **Simplified usage**, when using a server loader, the data fetching code for both the SSR and CSR phases is in the server loader (the real calls are made by the framework layer), and the code in the server loader doesn't need to care whether it's in a browser environment or a server-side environment.
446
+ - **Reducing data for network requests**, The server loader can be used as a BFF layer, which reduces the amount of data that needs to be fetched by the front-end at runtime.
447
+ - **Reduce client-side bundle size**, moving the logic code and its dependencies from the client to the server.
448
+ - **Improve maintainability**, moving the logic code to the server side reduces the direct impact of data logic on the front-end UI. In addition, the problem of mistakenly introducing server-side dependencies in the client-side bundle or client-side dependencies in the server-side bundle is also avoided.
449
+
450
+
406
451
  ## useLoader (old version)
407
452
 
408
453
  **`useLoader`** is a legacy API in Modern.js v1. This API is a React Hook designed specifically for SSR applications, allowing developers to fetch data in components in isomorphic development.
@@ -184,8 +184,6 @@ Under the application root directory, create the `config/html/` directory, which
184
184
  <!DOCTYPE html>
185
185
  <html>
186
186
  <head>
187
- <%= meta %>
188
- <title><%= title %></title>
189
187
  <%= topTemplate %>
190
188
  <%= headTemplate %>
191
189
  {/* webpack inject css */}
@@ -46,6 +46,12 @@ import ModuleFederation from '@modern-js/builder-doc/docs/en/shared/module-feder
46
46
 
47
47
  <ModuleFederation />
48
48
 
49
+ ## Rsbuild
50
+
51
+ import Rsbuild from '@modern-js/builder-doc/docs/en/shared/rsbuild.md';
52
+
53
+ <Rsbuild />
54
+
49
55
  ## Rspack
50
56
 
51
57
  import Rspack from '@modern-js/builder-doc/docs/en/shared/rspack.md';
File without changes
@@ -31,6 +31,7 @@ export default defineConfig({
31
31
  - `disablePrerender`: `boolean = fasle`, 为了兼容旧数据请求方式 - `useLoader`, 默认情况下 Modern.js 会对组件进行一次预渲染即有两次渲染。
32
32
  开发者在保证项目中没有使用 useLoader Api 情况下, 可通过配置 `disablePrerender=true`来减少一次渲染。
33
33
  - `unsafeHeaders`: `string[] = []`, 为了安全考虑,Modern.js 不会往 SSR_DATA 添加过多的内容。开发者可以通过该配置,对需要注入的 headers 进行配置。
34
+ - `scriptLoading`: `'defer' | 'blocking' | 'module' | 'async'`, 配置同 [html.scriptLoading](/configure/app/html/script-loading),支持 ssr 注入的 script 设置为 async 加载方式。优先级为 `ssr.scriptLoading` > `html.scriptLoading`
34
35
 
35
36
  ```ts title="modern.config.ts"
36
37
  export default defineConfig({
@@ -41,6 +42,7 @@ export default defineConfig({
41
42
  inlineScript: false,
42
43
  disablePrerender: true,
43
44
  unsafeHeaders: ['User-Agent'],
45
+ scriptLoading: 'async',
44
46
  },
45
47
  },
46
48
  });
@@ -25,27 +25,18 @@ import InitRspackApp from '@site-docs/components/init-rspack-app';
25
25
  :::tip
26
26
  在使用 Rspack 作为打包工具时,由于部分能力尚在开发中,以下 features 暂时无法使用,我们将在未来提供支持:
27
27
 
28
- - Storybook 调试
29
28
  - 客户端渲染(CSR)使用 [useLoader](/guides/basic-features/data/data-fetch.html)
30
29
 
31
30
  :::
32
31
 
33
32
  ## 开启 Rspack 构建
34
33
 
35
- 在一个已有的 Modern.js 项目中,你可以通过执行 `pnpm run new` 来启用 Rspack 构建:
36
-
37
- ```bash
38
- $ pnpm run new
39
- ? 请选择你想要的操作 启用可选功能
40
- ? 请选择功能名称 启用「Rspack 构建」
41
- ```
42
-
43
- 执行以上命令后,在 `modern.config.ts` 中添加 Rspack 相关配置即可:
34
+ Modern.js MAJOR_VERSION.46.0 版本起,在一个已有的 Modern.js 项目中,你仅需在 `modern.config.ts` 中添加以下配置,即可启用 Rspack 构建:
44
35
 
45
36
  ```diff title=modern.config.ts
46
37
  import { appTools, defineConfig } from '@modern-js/app-tools';
47
38
 
48
- + export default defineConfig<'rspack'>({
39
+ export default defineConfig({
49
40
  plugins: [
50
41
  appTools({
51
42
  + bundler: 'experimental-rspack',
@@ -54,13 +45,70 @@ import { appTools, defineConfig } from '@modern-js/app-tools';
54
45
  });
55
46
  ```
56
47
 
48
+ :::tip
49
+ 如果你当前版本低于 MAJOR_VERSION.46.0, 可通过执行 `npx modern upgrade` 进行升级。
50
+ :::
51
+
57
52
  import RspackPrecautions from '@modern-js/builder-doc/docs/zh/shared/rspackPrecautions.md';
58
53
 
59
54
  <RspackPrecautions />
60
55
 
61
56
  ## 配置迁移
62
57
 
63
- 开启 Rspack 构建能力后,还需要参考 [配置差异](https://modernjs.dev/builder/guide/advanced/rspack-start.html#从-webpack-迁移到-rspack) 进行进一步的配置迁移。
58
+ Modern.js [tools.webpack](/configure/app/tools/webpack) [tools.webpackChain](/configure/app/tools/webpack-chain) 配置仅在 webpack 模式下生效,开启 Rspack 构建能力后,可根据实际使用场景决定是否修改为 [tools.rspack](/configure/app/tools/rspack) 或 [tools.bundlerChain](/configure/app/tools/bundler-chain)。
59
+
60
+ ```diff
61
+ export default {
62
+ tools: {
63
+ - webppack: (config, { env }) => {
64
+ + rspack: (config, { env }) => {
65
+ if (env === 'development') {
66
+ config.devtool = 'cheap-module-eval-source-map';
67
+ }
68
+ return config;
69
+ },
70
+ - webpackChain: (chain, { env }) => {
71
+ + bundlerChain: (chain, { env }) => {
72
+ if (env === 'development') {
73
+ chain.devtool('cheap-module-eval-source-map');
74
+ }
75
+ },
76
+ },
77
+ };
78
+ ```
79
+
80
+
81
+ :::tip
82
+ 开启 Rspack 构建能力后,目前有小部分配置在 Rspack 中还不支持使用,如 [source.moduleScopes](/configure/app/source/module-scopes)、[security.sri](/configure/app/security/sri) 等。
83
+
84
+ 对于不支持的配置,我们在文档中有标注 `打包工具: 仅支持 webpack` 或 `打包工具: 仅支持 rspack`,可参考具体配置介绍。
85
+ :::
86
+
87
+ ## 修改转译配置
88
+
89
+ Modern.js 在 Rspack 模式下使用 Rspack [builtin:swc-loader](https://www.rspack.dev/zh/guide/builtin-swc-loader.html) 进行代码转译。
90
+
91
+ Modern.js 已对 `builtin:swc-loader` 的常见配置提供了更方便的配置方式,如:通过 [source.transformImport](/configure/app/source/transform-import) 配置组件库按需引入。如果对 `builtin:swc-loader` 有自定义配置的需求,可参考以下代码:
92
+
93
+ ```ts
94
+ export default {
95
+ tools: {
96
+ bundlerChain: (chain, { CHAIN_ID }) => {
97
+ chain.module
98
+ .rule(CHAIN_ID.RULE.JS)
99
+ .use(CHAIN_ID.USE.SWC)
100
+ .tap(options => {
101
+ options.xxx = '';
102
+ return options;
103
+ });
104
+ },
105
+ }
106
+ };
107
+ ```
108
+
109
+ :::tip
110
+ 在启用 Rspack 构建时,babel-loader 默认不会被启用。如需添加 babel 插件,可通过 [tools.babel](/configure/app/tools/babel) 配置,此时会产生额外的编译开销,在一定程度上拖慢 Rspack 构建速度。
111
+ :::
64
112
 
65
113
  ## Rspack 和 Modern.js 的版本关系
66
114
 
@@ -68,9 +116,9 @@ import RspackPrecautions from '@modern-js/builder-doc/docs/zh/shared/rspackPreca
68
116
 
69
117
  但 Modern.js 对于 Rspack 的依赖方式为锁版本方式(非自动升级),由于发版周期不同步等原因,可能会出现 Modern.js 内集成的 Rspack 版本落后于 Rspack 最新版本的情况。
70
118
 
71
- 当你执行 dev / build 命令时,Modern.js 会自动打印当前使用的 Rspack 版本:
119
+ 当你执行 dev / build 命令时,Modern.js 会在开启调试模式时自动打印当前使用的 Rspack 版本:
72
120
 
73
- ![rspack_version_log](https://lf3-static.bytednsdoc.com/obj/eden-cn/6221eh7uhbfvhn/modern/img_v2_dfcf051f-21db-4741-a108-d9f7a82c3abg.png)
121
+ ![rspack_version_log](https://lf3-static.bytednsdoc.com/obj/eden-cn/6221eh7uhbfvhn/modern/20240110-155444.png)
74
122
 
75
123
  #### 修改内置 Rspack 版本
76
124
 
@@ -84,7 +132,6 @@ import RspackPrecautions from '@modern-js/builder-doc/docs/zh/shared/rspackPreca
84
132
  "overrides": {
85
133
  "@rspack/core": "nightly",
86
134
  "@rspack/plugin-react-refresh": "nightly",
87
- "@rspack/plugin-html": "nightly"
88
135
  }
89
136
  }
90
137
  }
@@ -232,9 +232,21 @@ function ErrorElement() {
232
232
  }
233
233
  ```
234
234
 
235
+ ## 为爬虫等待所有内容加载完毕
236
+
237
+ 流式传输可以提高用户体验,因为当页面内容可用时,用户可以及时感知到它们。
238
+
239
+ 然而,当一个爬虫访问该页面时,它可能需要先加载所有内容,直接输出整个 HTML,而不是渐进式地加载它。
240
+
241
+ Modern.js 使用 [isbot](https://www.npmjs.com/package/isbot) 对请求的 `uesr-agent`, 以判断请求是否来自爬虫。
242
+
235
243
  :::info 补充信息
236
244
 
237
245
  1. [Deferred Data](https://reactrouter.com/en/main/guides/deferred)
238
246
  2. [New Suspense SSR Architecture in React 18](https://github.com/reactwg/react-18/discussions/37)
239
247
 
240
248
  :::
249
+
250
+ import StreamSSRPerformance from '@site-docs/components/stream-ssr-performance';
251
+
252
+ <StreamSSRPerformance />
@@ -6,7 +6,7 @@ sidebar_position: 14
6
6
 
7
7
  [CSS Modules](https://github.com/css-modules/css-modules) 让我们能以模块化的方式编写 CSS 代码,并且可以在 JavaScript 文件中导入和使用这些样式。使用 CSS Modules 可以自动生成唯一的类名,隔离不同模块之间的样式,避免类名冲突。
8
8
 
9
- Builder 默认支持使用 CSS Modules,无需添加额外的配置。我们约定使用 `[name].module.css` 文件名来启用 CSS Modules。
9
+ Modern.js 默认支持使用 CSS Modules,无需添加额外的配置。我们约定使用 `[name].module.css` 文件名来启用 CSS Modules。
10
10
 
11
11
  以下样式文件会被视为 CSS Modules:
12
12
 
@@ -299,6 +299,10 @@ defer 的具体用法请查看 [defer](https://reactrouter.com/en/main/guides/de
299
299
 
300
300
  ### `shouldRevalidate`
301
301
 
302
+ :::warning
303
+ 目前 `shouldRevalidate` 会在 csr 和 streaming ssr 下生效。
304
+ :::
305
+
302
306
  在每个路由组件(`layout.tsx`,`page.tsx`, `$.tsx`)中,我们可以导出一个 `shouldRevalidate` 函数,在每次项目中的路由变化时,这个函数会触发,该函数可以控制要重新加载哪些路由中的数据,当这个函数返回 true, 对应路由的数据就会重新加载。
303
307
 
304
308
  ```ts title="routes/user/layout.tsx"
@@ -323,6 +327,66 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
323
327
  `shouldRevalidate` 函数的更多信息可以参考 [react-router](https://reactrouter.com/en/main/route/should-revalidate)
324
328
  :::
325
329
 
330
+ ### Client Loader
331
+
332
+ :::info
333
+ 1. 这个 feature 需要 x.36.0 以上版本,推荐使用框架最新版本
334
+ 2. 只有 SSR 项目中有 Client Loader,CSR 项目中可以认为默认就是 Client Loader
335
+ 3. 这个特性可以渐进使用,并不是每个项目都需要,具体可以看下面文档适用场景的说明
336
+
337
+ :::
338
+
339
+ #### 适用场景
340
+
341
+ 在 SSR 项目中,Data Loader 中的代码只会在服务端执行,当客户端进行 SPA 导航时,
342
+ 框架会发送一个 http 请求到 SSR 服务,触发 Data Loader 的执行,
343
+ 但有些场景下,我们可能期望在客户端发送的请求不经过 SSR 服务,直接请求数据源。
344
+
345
+ :::info
346
+ 为什么 SSR 项目中 Data Loader 只会在服务端执行可参考 [常见问题](#常见问题)
347
+
348
+ :::
349
+
350
+ 例如以下场景:
351
+
352
+ 1. 在 SSR 降级时,不希望框架向 SSR 服务发送请求获取数据,希望能直接请求后端服务。
353
+ 2. 在客户端有一些缓存,不希望请求 SSR 服务获取数据。
354
+
355
+ 这些场景下,我们可以使用 Client Loader, 添加 Client Loader 后,在以下的场景,会调用 Client Loader 中的代码,而不再像 SSR 服务发送请求:
356
+
357
+ 1. SSR 降级为 CSR 后,在客户端获取数据时,会执行 Client Loader 代替框架发送请求到 Data Loader(Server) 获取数据。
358
+ 2. SSR 项目进行 SPA 跳转时,获取数据,会执行 Clinet Loader。
359
+
360
+
361
+ #### 使用方式
362
+
363
+ :::warning
364
+ 要使用 client loader,必须有对应的 server loader(data loader)
365
+ :::
366
+
367
+ 1. 如果原有项目中 loader 是以 `.loader.ts` 文件为约定的,需要修改 `.loader.ts` 为 `.data.ts`(如果 loader 是在 `.data.ts` 文件中定义,忽略这个步骤)。
368
+
369
+ - 将 `.loader.ts` 文件重命名为 `.data.ts`
370
+ - 将文件中的代码做以下改动:
371
+ ```ts
372
+ // xxx.loader.ts
373
+ export default () => {}
374
+
375
+ // xxx.data.ts
376
+ export const loader = () => {}
377
+ ```
378
+
379
+
380
+ 2. 添加 client loader,client loader API 中的入参和 data loader 是一致的。
381
+
382
+ ```
383
+ // xxx.data.client.ts
384
+ export const loader = () => {}
385
+ ```
386
+
387
+
388
+
389
+
326
390
  ### 错误用法
327
391
 
328
392
  1. `loader` 中只能返回可序列化的数据,在 SSR 环境下,`loader` 函数的返回值会被序列化为 JSON 字符串,然后在客户端被反序列化为对象。因此,`loader` 函数中不能返回不可序列化的数据(如函数)。
@@ -394,6 +458,17 @@ export const loader = async (): Promise<ProfileData> => {
394
458
 
395
459
  在 SSR 项目中,每个 `loader` 也是一个服务端接口,我们推荐使用 `loader` 替代 http method 为 `get` 的 BFF 函数,作为接口层,避免多一层转发和执行。
396
460
 
461
+
462
+ 2. 为什么 SSR 项目中 Data Loader 只会在服务端执行?
463
+
464
+ 我们设计 SSR 项目中 Data Loader 只会在服务端,在客户端渲染时,由框架发送请求到服务端主要有以下原因:
465
+
466
+ - **简化使用方式**,有 server loader 后,SSR 阶段和 CSR 阶段数据获取的操作都可以放在 server loader 中(真实的调用由框架层去做),server loader 中的代码无需关心是在浏览器环境中还是服务端环境中。
467
+ - **减少网络请求的数据**,作为 BFF 层,可以减少前端运行时需要获取的数据。
468
+ - **减少客户端 bundle 体积**,将逻辑代码及其依赖,从客户端移动到了服务端。
469
+ - **提高可维护性**,将逻辑代码移动到服务端,减少了数据逻辑对前端 UI 的直接影响。此外,也避免了客户端 bundle 中误引入服务端依赖,或服务端 bundle 中误引入客户端依赖的问题。
470
+
471
+
397
472
  ## useLoader(旧版)
398
473
 
399
474
  **`useLoader`** 是 Modern.js 老版本中的 API。该 API 是一个 React Hook,专门提供给 SSR 应用使用,让开发者能同构的在组件中获取数据。
@@ -187,8 +187,6 @@ Modern.js 也支持通过 HTML(EJS) 语法来生成 HTML 文件。
187
187
  <!DOCTYPE html>
188
188
  <html>
189
189
  <head>
190
- <%= meta %>
191
- <title><%= title %></title>
192
190
  <%= topTemplate %>
193
191
  <%= headTemplate %>
194
192
  {/* webpack inject css */}
@@ -46,6 +46,12 @@ import ModuleFederation from '@modern-js/builder-doc/docs/zh/shared/module-feder
46
46
 
47
47
  <ModuleFederation />
48
48
 
49
+ ## Rsbuild
50
+
51
+ import Rsbuild from '@modern-js/builder-doc/docs/zh/shared/rsbuild.md';
52
+
53
+ <Rsbuild />
54
+
49
55
  ## Rspack
50
56
 
51
57
  import Rspack from '@modern-js/builder-doc/docs/zh/shared/rspack.md';
@@ -40,7 +40,7 @@ export interface IPluginContext {
40
40
 
41
41
  ### 文件类型
42
42
 
43
- 生成器插件将文件类型分为撕四类:
43
+ 生成器插件将文件类型分为四类:
44
44
 
45
45
  - 文本文件
46
46
 
package/package.json CHANGED
@@ -15,17 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.44.0",
18
+ "version": "2.46.0",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
24
  "dependencies": {
25
- "@modern-js/sandpack-react": "2.44.0"
25
+ "@modern-js/sandpack-react": "2.46.0"
26
26
  },
27
27
  "peerDependencies": {
28
- "@modern-js/builder-doc": "^2.44.0"
28
+ "@modern-js/builder-doc": "^2.46.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "classnames": "^2",
@@ -35,12 +35,12 @@
35
35
  "ts-node": "^10.9.1",
36
36
  "typescript": "^5",
37
37
  "fs-extra": "^10",
38
- "rspress": "1.8.4",
39
- "@rspress/shared": "1.8.4",
38
+ "rspress": "1.9.3",
39
+ "@rspress/shared": "1.9.3",
40
40
  "@types/node": "^16",
41
41
  "@types/fs-extra": "9.0.13",
42
- "@modern-js/doc-plugin-auto-sidebar": "2.44.0",
43
- "@modern-js/builder-doc": "2.44.0"
42
+ "@modern-js/doc-plugin-auto-sidebar": "2.46.0",
43
+ "@modern-js/builder-doc": "2.46.0"
44
44
  },
45
45
  "scripts": {
46
46
  "dev": "rspress dev",
@@ -1,9 +0,0 @@
1
- ---
2
- sidebar_label: inspector
3
- ---
4
-
5
- # tools.inspector
6
-
7
- import Main from '@modern-js/builder-doc/docs/en/config/tools/inspector.md';
8
-
9
- <Main />
@@ -1,9 +0,0 @@
1
- ---
2
- sidebar_label: inspector
3
- ---
4
-
5
- # tools.inspector
6
-
7
- import Main from '@modern-js/builder-doc/docs/zh/config/tools/inspector.md';
8
-
9
- <Main />