@modern-js/main-doc 2.67.4 → 2.67.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/en/configure/app/plugins.mdx +13 -33
- package/docs/en/configure/app/runtime/master-app.mdx +1 -5
- package/docs/en/configure/app/runtime/plugins.mdx +58 -0
- package/docs/en/configure/app/usage.mdx +1 -1
- package/docs/en/guides/advanced-features/_meta.json +1 -0
- package/docs/en/guides/advanced-features/bff.mdx +1 -1
- package/docs/en/guides/advanced-features/compatibility.mdx +1 -1
- package/docs/en/guides/advanced-features/custom-server.mdx +218 -0
- package/docs/en/guides/advanced-features/page-performance/inline-assets.mdx +2 -0
- package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
- package/docs/en/guides/advanced-features/web-server.mdx +174 -1
- package/docs/en/guides/basic-features/data/data-fetch.mdx +2 -1
- package/docs/en/guides/basic-features/html.mdx +3 -3
- package/docs/en/guides/basic-features/render/ssr.mdx +2 -2
- package/docs/en/guides/concept/entries.mdx +1 -1
- package/docs/en/plugin/cli-plugins/api.mdx +6 -0
- package/docs/en/plugin/runtime-plugins/api.mdx +37 -12
- package/docs/en/tutorials/first-app/c05-loader.mdx +1 -1
- package/docs/zh/configure/app/plugins.mdx +3 -24
- package/docs/zh/configure/app/runtime/master-app.mdx +1 -5
- package/docs/zh/configure/app/runtime/plugins.mdx +58 -0
- package/docs/zh/configure/app/usage.mdx +1 -1
- package/docs/zh/guides/advanced-features/_meta.json +1 -0
- package/docs/zh/guides/advanced-features/custom-server.mdx +216 -0
- package/docs/zh/guides/advanced-features/web-server.mdx +174 -1
- package/docs/zh/plugin/cli-plugins/api.mdx +6 -0
- package/docs/zh/plugin/runtime-plugins/api.mdx +37 -12
- package/package.json +2 -2
- package/src/i18n/index.ts +1 -1
@@ -1,47 +1,27 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 9
|
3
|
-
---
|
4
|
-
|
5
1
|
# plugins
|
6
2
|
|
7
3
|
- **Type:** `CliPlugin[]`
|
8
4
|
- **Default:** `[]`
|
9
5
|
|
10
|
-
Used to configure custom Modern.js framework plugins.
|
11
|
-
|
12
|
-
Refer to [How to Develop Plugins](/plugin/plugin-system) for how to write custom plugins.
|
6
|
+
Used to configure custom Modern.js framework CLI plugins. For information on how to create custom CLI plugins, please refer to [How to Write CLI Plugins](/plugin/introduction.html#cli-plugins).
|
13
7
|
|
14
8
|
## Note
|
15
9
|
|
16
|
-
This option is
|
17
|
-
|
18
|
-
- Use [builderPlugins](/configure/app/builder-plugins) to configure Rsbuild plugins.
|
19
|
-
- Use [tools.bundlerChain](/configure/app/tools/bundler-chain) to configure Rspack or webpack plugins.
|
20
|
-
- Use [tools.babel](/configure/app/tools/babel) to configure Babel plugins.
|
21
|
-
|
22
|
-
## Plugin types
|
23
|
-
|
24
|
-
Modern.js has three types of plugins:
|
25
|
-
|
26
|
-
- `CLI plugins`, applicable to local development, compilation and construction stages, can extend various capabilities in the command line and compilation stages.
|
27
|
-
- `Server plugins`, applicable to the server.
|
28
|
-
- `Runtime plugins`, applicable to the front-end runtime.
|
29
|
-
|
30
|
-
Currently, Modern.js has opened up the ability to customize CLI plugins, and Server plugins and Runtime plugins will be opened up later.
|
31
|
-
|
32
|
-
## Plugin execution order
|
10
|
+
This option is **specifically for configuring framework CLI plugins**. If you need to configure other types of plugins, use the appropriate configuration method:
|
33
11
|
|
34
|
-
|
12
|
+
- Use [builderPlugins](/configure/app/builder-plugins) for Rsbuild plugins.
|
13
|
+
- Use [tools.bundlerChain](/configure/app/tools/bundler-chain) for Rspack or webpack plugins.
|
14
|
+
- Use [tools.babel](/configure/app/tools/babel) for Babel plugins.
|
15
|
+
- Use the [plugins field in runtime config](/configure/app/runtime/plugins) for framework Runtime plugins.
|
35
16
|
|
36
|
-
When the plugin sets options that control the order, such as `pre` and `post`, the execution order will be adjusted based on the declared fields. Refer to [Plugins Structure](/plugin/plugin-system) for more information.
|
37
17
|
|
38
|
-
##
|
18
|
+
## Examples
|
39
19
|
|
40
|
-
|
20
|
+
Below are examples of using CLI plugins:
|
41
21
|
|
42
|
-
###
|
22
|
+
### Using plugins from npm
|
43
23
|
|
44
|
-
To use plugins from npm registry,
|
24
|
+
To use plugins from the npm registry, first install the plugins and then import them in your configuration:
|
45
25
|
|
46
26
|
```ts title="modern.config.ts"
|
47
27
|
import { myPlugin } from 'my-plugin';
|
@@ -51,9 +31,9 @@ export default defineConfig({
|
|
51
31
|
});
|
52
32
|
```
|
53
33
|
|
54
|
-
###
|
34
|
+
### Using local plugins
|
55
35
|
|
56
|
-
To use local
|
36
|
+
To use plugins from your local repository, import them directly using a relative path:
|
57
37
|
|
58
38
|
```ts title="modern.config.ts"
|
59
39
|
import { myPlugin } from './config/plugin/myPlugin';
|
@@ -65,7 +45,7 @@ export default defineConfig({
|
|
65
45
|
|
66
46
|
### Plugin configuration
|
67
47
|
|
68
|
-
If
|
48
|
+
If a plugin provides custom configuration options, pass them as parameters to the plugin function:
|
69
49
|
|
70
50
|
```ts title="modern.config.ts"
|
71
51
|
import { myPlugin } from 'my-plugin';
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# plugins
|
2
|
+
|
3
|
+
- **Type:** `RuntimePlugin[]`
|
4
|
+
- **Default:** `[]`
|
5
|
+
|
6
|
+
Used to configure custom Modern.js Runtime plugins. For details on how to create custom Runtime plugins, please refer to [How to Write Runtime Plugins](/plugin/introduction#runtime-plugins).
|
7
|
+
|
8
|
+
:::info
|
9
|
+
|
10
|
+
Runtime plugins must be configured in the `plugins` array within the `src/modern.runtime.ts` file.
|
11
|
+
|
12
|
+
:::
|
13
|
+
|
14
|
+
## Examples
|
15
|
+
|
16
|
+
Here are examples demonstrating how to use Runtime plugins:
|
17
|
+
|
18
|
+
### Using plugins from npm packages
|
19
|
+
|
20
|
+
To use plugins published on npm, first install them via your package manager, then import them into your configuration.
|
21
|
+
|
22
|
+
```ts title="src/modern.runtime.ts"
|
23
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
24
|
+
import { myPlugin } from 'my-plugin';
|
25
|
+
|
26
|
+
export default defineRuntimeConfig({
|
27
|
+
plugins: [myPlugin()],
|
28
|
+
});
|
29
|
+
```
|
30
|
+
|
31
|
+
### Using local plugins
|
32
|
+
|
33
|
+
To use plugins from your local codebase, import them directly using relative paths.
|
34
|
+
|
35
|
+
```ts title="src/modern.runtime.ts"
|
36
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
37
|
+
import { myPlugin } from './config/plugin/myPlugin';
|
38
|
+
|
39
|
+
export default defineRuntimeConfig({
|
40
|
+
plugins: [myPlugin()],
|
41
|
+
});
|
42
|
+
```
|
43
|
+
|
44
|
+
### Plugin configuration
|
45
|
+
|
46
|
+
If a plugin supports custom configuration options, you can provide them as arguments to the plugin function.
|
47
|
+
|
48
|
+
```ts title="src/modern.runtime.ts"
|
49
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
50
|
+
import { myPlugin } from './config/plugin/myPlugin';
|
51
|
+
|
52
|
+
export default defineRuntimeConfig({
|
53
|
+
plugins: [myPlugin({
|
54
|
+
foo: 1,
|
55
|
+
bar: 2,
|
56
|
+
})],
|
57
|
+
});
|
58
|
+
```
|
@@ -13,7 +13,7 @@ Modern.js does not support configuring the same configuration item in both `pack
|
|
13
13
|
|
14
14
|
**Runtime configuration** can be configured in the `src/modern.runtime.(ts|js|mjs)` file.
|
15
15
|
|
16
|
-
**Server Runtime configuration** can be configured in the `modern.server
|
16
|
+
**Server Runtime configuration** can be configured in the `server/modern.server.(ts|js|mjs)` file.
|
17
17
|
|
18
18
|
## Compile Configuration
|
19
19
|
|
@@ -6,7 +6,7 @@ title: BFF
|
|
6
6
|
|
7
7
|
BFF (Backends for Frontends) is an architectural pattern primarily used to address issues of data aggregation in front-end and back-end collaboration. Under the BFF architecture, front-end applications do not communicate directly with backend services. Instead, they interact with backend services through a dedicated BFF middleware layer, custom-made for the front end.
|
8
8
|
|
9
|
-
The main problems it to solve include:
|
9
|
+
The main problems it tries to solve include:
|
10
10
|
|
11
11
|
- Aggregation, mapping, clipping, and proxying of lower-level APIs according to their own business needs.
|
12
12
|
- Cache data for some specific scenarios to improve performance and thus improve user experience.
|
@@ -26,7 +26,7 @@ Please refer to [Rsbuild - Browserslist](https://rsbuild.dev/guide/advanced/brow
|
|
26
26
|
|
27
27
|
### Polyfill At Compile
|
28
28
|
|
29
|
-
Modern.js defaults to importing corresponding polyfill code from [core-js]
|
29
|
+
Modern.js defaults to importing corresponding polyfill code from [core-js](https://github.com/zloirock/core-js) during compilation.
|
30
30
|
|
31
31
|
By default, the required Polyfill code will be introduced according to the settings of the Browserslist, so there is no need to worry about the Polyfill problem of the project source code and third-party dependencies, but because it contains some Polyfill code that is not used, the final bundle size may be increased.
|
32
32
|
|
@@ -0,0 +1,218 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 16
|
3
|
+
---
|
4
|
+
|
5
|
+
# Custom Server
|
6
|
+
|
7
|
+
Modern.js encapsulates most server-side capabilities required by projects, typically eliminating the need for server-side development. However, in certain scenarios such as user authentication, request preprocessing, or adding page skeletons, custom server-side logic may still be necessary.
|
8
|
+
|
9
|
+
## Custom Server Capabilities
|
10
|
+
|
11
|
+
Create the `server/modern.server.ts` file in the project directory, and you can add the following configurations to extend the Server:
|
12
|
+
- **Middleware**
|
13
|
+
- **Render Middleware**
|
14
|
+
- **Server Plugin**
|
15
|
+
|
16
|
+
In the **Plugin**, you can define **Middleware** and **RenderMiddleware**. The middleware loading process is illustrated in the following diagram:
|
17
|
+
|
18
|
+
<img
|
19
|
+
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/10eh7nuhpenuhog/server-md-wf.png"
|
20
|
+
style={{ width: '100%', maxWidth: '540px' }}
|
21
|
+
/>
|
22
|
+
|
23
|
+
### Basic Configuration
|
24
|
+
|
25
|
+
```ts title="server/modern.server.ts"
|
26
|
+
import { defineServerConfig } from '@modern-js/server-runtime';
|
27
|
+
|
28
|
+
export default defineServerConfig({
|
29
|
+
middlewares: [],
|
30
|
+
renderMiddlewares: [],
|
31
|
+
plugins: [],
|
32
|
+
});
|
33
|
+
```
|
34
|
+
|
35
|
+
|
36
|
+
### Type Definition
|
37
|
+
|
38
|
+
`defineServerConfig` type definition is as follows:
|
39
|
+
|
40
|
+
```ts
|
41
|
+
import type { MiddlewareHandler } from 'hono';
|
42
|
+
|
43
|
+
type MiddlewareOrder = 'pre' | 'post' | 'default';
|
44
|
+
type MiddlewareObj = {
|
45
|
+
name: string;
|
46
|
+
path?: string;
|
47
|
+
method?: 'options' | 'get' | 'post' | 'put' | 'delete' | 'patch' | 'all';
|
48
|
+
handler: MiddlewareHandler | MiddlewareHandler[];
|
49
|
+
before?: Array<MiddlewareObj['name']>;
|
50
|
+
order?: MiddlewareOrder;
|
51
|
+
};
|
52
|
+
type ServerConfig = {
|
53
|
+
middlewares?: MiddlewareObj[];
|
54
|
+
renderMiddlewares?: MiddlewareObj[];
|
55
|
+
plugins?: (ServerPlugin | ServerPluginLegacy)[];
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
|
60
|
+
### Middleware
|
61
|
+
|
62
|
+
Middleware supports executing custom logic before and after the **request handling** and **page routing** processes in Modern.js services.
|
63
|
+
That is, if custom logic needs to handle both API routes and affect page routes, then Middleware is the obvious choice. If you only need to handle BFF API routes, this can be achieved by configuring the `path` to the BFF's `prefix`.
|
64
|
+
|
65
|
+
:::note
|
66
|
+
In the BFF scenario, BFF routing will only go through Middleware when the [runtime framework](/guides/advanced-features/bff/frameworks.html) is Hono.
|
67
|
+
:::
|
68
|
+
|
69
|
+
#### Using Posture
|
70
|
+
|
71
|
+
```ts title="server/modern.server.ts"
|
72
|
+
import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
|
73
|
+
import { getMonitors } from '@modern-js/runtime';
|
74
|
+
|
75
|
+
export const handler: MiddlewareHandler = async (c, next) => {
|
76
|
+
const monitors = getMonitors();
|
77
|
+
const start = Date.now();
|
78
|
+
|
79
|
+
await next();
|
80
|
+
|
81
|
+
const end = Date.now();
|
82
|
+
// Report Duration
|
83
|
+
monitors.timing('request_timing', end - start);
|
84
|
+
};
|
85
|
+
|
86
|
+
export default defineServerConfig({
|
87
|
+
middlewares: [
|
88
|
+
{
|
89
|
+
name: 'request-timing',
|
90
|
+
handler,
|
91
|
+
},
|
92
|
+
],
|
93
|
+
});
|
94
|
+
```
|
95
|
+
|
96
|
+
:::warning
|
97
|
+
You must execute the `next` function to proceed with the subsequent Middleware.
|
98
|
+
:::
|
99
|
+
|
100
|
+
|
101
|
+
### RenderMiddleware
|
102
|
+
|
103
|
+
If you only need to handle the logic before and after page rendering, modern.js also provides rendering middleware.
|
104
|
+
|
105
|
+
#### Using Posture
|
106
|
+
|
107
|
+
```ts title="server/modern.server.ts"
|
108
|
+
import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
|
109
|
+
|
110
|
+
// Inject render performance metrics
|
111
|
+
const renderTiming: MiddlewareHandler = async (c, next) => {
|
112
|
+
const start = Date.now();
|
113
|
+
|
114
|
+
await next();
|
115
|
+
|
116
|
+
const end = Date.now();
|
117
|
+
c.res.headers.set('server-timing', `render; dur=${end - start}`);
|
118
|
+
};
|
119
|
+
|
120
|
+
// Modify the Response Body
|
121
|
+
const modifyResBody: MiddlewareHandler = async (c, next) => {
|
122
|
+
await next();
|
123
|
+
|
124
|
+
const { res } = c;
|
125
|
+
const text = await res.text();
|
126
|
+
const newText = text.replace('<body>', '<body> <h3>bytedance</h3>');
|
127
|
+
|
128
|
+
c.res = c.body(newText, {
|
129
|
+
status: res.status,
|
130
|
+
headers: res.headers,
|
131
|
+
});
|
132
|
+
};
|
133
|
+
|
134
|
+
export default defineServerConfig({
|
135
|
+
renderMiddlewares: [
|
136
|
+
{
|
137
|
+
name: 'render-timing',
|
138
|
+
handler: renderTiming,
|
139
|
+
},
|
140
|
+
{
|
141
|
+
name: 'modify-res-body',
|
142
|
+
handler: modifyResBody,
|
143
|
+
},
|
144
|
+
],
|
145
|
+
});
|
146
|
+
```
|
147
|
+
|
148
|
+
|
149
|
+
### Plugin
|
150
|
+
|
151
|
+
Modern.js supports adding the aforementioned middleware and rendering middleware for the Server in custom plugins.
|
152
|
+
|
153
|
+
#### Using Posture
|
154
|
+
|
155
|
+
|
156
|
+
```ts title="server/plugins/server.ts"
|
157
|
+
import type { ServerPluginLegacy } from '@modern-js/server-runtime';
|
158
|
+
|
159
|
+
export default (): ServerPluginLegacy => ({
|
160
|
+
name: 'serverPlugin',
|
161
|
+
setup(api) {
|
162
|
+
return {
|
163
|
+
prepare(serverConfig) {
|
164
|
+
const { middlewares, renderMiddlewares } = api.useAppContext();
|
165
|
+
|
166
|
+
// Inject server-side data for page dataLoader consumption
|
167
|
+
middlewares?.push({
|
168
|
+
name: 'server-plugin-middleware',
|
169
|
+
handler: async (c, next) => {
|
170
|
+
c.set('message', 'hi modern.js');
|
171
|
+
await next();
|
172
|
+
// ...
|
173
|
+
},
|
174
|
+
});
|
175
|
+
|
176
|
+
// redirect
|
177
|
+
renderMiddlewares?.push({
|
178
|
+
name: 'server-plugin-render-middleware',
|
179
|
+
handler: async (c, next) => {
|
180
|
+
const user = getUser(c.req);
|
181
|
+
if (!user) {
|
182
|
+
return c.redirect('/login');
|
183
|
+
}
|
184
|
+
|
185
|
+
await next();
|
186
|
+
},
|
187
|
+
});
|
188
|
+
return serverConfig;
|
189
|
+
},
|
190
|
+
};
|
191
|
+
},
|
192
|
+
});
|
193
|
+
```
|
194
|
+
|
195
|
+
|
196
|
+
```ts title="server/modern.server.ts"
|
197
|
+
import { defineServerConfig } from '@modern-js/server-runtime';
|
198
|
+
import serverPlugin from './plugins/serverPlugin';
|
199
|
+
|
200
|
+
export default defineServerConfig({
|
201
|
+
plugins: [serverPlugin()],
|
202
|
+
});
|
203
|
+
```
|
204
|
+
|
205
|
+
|
206
|
+
```ts title="src/routes/page.data.ts"
|
207
|
+
import { useHonoContext } from '@modern-js/server-runtime';
|
208
|
+
import { defer } from '@modern-js/runtime/router';
|
209
|
+
|
210
|
+
export default () => {
|
211
|
+
const ctx = useHonoContext();
|
212
|
+
// Consuming Data Injected by the Server-Side
|
213
|
+
const message = ctx.get('message');
|
214
|
+
|
215
|
+
// ...
|
216
|
+
};
|
217
|
+
|
218
|
+
```
|
@@ -96,6 +96,8 @@ When you reference a static asset in your CSS file, you can also force the asset
|
|
96
96
|
:::tip Do you really need to exclude assets from inlining?
|
97
97
|
Excluding assets from inlining will increase the number of assets that the Web App needs to load. This will reduce the efficiency of loading assets in a weak network environment or in scenarios where HTTP2 is not enabled. Please use force no Inline with caution.
|
98
98
|
|
99
|
+
:::
|
100
|
+
|
99
101
|
## Inline JS files
|
100
102
|
|
101
103
|
In addition to inlining static assets into JS files, Modern.js also supports inlining JS files into HTML files.
|
@@ -4,7 +4,7 @@ sidebar_position: 13
|
|
4
4
|
|
5
5
|
# Bundle Size Optimization
|
6
6
|
|
7
|
-
Bundle size optimization is an important part
|
7
|
+
Bundle size optimization is an important part of optimizing your production environment because it directly affects the user experience. In this document, we will introduce some common bundle size optimization methods in Modern.js.
|
8
8
|
|
9
9
|
## Reduce duplicate dependencies
|
10
10
|
|
@@ -2,7 +2,11 @@
|
|
2
2
|
sidebar_position: 16
|
3
3
|
---
|
4
4
|
|
5
|
-
# Custom Web Server
|
5
|
+
# Custom Web Server (Not Recommended)
|
6
|
+
|
7
|
+
:::warning
|
8
|
+
Custom Web Server is compatible but no longer recommended. For extending Server capabilities, please refer to [Custom Server](/guides/advanced-features/custom-server.html). For migration guide, see [Migrate to the New Version of Custom Server](/guides/advanced-features/web-server.html#migrate-to-the-new-version-of-custom-server).
|
9
|
+
:::
|
6
10
|
|
7
11
|
Modern.js encapsulates most server-side capabilities required by projects, typically eliminating the need for server-side development. However, in certain scenarios such as user authentication, request preprocessing, or adding page skeletons, custom server-side logic may still be necessary.
|
8
12
|
|
@@ -96,3 +100,172 @@ Best practices when using Hooks:
|
|
96
100
|
:::info
|
97
101
|
For detailed API and more usage, see [Hook](/apis/app/runtime/web-server/hook).
|
98
102
|
:::
|
103
|
+
|
104
|
+
|
105
|
+
## Migrate to the New Version of Custom Server
|
106
|
+
|
107
|
+
### Migration Background
|
108
|
+
|
109
|
+
Modern.js Server is continuously evolving to provide more powerful features. We have optimized the definition and usage of middleware and Server plugins.
|
110
|
+
While the old custom Web Server approach is still compatible, we strongly recommend migrating according to this guide to fully leverage the advantages of the new version.
|
111
|
+
|
112
|
+
### Migration Steps
|
113
|
+
|
114
|
+
1. Upgrade Modern.js version to x.67.5 or above.
|
115
|
+
2. Configure middleware or plugins in `server/modern.server.ts` according to the new definition method.
|
116
|
+
3. Migrate the custom logic in `server/index.ts` to middleware or plugins, and update your code with reference to the differences between `Context` and `Next`.
|
117
|
+
|
118
|
+
### Context Differences
|
119
|
+
|
120
|
+
In the new version, the middleware handler type is Hono's `MiddlewareHandler`, meaning the `Context` type is `Hono Context`. The differences from the old custom Web Server's `Context` are as follows:
|
121
|
+
|
122
|
+
|
123
|
+
#### UnstableMiddleware
|
124
|
+
|
125
|
+
|
126
|
+
```ts
|
127
|
+
type Body = ReadableStream | ArrayBuffer | string | null;
|
128
|
+
|
129
|
+
type UnstableMiddlewareContext<
|
130
|
+
V extends Record<string, unknown> = Record<string, unknown>,
|
131
|
+
> = {
|
132
|
+
request: Request;
|
133
|
+
response: Response;
|
134
|
+
get: Get<V>;
|
135
|
+
set: Set<V>;
|
136
|
+
// Current Matched Routing Information
|
137
|
+
route: string;
|
138
|
+
header: (name: string, value: string, options?: { append?: boolean }) => void;
|
139
|
+
status: (code: number) => void;
|
140
|
+
redirect: (location: string, status?: number) => Response;
|
141
|
+
body: (data: Body, init?: ResponseInit) => Response;
|
142
|
+
html: (
|
143
|
+
data: string | Promise<string>,
|
144
|
+
init?: ResponseInit,
|
145
|
+
) => Response | Promise<Response>;
|
146
|
+
};
|
147
|
+
```
|
148
|
+
|
149
|
+
Differences between UnstableMiddleware Context and Hono Context:
|
150
|
+
|
151
|
+
| UnstableMiddleware | Hono | Description |
|
152
|
+
| :----------------------- | :---------------------------- | :------------------------------------------------------------------------ |
|
153
|
+
| `c.request` | `c.req.raw` | Refer to [HonoRequest raw](https://hono.dev/docs/api/request#raw) documentation |
|
154
|
+
| `c.response` | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
|
155
|
+
| `c.route` | `c.get('route')` | Get application context information. |
|
156
|
+
| `loaderContext.get` | `honoContext.get` | After injecting data using `c.set`, consume in dataLoader: the old version uses `loaderContext.get`, refer to the new version in [Plugin](/guides/advanced-features/custom-server.html#using-posture-2) example |
|
157
|
+
|
158
|
+
|
159
|
+
#### Middleware
|
160
|
+
|
161
|
+
```ts
|
162
|
+
type MiddlewareContext = {
|
163
|
+
response: {
|
164
|
+
set: (key: string, value: string) => void;
|
165
|
+
status: (code: number) => void;
|
166
|
+
getStatus: () => number;
|
167
|
+
cookies: {
|
168
|
+
set: (key: string, value: string, options?: any) => void;
|
169
|
+
clear: () => void;
|
170
|
+
};
|
171
|
+
raw: (
|
172
|
+
body: string,
|
173
|
+
{ status, headers }: { status: number; headers: Record<string, any> },
|
174
|
+
) => void;
|
175
|
+
locals: Record<string, any>;
|
176
|
+
};
|
177
|
+
request: {
|
178
|
+
url: string;
|
179
|
+
host: string;
|
180
|
+
pathname: string;
|
181
|
+
query: Record<string, any>;
|
182
|
+
cookie: string;
|
183
|
+
cookies: {
|
184
|
+
get: (key: string) => string;
|
185
|
+
};
|
186
|
+
headers: IncomingHttpHeaders;
|
187
|
+
};
|
188
|
+
source: {
|
189
|
+
req: IncomingMessage;
|
190
|
+
res: ServerResponse;
|
191
|
+
};
|
192
|
+
};
|
193
|
+
|
194
|
+
```
|
195
|
+
|
196
|
+
Differences between Middleware `Context` and Hono `Context`:
|
197
|
+
| UnstableMiddleware | Hono | Description |
|
198
|
+
| :----------------------- | :---------------------------- | :--------------------------------------------------------------------------- |
|
199
|
+
| `c.request.cookie` | `c.req.cookie()` | Refer to [Hono Cookie Helper](https://hono.dev/docs/helpers/cookie) documentation |
|
200
|
+
| `c.request.pathname` | `c.req.path` | Refer to [HonoRequest path](https://hono.dev/docs/api/request#path) documentation |
|
201
|
+
| `c.request.url` | - | Hono `c.req.url` provides the full request URL, calculate manually from URL |
|
202
|
+
| `c.request.host` | `c.req.header('Host')` | Obtain host through header |
|
203
|
+
| `c.request.query` | `c.req.query()` | Refer to [HonoRequest query](https://hono.dev/docs/api/request#query) documentation |
|
204
|
+
| `c.request.headers` | `c.req.header()` | Refer to [HonoRequest header](https://hono.dev/docs/api/request#header) documentation |
|
205
|
+
| `c.response.set` | `c.res.headers.set` | Example: `c.res.headers.set('custom-header', '1')` |
|
206
|
+
| `c.response.status` | `c.status` | Example: `c.status(201)` |
|
207
|
+
| `c.response.cookies` | `c.header` | Example: `c.header('Set-Cookie', 'user_id=123')` |
|
208
|
+
| `c.response.raw` | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
|
209
|
+
|
210
|
+
#### Hook
|
211
|
+
|
212
|
+
```ts
|
213
|
+
type HookContext = {
|
214
|
+
response: {
|
215
|
+
set: (key: string, value: string) => void;
|
216
|
+
status: (code: number) => void;
|
217
|
+
getStatus: () => number;
|
218
|
+
cookies: {
|
219
|
+
set: (key: string, value: string, options?: any) => void;
|
220
|
+
clear: () => void;
|
221
|
+
};
|
222
|
+
raw: (
|
223
|
+
body: string,
|
224
|
+
{ status, headers }: { status: number; headers: Record<string, any> },
|
225
|
+
) => void;
|
226
|
+
};
|
227
|
+
request: {
|
228
|
+
url: string;
|
229
|
+
host: string;
|
230
|
+
pathname: string;
|
231
|
+
query: Record<string, any>;
|
232
|
+
cookie: string;
|
233
|
+
cookies: {
|
234
|
+
get: (key: string) => string;
|
235
|
+
};
|
236
|
+
headers: IncomingHttpHeaders;
|
237
|
+
};
|
238
|
+
};
|
239
|
+
|
240
|
+
type AfterMatchContext = HookContext & {
|
241
|
+
router: {
|
242
|
+
redirect: (url: string, status: number) => void;
|
243
|
+
rewrite: (entry: string) => void;
|
244
|
+
};
|
245
|
+
};
|
246
|
+
|
247
|
+
type AfterRenderContext = {
|
248
|
+
template: {
|
249
|
+
get: () => string;
|
250
|
+
set: (html: string) => void;
|
251
|
+
prependHead: (fragment: string) => void;
|
252
|
+
appendHead: (fragment: string) => void;
|
253
|
+
prependBody: (fragment: string) => void;
|
254
|
+
appendBody: (fragment: string) => void;
|
255
|
+
};
|
256
|
+
};
|
257
|
+
```
|
258
|
+
|
259
|
+
Hook Context is mostly consistent with Middleware Context, so we need to pay extra attention to the additional parts of different Hooks.
|
260
|
+
|
261
|
+
| UnstableMiddleware | Hono | Description |
|
262
|
+
| :----------------------- | :---------------------------- | :------------------------------------ |
|
263
|
+
| `router.redirect` | `c.redirect` | Refer to [Hono Context redirect](https://hono.dev/docs/api/context#redirect) documentation |
|
264
|
+
| `router.rewrite` | - | No corresponding capability provided at the moment |
|
265
|
+
| template API | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
|
266
|
+
|
267
|
+
|
268
|
+
### Differences in Next API
|
269
|
+
|
270
|
+
In Middleware and Hooks, the render function executes even without invoking `next`.
|
271
|
+
In the new design, subsequent Middleware will only execute if the `next` function is invoked.
|
@@ -149,9 +149,10 @@ Having the `loader` function run only on the server in SSR applications brings s
|
|
149
149
|
- **Simplifies usage**: Guarantees consistent data-fetching methods in SSR applications, so developers don't have to distinguish between client and server code.
|
150
150
|
- **Reduces client bundle size**: Moves logic code and dependencies from the client to the server.
|
151
151
|
- **Improves maintainability**: Less direct influence of data logic on front-end UI and avoids issues of accidentally including server dependencies in the client bundle or vice versa.
|
152
|
+
|
152
153
|
:::
|
153
154
|
|
154
|
-
We recommend using the `fetch` API in `loader` functions to make requests.
|
155
|
+
We recommend using the `fetch` API in `loader` functions to make requests. Since `fetch` works similarly on the client and server, you can fetch data in a consistent manner whether in CSR or SSR:
|
155
156
|
|
156
157
|
```tsx
|
157
158
|
export async function loader() {
|
@@ -8,7 +8,7 @@ Modern.js provides **JSX syntax** and **HTML(EJS) syntax** to customize the HTML
|
|
8
8
|
|
9
9
|
## JSX Syntax
|
10
10
|
|
11
|
-
According to Modern.js conventions, you can create a `Document.[jt]sx` file under `src/` or the entry directory and default export a component
|
11
|
+
According to Modern.js conventions, you can create a `Document.[jt]sx` file under `src/` or the entry directory and default export a component. The rendering result of this component can be used as the HTML template of the entry.
|
12
12
|
|
13
13
|
For example, consider the following directory structure:
|
14
14
|
|
@@ -218,9 +218,9 @@ The implementation of custom HTML fragments is to merge the fragments with the b
|
|
218
218
|
|
219
219
|
:::
|
220
220
|
|
221
|
-
###
|
221
|
+
### Customize the entire HTML Template
|
222
222
|
|
223
|
-
In some cases, HTML fragments may
|
223
|
+
In some cases, HTML fragments may not offer enough control. Modern.js provides a fully customized way.
|
224
224
|
|
225
225
|
:::caution Note
|
226
226
|
It is generally not recommended to directly override the default HTML template, as some functional options may be lost. If it is truly necessary to customize the entire HTML template, it is recommended to modify based on the built-in template as needed.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Server-Side Rendering
|
2
2
|
|
3
|
-
Server-Side Rendering (SSR) involves rendering the HTML content of a webpage-side and then sending the fully-rendered page to the browser. The browser only needs to display the page without additional rendering.
|
3
|
+
Server-Side Rendering (SSR) involves rendering the HTML content of a webpage server-side and then sending the fully-rendered page to the browser. The browser only needs to display the page without additional rendering.
|
4
4
|
|
5
5
|
The main advantages are:
|
6
6
|
|
@@ -320,4 +320,4 @@ In this case, the `epicMiddleware` instance is created outside the component, an
|
|
320
320
|
|
321
321
|
This code does not cause issues on the client-side. However, in SSR, the Middleware instance remains non-disposable. Each time the component renders, calling `epicMiddleware.run(rootEpic)` adds new event bindings internally, causing the entire object to grow continuously, ultimately affecting application performance.
|
322
322
|
|
323
|
-
Such issues are not easily noticed in CSR. When transitioning from CSR to SSR, if you're unsure whether your application has such hidden pitfalls, consider stress testing the application.
|
323
|
+
Such issues are not easily noticed in CSR. When transitioning from CSR to SSR, if you're unsure whether your application has such hidden pitfalls, consider stress testing the application.
|
@@ -76,7 +76,7 @@ By default, Modern.js scans the files under `src/` before starting the project,
|
|
76
76
|
|
77
77
|
:::tip
|
78
78
|
|
79
|
-
- You can
|
79
|
+
- You can customize the recognition directory for page entries by using [source.entriesDir](/configure/app/source/entries-dir).
|
80
80
|
- If you need to customize the entry points, please refer to [Custom Entries](#custom-entries).
|
81
81
|
|
82
82
|
:::
|