@modern-js/main-doc 2.20.0 → 2.21.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +11 -0
- package/docs/en/apis/app/runtime/router/router.mdx +22 -0
- package/docs/en/configure/app/security/nonce.mdx +13 -0
- package/docs/en/guides/advanced-features/rspack-start.mdx +38 -0
- package/docs/en/guides/basic-features/css.mdx +37 -27
- package/docs/en/guides/basic-features/data-fetch.mdx +56 -69
- package/docs/en/guides/basic-features/routes.mdx +189 -93
- package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +22 -4
- package/docs/zh/apis/app/runtime/router/router.mdx +22 -0
- package/docs/zh/configure/app/security/nonce.mdx +13 -0
- package/docs/zh/guides/advanced-features/rspack-start.mdx +37 -0
- package/docs/zh/guides/basic-features/data-fetch.mdx +14 -14
- package/docs/zh/guides/basic-features/routes.mdx +22 -22
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +23 -5
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# @modern-js/main-doc
|
2
2
|
|
3
|
+
## 2.21.0
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- 26dcf3a: chore: bump typescript to v5 in devDependencies
|
8
|
+
|
9
|
+
chore: 升级 devDependencies 中的 typescript 版本到 v5
|
10
|
+
|
11
|
+
- Updated dependencies [1ef03dc]
|
12
|
+
- @modern-js/builder-doc@2.21.0
|
13
|
+
|
3
14
|
## 2.20.0
|
4
15
|
|
5
16
|
### Patch Changes
|
@@ -107,6 +107,28 @@ function App() {
|
|
107
107
|
}
|
108
108
|
```
|
109
109
|
|
110
|
+
### useRouteError
|
111
|
+
|
112
|
+
```ts
|
113
|
+
export declare function useRouteError(): unknown;
|
114
|
+
```
|
115
|
+
|
116
|
+
`useRouteError` returns the nearest ancestor Route error。
|
117
|
+
|
118
|
+
```tsx
|
119
|
+
import { useRouteError } from '@modern-js/runtime/router';
|
120
|
+
const ErrorBoundary = () => {
|
121
|
+
const error = useRouteError();
|
122
|
+
return (
|
123
|
+
<div>
|
124
|
+
<h1>{error.status}</h1>
|
125
|
+
<h2>{error.message}</h2>
|
126
|
+
</div>
|
127
|
+
);
|
128
|
+
};
|
129
|
+
export default ErrorBoundary;
|
130
|
+
```
|
131
|
+
|
110
132
|
## Components
|
111
133
|
|
112
134
|
### Link
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: nonce
|
3
|
+
---
|
4
|
+
|
5
|
+
# security.nonce
|
6
|
+
|
7
|
+
:::tip
|
8
|
+
This config is provided by Modern.js Builder, more detail can see [security.nonce](https://modernjs.dev/builder/en/api/config-security.html#securitynonce).
|
9
|
+
:::
|
10
|
+
|
11
|
+
import Main from '@modern-js/builder-doc/docs/en/config/security/nonce.md';
|
12
|
+
|
13
|
+
<Main />
|
@@ -57,3 +57,41 @@ import appTools, { defineConfig } from '@modern-js/app-tools';
|
|
57
57
|
:::tip
|
58
58
|
When migrating from webpack to Rspack, there may have some differences in build and configuration capabilities. For more details, please refer to [Configuration Differences](https://modernjs.dev/builder/en/guide/advanced/rspack-start.html#migrating-from-webpack-to-rspack).
|
59
59
|
:::
|
60
|
+
|
61
|
+
## The relationship between Rspack and Modern.js versions
|
62
|
+
|
63
|
+
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.
|
64
|
+
|
65
|
+
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.
|
66
|
+
|
67
|
+
When Rspack is enabled for building through dev / build, the current version of Rspack used in the framework will be printed automatically:
|
68
|
+
|
69
|
+

|
70
|
+
|
71
|
+
### Override the Built-in Rspack Version
|
72
|
+
|
73
|
+
You can override Rspack to a specific version using the capbilities provided by package managers such as pnpm, yarn, npm.
|
74
|
+
|
75
|
+
For example, if you are using pnpm, you can update the Rspack version with `overrides` as shown below:
|
76
|
+
|
77
|
+
```json title=package.json
|
78
|
+
{
|
79
|
+
"pnpm": {
|
80
|
+
"overrides": {
|
81
|
+
"@rspack/core": "nightly",
|
82
|
+
"@rspack/dev-client": "nightly",
|
83
|
+
"@rspack/dev-middleware": "nightly",
|
84
|
+
"@rspack/plugin-html": "nightly",
|
85
|
+
"@rspack/postcss-loader": "nightly"
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
:::tip What is Rspack Nightly Version
|
92
|
+
The Rspack nightly build fully replicates the full release build for catching errors early.
|
93
|
+
Usually it is available and any errors that arise will fixed promptly.
|
94
|
+
However, if there are any break changes that require modern.js to modify the code, we recommend to wait for the next version of modern.js.
|
95
|
+
:::
|
96
|
+
|
97
|
+
More examples of using package management tools, please refer to: [Lock nested dependency](/guides/get-started/upgrade.html#lock-nested-dependency).
|
@@ -4,33 +4,33 @@ sidebar_position: 2
|
|
4
4
|
|
5
5
|
# CSS Solutions
|
6
6
|
|
7
|
-
Modern.js has built-in
|
7
|
+
Modern.js has built-in a variety of commonly used CSS solutions, including Less / Sass / Stylus preprocessors, PostCSS, CSS Modules, CSS-in-JS, and Tailwind CSS.
|
8
8
|
|
9
9
|
## Using Less, Sass and Stylus
|
10
10
|
|
11
|
-
Modern.js has built-in community
|
11
|
+
Modern.js has built-in popular community CSS preprocessors, including Less and Sass.
|
12
12
|
|
13
|
-
By default, you don't need to configure
|
13
|
+
By default, you don't need to configure Less and Sass. If you have custom loader configuration requirements, you can set them up by configuring [tools.less](/configure/app/tools/less) and [tools.sass](/configure/app/tools/sass).
|
14
14
|
|
15
|
-
You can also use Stylus in Modern.js
|
15
|
+
You can also use Stylus in Modern.js by installing the Stylus plugin provided by Modern.js Builder. For usage, please refer to [Stylus Plugin](https://modernjs.dev/builder/plugins/plugin-stylus.html).
|
16
16
|
|
17
17
|
## Using PostCSS
|
18
18
|
|
19
|
-
Modern.js has built-in [PostCSS](https://postcss.org/) to transform
|
19
|
+
Modern.js has built-in [PostCSS](https://postcss.org/) to transform CSS code.
|
20
20
|
|
21
21
|
Please refer to [Modern.js Builder - Using PostCSS](https://modernjs.dev/builder/en/guide/basic/css-usage.html#using-postcss) for detailed usage.
|
22
22
|
|
23
23
|
## Using CSS Modules
|
24
24
|
|
25
|
-
Please read the [Using CSS Modules](https://modernjs.dev/builder/en/guide/basic/css-modules.html)
|
25
|
+
Please read the [Using CSS Modules](https://modernjs.dev/builder/en/guide/basic/css-modules.html) section to learn about the complete usage of CSS Modules.
|
26
26
|
|
27
27
|
## Using CSS-in-JS
|
28
28
|
|
29
|
-
CSS-in-JS is a
|
29
|
+
CSS-in-JS is a technique that allows you to write CSS styles in JS files.
|
30
30
|
|
31
|
-
Modern.js integrates the CSS-in-JS library [styled-components](https://styled-components.com/)
|
31
|
+
Modern.js integrates the popular CSS-in-JS implementation library [styled-components](https://styled-components.com/), which uses the new JavaScript feature [Tagged template](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) to write component CSS styles. You can directly import the API of [styled-components](https://styled-components.com/) from `@modern-js/runtime/styled` for use.
|
32
32
|
|
33
|
-
When you need to write a `div` component with an internal font
|
33
|
+
When you need to write a `div` component with an internal font color of red, you can implement it as follows:
|
34
34
|
|
35
35
|
```js
|
36
36
|
import styled from '@modern-js/runtime/styled';
|
@@ -40,7 +40,7 @@ const RedDiv = styled.div`
|
|
40
40
|
`;
|
41
41
|
```
|
42
42
|
|
43
|
-
|
43
|
+
If you need to dynamically set component styles based on the component's `props`, for example, the `primary` property of `props` is `true`, the button color is white, otherwise it is red, you can implement the code as follows:
|
44
44
|
|
45
45
|
```js
|
46
46
|
import styled from '@modern-js/runtime/styled';
|
@@ -51,26 +51,36 @@ const Button = styled.button`
|
|
51
51
|
`;
|
52
52
|
```
|
53
53
|
|
54
|
-
For more usage of styled-components, please refer to [
|
54
|
+
For more usage of styled-components, please refer to [styled-components official website](https://styled-components.com/).
|
55
55
|
|
56
|
-
Modern.js
|
56
|
+
Modern.js integrates Babel's [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) plugin internally, and you can configure the plugin through [tools.styledComponents](/configure/app/tools/styled-components).
|
57
57
|
|
58
58
|
:::tip
|
59
|
-
If you need to use [styled-jsx](https://www.npmjs.com/package/styled-jsx)
|
59
|
+
If you need to use other CSS-in-JS libraries such as [styled-jsx](https://www.npmjs.com/package/styled-jsx) and [Emotion](https://emotion.sh/), you need to install the corresponding dependencies first. For specific usage, please refer to the library's official website.
|
60
60
|
:::
|
61
61
|
|
62
62
|
## Using Tailwind CSS
|
63
63
|
|
64
|
-
[Tailwind CSS](https://tailwindcss.com/) is a CSS framework and design system based on Utility Class, which can quickly add common styles to components, and support flexible extension of theme styles. To use [Tailwind CSS](https://tailwindcss.com/) in
|
64
|
+
[Tailwind CSS](https://tailwindcss.com/) is a CSS framework and design system based on Utility Class, which can quickly add common styles to components, and support flexible extension of theme styles. To use [Tailwind CSS](https://tailwindcss.com/) in Modern.js, simply run `pnpm run new` in the project root directory and enable it.
|
65
65
|
|
66
|
-
|
66
|
+
Follow the steps below to make a selection:
|
67
67
|
|
68
68
|
```bash
|
69
69
|
? Action: Enable features
|
70
70
|
? Enable features: Enable Tailwind CSS
|
71
71
|
```
|
72
72
|
|
73
|
-
|
73
|
+
Register the Tailwind plugin in `modern.config.ts`:
|
74
|
+
|
75
|
+
```ts title="modern.config.ts"
|
76
|
+
import tailwindcssPlugin from '@modern-js/plugin-tailwindcss';
|
77
|
+
|
78
|
+
export default defineConfig({
|
79
|
+
plugins: [..., tailwindcssPlugin()],
|
80
|
+
});
|
81
|
+
```
|
82
|
+
|
83
|
+
To use, add the following code to the root component (such as `src/App.jsx`) of the entry:
|
74
84
|
|
75
85
|
```js
|
76
86
|
import 'tailwindcss/base.css';
|
@@ -78,7 +88,7 @@ import 'tailwindcss/components.css';
|
|
78
88
|
import 'tailwindcss/utilities.css';
|
79
89
|
```
|
80
90
|
|
81
|
-
|
91
|
+
Then you can use the Utility Class provided by Tailwind CSS in each component:
|
82
92
|
|
83
93
|
```tsx
|
84
94
|
const App = () => (
|
@@ -88,14 +98,14 @@ const App = () => (
|
|
88
98
|
);
|
89
99
|
```
|
90
100
|
|
91
|
-
:::info Additional
|
92
|
-
|
101
|
+
:::info Additional Information
|
102
|
+
Depending on your needs, you can selectively import the CSS files provided by Tailwind CSS. Since using `@tailwind` is equivalent to directly importing CSS files, you can refer to the comments in the [`@tailwind` usage](https://tailwindcss.com/docs/functions-and-directives#tailwind) documentation for the purpose of the CSS files provided by Tailwind CSS.
|
93
103
|
|
94
104
|
:::
|
95
105
|
|
96
|
-
### Tailwind CSS
|
106
|
+
### Tailwind CSS Version
|
97
107
|
|
98
|
-
Modern.js supports both Tailwind CSS v2 and v3
|
108
|
+
Modern.js supports both Tailwind CSS v2 and v3 versions, and the framework will recognize the version of the `tailwindcss` dependency in the project `package.json` file and enable the corresponding configuration. By default, we will install Tailwind CSS v3 version for you.
|
99
109
|
|
100
110
|
If your project is still using Tailwind CSS v2, we recommend that you upgrade to v3 to support JIT and other capabilities. For the differences between Tailwind CSS v2 and v3 versions, please refer to the following articles:
|
101
111
|
|
@@ -104,16 +114,16 @@ If your project is still using Tailwind CSS v2, we recommend that you upgrade to
|
|
104
114
|
|
105
115
|
### Browser Compatibility
|
106
116
|
|
107
|
-
|
117
|
+
Tailwind CSS v2 and v3 do not support the IE 11 browser, please refer to:
|
108
118
|
|
109
119
|
- [Tailwind CSS v3 - Browser Support](https://tailwindcss.com/docs/browser-support).
|
110
120
|
- [Tailwind CSS v2 - Browser Support](https://v2.tailwindcss.com/docs/browser-support)
|
111
121
|
|
112
|
-
If you use Tailwind CSS on IE 11 browser, some styles may not be available, please
|
122
|
+
If you use Tailwind CSS on IE 11 browser, some styles may not be available, please use it with caution.
|
113
123
|
|
114
|
-
### Theme
|
124
|
+
### Theme Configuration
|
115
125
|
|
116
|
-
When you need to customize the [theme](https://tailwindcss.com/docs/theme) configuration of Tailwind CSS, you can modify it in the
|
126
|
+
When you need to customize the [theme](https://tailwindcss.com/docs/theme) configuration of Tailwind CSS, you can modify it in the [`source.designSystem`](/configure/app/source/design-system) configuration. For example, adding a `primary` color theme:
|
117
127
|
|
118
128
|
```ts title="modern.config.ts"
|
119
129
|
export default defineConfig({
|
@@ -129,7 +139,7 @@ export default defineConfig({
|
|
129
139
|
});
|
130
140
|
```
|
131
141
|
|
132
|
-
When you need special
|
142
|
+
When you need to make other special configurations to Tailwind CSS besides [theme](https://tailwindcss.com/docs/theme), you can configure them in [`tools.tailwindcss`](/configure/app/tools/tailwindcss), such as setting `variants`:
|
133
143
|
|
134
144
|
```ts title="modern.config.ts"
|
135
145
|
export default defineConfig({
|
@@ -145,4 +155,4 @@ export default defineConfig({
|
|
145
155
|
});
|
146
156
|
```
|
147
157
|
|
148
|
-
> When
|
158
|
+
> When you configure Tailwind CSS for your project, the combination of [source.designSystem](/configure/app/source/design-system) and [tools.tailwindcss](/configure/app/tools/tailwindcss) configurations is equivalent to configuring a `tailwindcss.config.js` file separately. [source.designSystem](/configure/app/source/design-system) is equivalent to the Tailwind CSS [theme](https://v2.tailwindcss.com/docs/configuration#theme) configuration.
|
@@ -1,27 +1,27 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Data Fetching
|
3
3
|
sidebar_position: 3
|
4
4
|
---
|
5
|
-
#
|
5
|
+
# Data Fetching
|
6
6
|
|
7
|
-
Modern.js provides out
|
7
|
+
Modern.js provides out-of-the-box data fetching capabilities, allowing developers to develop in an isomorphic way in both client-side and server-side code.
|
8
8
|
|
9
|
-
It should be noted that these APIs do not help applications
|
9
|
+
It should be noted that these APIs do not help applications initiate requests, but rather help developers better manage data and improve project performance.
|
10
10
|
|
11
|
-
## Data
|
11
|
+
## Data Loader (Recommended)
|
12
12
|
|
13
|
-
Modern.js recommends
|
13
|
+
Modern.js recommends using [conventional routing](/guides/basic-features/routes) for routing management. Through Modern.js's [conventional (nested) routing](/guides/basic-features/routes#conventional-routing), each routing component (`layout.ts` or `page.ts`) can have a same-named `loader` file. The `loader` file needs to export a function that will be executed before the component is rendered to provide data for the routing component.
|
14
14
|
|
15
15
|
:::info
|
16
|
-
Modern.js v1 supports
|
16
|
+
Modern.js v1 supports fetching data via [useLoader](/guides/basic-features/data-fetch.html#useloader-(old-version)), which is no longer the recommended usage. We do not recommend mixing the two except during the migration process.
|
17
17
|
|
18
18
|
:::
|
19
19
|
|
20
|
-
### Basic
|
20
|
+
### Basic Example
|
21
21
|
|
22
|
-
|
22
|
+
Routing components such as `layout.ts` or `page.ts` can define a same-named `loader` file. The function exported by the `loader` file provides the data required by the component, and then the data is obtained in the routing component through the `useLoaderData` function, as shown in the following example:
|
23
23
|
|
24
|
-
```
|
24
|
+
```bash
|
25
25
|
.
|
26
26
|
└── routes
|
27
27
|
├── layout.tsx
|
@@ -56,28 +56,28 @@ export default async (): Promise<ProfileData> => {
|
|
56
56
|
```
|
57
57
|
|
58
58
|
:::caution
|
59
|
-
Here
|
59
|
+
Here, routing components and `loader` files share a type, so the `import type` syntax should be used.
|
60
60
|
|
61
61
|
:::
|
62
62
|
|
63
|
-
In
|
63
|
+
In the CSR environment, the `loader` function is executed on the client and can use browser APIs (although it is not necessary and not recommended).
|
64
64
|
|
65
|
-
In
|
65
|
+
In the SSR environment, whether it is the first screen or client navigation, the `loader` function will only be executed on the server, and any Node.js API can be called here. Also, any dependencies and code used here will not be included in the client's bundle.
|
66
66
|
|
67
67
|
:::info
|
68
|
-
In
|
68
|
+
In future versions, Modern.js may support running the `loader` function on the server in the CSR environment to improve performance and security. Therefore, it is recommended to ensure that the `loader` function is as pure as possible and only used for data fetching scenarios.
|
69
69
|
|
70
70
|
:::
|
71
71
|
|
72
|
-
When navigating on the client
|
72
|
+
When navigating on the client based on Modern.js's [conventional routing](/guides/basic-features/routes), all `loader` functions will be executed in parallel (requested). That is, when accessing `/user/profile`, the loader functions under `/user` and `/user/profile` will be executed in parallel (requested) to improve the performance of the client.
|
73
73
|
|
74
|
-
### `loader`
|
74
|
+
### The `loader` Function
|
75
75
|
|
76
76
|
The `loader` function has two input parameters:
|
77
77
|
|
78
|
-
|
78
|
+
#### `params`
|
79
79
|
|
80
|
-
When
|
80
|
+
When the route file is accessed through `[]`, it is used as [dynamic routing](/guides/basic-features/routes#dynamic-routing), and the dynamic routing fragment is passed as a parameter to the `loader` function:
|
81
81
|
|
82
82
|
```tsx
|
83
83
|
// routes/user/[id]/page.loader.tsx
|
@@ -90,13 +90,13 @@ export default async ({ params }: LoaderFunctionArgs) => {
|
|
90
90
|
};
|
91
91
|
```
|
92
92
|
|
93
|
-
When accessing `/user/123`, the
|
93
|
+
When accessing `/user/123`, the parameter of the `loader` function is `{ params: { id: '123' } }`.
|
94
94
|
|
95
95
|
#### `request`
|
96
96
|
|
97
97
|
`request` is a [Fetch Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance.
|
98
98
|
|
99
|
-
A common usage scenario is to
|
99
|
+
A common usage scenario is to get query parameters through `request`:
|
100
100
|
|
101
101
|
```tsx
|
102
102
|
// routes/user/[id]/page.loader.ts
|
@@ -109,9 +109,9 @@ export default async ({ request }: LoaderFunctionArgs) => {
|
|
109
109
|
};
|
110
110
|
```
|
111
111
|
|
112
|
-
#### Return
|
112
|
+
#### Return Value
|
113
113
|
|
114
|
-
The return value of the `loader` function can be
|
114
|
+
The return value of the `loader` function can be any serializable content or a [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) instance:
|
115
115
|
|
116
116
|
```tsx
|
117
117
|
const loader = async (): Promise<ProfileData> => {
|
@@ -122,7 +122,7 @@ const loader = async (): Promise<ProfileData> => {
|
|
122
122
|
export default loader;
|
123
123
|
```
|
124
124
|
|
125
|
-
By default, the
|
125
|
+
By default, the `Content-type` of the response returned by the `loader` is `application/json`, and the `status` is 200. You can customize the `Response` to set it:
|
126
126
|
|
127
127
|
```tsx
|
128
128
|
const loader = async (): Promise<ProfileData> => {
|
@@ -138,7 +138,7 @@ const loader = async (): Promise<ProfileData> => {
|
|
138
138
|
|
139
139
|
### Request API
|
140
140
|
|
141
|
-
Modern.js
|
141
|
+
Modern.js provides a polyfill for the `fetch` API to make requests. This API is consistent with the browser's `fetch` API, but can also be used to make requests on the server. This means that whether it is CSR or SSR, a unified `fetch` API can be used to get data:
|
142
142
|
|
143
143
|
```tsx
|
144
144
|
function loader() {
|
@@ -146,9 +146,9 @@ function loader() {
|
|
146
146
|
}
|
147
147
|
```
|
148
148
|
|
149
|
-
### Error
|
149
|
+
### Error Handling
|
150
150
|
|
151
|
-
In the `loader` function, errors can be handled by `
|
151
|
+
In the `loader` function, errors can be handled by throwing an `error` or a `response`. When an error is thrown in the `loader` function, Modern.js will stop executing the code in the current `loader` and switch the front-end UI to the defined [`ErrorBoundary`](/guides/basic-features/routes#error-handling) component:
|
152
152
|
|
153
153
|
```tsx
|
154
154
|
// routes/user/profile/page.loader.tsx
|
@@ -175,9 +175,9 @@ const ErrorBoundary = () => {
|
|
175
175
|
export default ErrorBoundary;
|
176
176
|
```
|
177
177
|
|
178
|
-
### Get data from
|
178
|
+
### Get data from parent component
|
179
179
|
|
180
|
-
In many cases,
|
180
|
+
In many cases, child components need to access data in the parent component `loader`. You can easily get the data from the parent component using `useRouteLoaderData`:
|
181
181
|
|
182
182
|
```tsx
|
183
183
|
// routes/user/profile/page.tsx
|
@@ -195,9 +195,9 @@ export default function UserLayout() {
|
|
195
195
|
}
|
196
196
|
```
|
197
197
|
|
198
|
-
`
|
198
|
+
The `useRouteLoaderData` function accepts a parameter `routeId`. When using [conventional routing](/guides/basic-features/routes), Modern.js will automatically generate the `routeId` for you. The value of `routeId` is the path of the corresponding component relative to `src/routes`. For example, in the above example, if the child component wants to get the data returned by the loader in `routes/user/layout.tsx`, the value of `routeId` is `user/layout`.
|
199
199
|
|
200
|
-
In a multi-entry (MPA) scenario, the value of `routeId` needs to
|
200
|
+
In a multi-entry (MPA) scenario, the value of `routeId` needs to include the name of the corresponding entry. Unless specified, the entry name is generally the name of the entry directory. For example, in the following directory structure:
|
201
201
|
|
202
202
|
```bash
|
203
203
|
.
|
@@ -210,17 +210,16 @@ In a multi-entry (MPA) scenario, the value of `routeId` needs to be added to the
|
|
210
210
|
└── layout.tsx
|
211
211
|
```
|
212
212
|
|
213
|
-
If you want to get the data returned by the loader in `entry1/routes/layout.tsx`, the value of `routeId` is `entry1_layout`.
|
213
|
+
If you want to get the data returned by the `loader` in `entry1/routes/layout.tsx`, the value of `routeId` is `entry1_layout`.
|
214
214
|
|
215
215
|
### (WIP)Loading UI
|
216
216
|
|
217
217
|
:::info
|
218
|
-
This feature is currently experimental and the API may
|
219
|
-
Currently
|
220
|
-
|
218
|
+
This feature is currently experimental and the API may change in the future.
|
219
|
+
Currently only supports CSR, please look forward to Streaming SSR.
|
221
220
|
:::
|
222
221
|
|
223
|
-
|
222
|
+
Create `user/layout.loader.ts` and add the following code:
|
224
223
|
|
225
224
|
```ts title="routes/user/layout.loader.ts"
|
226
225
|
import { defer } from "@modern-js/runtime/router"
|
@@ -240,7 +239,7 @@ defer({
|
|
240
239
|
export default loader;
|
241
240
|
```
|
242
241
|
|
243
|
-
Add the following code
|
242
|
+
Add the following code in `user/layout.tsx`:
|
244
243
|
|
245
244
|
```tsx title="routes/user/layout.tsx"
|
246
245
|
import {
|
@@ -272,19 +271,17 @@ export default function UserLayout() {
|
|
272
271
|
```
|
273
272
|
|
274
273
|
:::info
|
275
|
-
For
|
276
|
-
|
277
|
-
For specific usage of the defer function, see[defer](https://reactrouter.com/en/main/guides/deferred)
|
274
|
+
For details on how to use the Await component, please refer to [Await](https://reactrouter.com/en/main/components/await).
|
278
275
|
|
276
|
+
For details on how to use defer, please refer to [defer](https://reactrouter.com/en/main/guides/deferred).
|
279
277
|
:::
|
280
278
|
|
281
|
-
###
|
279
|
+
### Incorrect usage
|
282
280
|
|
283
|
-
1.
|
281
|
+
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).
|
284
282
|
|
285
283
|
:::warning
|
286
|
-
|
287
|
-
|
284
|
+
Currently, there is no such restriction under CSR, but we strongly recommend that you follow this restriction, and we may also add this restriction under CSR in the future.
|
288
285
|
:::
|
289
286
|
|
290
287
|
```ts
|
@@ -297,7 +294,7 @@ export default () => {
|
|
297
294
|
};
|
298
295
|
```
|
299
296
|
|
300
|
-
2. Modern.js will call the `loader` function for you, you
|
297
|
+
2. Modern.js will call the `loader` function for you, so you should not call the `loader` function yourself:
|
301
298
|
|
302
299
|
```tsx
|
303
300
|
// This won't work!
|
@@ -312,7 +309,7 @@ export default function RouteComp() {
|
|
312
309
|
}
|
313
310
|
```
|
314
311
|
|
315
|
-
3. You
|
312
|
+
3. You should not import the loader file from the route component, and you should also avoid importing variables from the route component into the loader file. If you need to share types, you should use `import type`.
|
316
313
|
|
317
314
|
```ts
|
318
315
|
// Not allowed
|
@@ -339,23 +336,22 @@ export default async (): Promise<ProfileData> => {
|
|
339
336
|
};
|
340
337
|
```
|
341
338
|
|
342
|
-
4. When
|
339
|
+
4. When running on the server, the `loader` function will be packaged into a unified bundle, so we do not recommend using `__filename` and `__dirname` in server-side code.
|
343
340
|
|
344
341
|
### FAQ
|
345
342
|
|
346
|
-
1. Relationship between loader and BFF functions
|
343
|
+
1. Relationship between `loader` and BFF functions
|
347
344
|
|
348
|
-
In
|
345
|
+
In CSR projects, `loader` is executed on the client side, and the BFF function can be called directly in the `loader` to make interface requests.
|
349
346
|
|
350
|
-
In
|
347
|
+
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.
|
351
348
|
|
352
|
-
## useLoader(
|
349
|
+
## useLoader (old version)
|
353
350
|
|
354
|
-
**`useLoader`** is
|
351
|
+
**`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.
|
355
352
|
|
356
353
|
:::tip
|
357
|
-
|
358
|
-
|
354
|
+
It is not necessary to use `useLoader` to fetch data in CSR projects.
|
359
355
|
:::
|
360
356
|
|
361
357
|
Here is the simplest example:
|
@@ -378,9 +374,9 @@ export default () => {
|
|
378
374
|
};
|
379
375
|
```
|
380
376
|
|
381
|
-
After the above code
|
377
|
+
After running the above code, when you access the page, you can see that logs are output to the terminal, but not printed in the browser console.
|
382
378
|
|
383
|
-
This is because Modern.js
|
379
|
+
This is because Modern.js collects the data returned by `useLoader` during server-side rendering and injects it into the corresponding HTML. If the SSR rendering is successful, you can see the following code snippet in the HTML:
|
384
380
|
|
385
381
|
```html
|
386
382
|
<script>
|
@@ -388,25 +384,16 @@ This is because Modern.js server-side rendering, the data returned by the `useLo
|
|
388
384
|
</script>
|
389
385
|
```
|
390
386
|
|
391
|
-
|
387
|
+
This global variable is used to record data, and during the browser-side rendering process, this data is used first. If the data does not exist, the `useLoader` function will be executed again.
|
392
388
|
|
393
389
|
:::note
|
394
|
-
During the build phase, Modern.js will automatically generate a Loader ID for each `useLoader` and inject it into the
|
395
|
-
|
390
|
+
During the build phase, Modern.js will automatically generate a Loader ID for each `useLoader` and inject it into the SSR and CSR JS Bundles to associate the Loader with the data.
|
396
391
|
:::
|
397
392
|
|
398
|
-
Compared
|
393
|
+
Compared to `getServerSideProps` in Next.js, which fetches data before rendering, using `useLoader` allows you to get data required for local UI in the component without passing data through multiple layers. Similarly, you don't have to add redundant logic to the outermost data acquisition function because different routes require different data requests. Of course, `useLoader` also has some issues, such as difficulties in server-side code tree shaking and the need for an additional pre-rendering step on the server.
|
399
394
|
|
400
|
-
|
395
|
+
In the new version of Modern.js, a new Loader solution has been designed. The new solution solves these problems and can be optimized for page performance in conjunction with [conventional routing](/guides/basic-features/routes).
|
401
396
|
|
402
397
|
:::note
|
403
|
-
|
404
|
-
|
405
|
-
:::
|
406
|
-
|
407
|
-
## Route Loader
|
408
|
-
|
409
|
-
:::note
|
410
|
-
Stay tuned.
|
411
|
-
|
398
|
+
For detailed API information, see [useLoader](/apis/app/runtime/core/use-loader).
|
412
399
|
:::
|