@modern-js/main-doc 2.67.3 → 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.
Files changed (39) hide show
  1. package/docs/en/apis/app/hooks/src/routes.mdx +70 -0
  2. package/docs/en/configure/app/output/filename.mdx +8 -3
  3. package/docs/en/configure/app/plugins.mdx +13 -33
  4. package/docs/en/configure/app/runtime/master-app.mdx +1 -5
  5. package/docs/en/configure/app/runtime/plugins.mdx +58 -0
  6. package/docs/en/configure/app/usage.mdx +1 -3
  7. package/docs/en/guides/advanced-features/_meta.json +1 -0
  8. package/docs/en/guides/advanced-features/bff.mdx +1 -1
  9. package/docs/en/guides/advanced-features/compatibility.mdx +1 -1
  10. package/docs/en/guides/advanced-features/custom-server.mdx +218 -0
  11. package/docs/en/guides/advanced-features/page-performance/inline-assets.mdx +2 -0
  12. package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
  13. package/docs/en/guides/advanced-features/web-server.mdx +174 -1
  14. package/docs/en/guides/basic-features/data/data-cache.mdx +216 -1
  15. package/docs/en/guides/basic-features/data/data-fetch.mdx +2 -1
  16. package/docs/en/guides/basic-features/deploy.mdx +3 -1
  17. package/docs/en/guides/basic-features/html.mdx +3 -3
  18. package/docs/en/guides/basic-features/render/ssr.mdx +2 -2
  19. package/docs/en/guides/concept/entries.mdx +1 -1
  20. package/docs/en/guides/get-started/quick-start.mdx +1 -1
  21. package/docs/en/plugin/cli-plugins/api.mdx +6 -0
  22. package/docs/en/plugin/runtime-plugins/api.mdx +37 -12
  23. package/docs/en/tutorials/first-app/c05-loader.mdx +1 -1
  24. package/docs/zh/configure/app/output/filename.mdx +8 -0
  25. package/docs/zh/configure/app/plugins.mdx +3 -24
  26. package/docs/zh/configure/app/runtime/master-app.mdx +1 -5
  27. package/docs/zh/configure/app/runtime/plugins.mdx +58 -0
  28. package/docs/zh/configure/app/usage.mdx +1 -2
  29. package/docs/zh/guides/advanced-features/_meta.json +1 -0
  30. package/docs/zh/guides/advanced-features/custom-server.mdx +216 -0
  31. package/docs/zh/guides/advanced-features/web-server.mdx +174 -1
  32. package/docs/zh/guides/basic-features/data/data-cache.mdx +205 -1
  33. package/docs/zh/guides/basic-features/routes.mdx +72 -0
  34. package/docs/zh/plugin/cli-plugins/api.mdx +6 -0
  35. package/docs/zh/plugin/runtime-plugins/api.mdx +37 -12
  36. package/package.json +2 -2
  37. package/src/i18n/index.ts +1 -1
  38. /package/docs/en/configure/app/source/{mainEntryName.mdx → main-entry-name.mdx} +0 -0
  39. /package/docs/zh/configure/app/source/{mainEntryName.mdx → main-entry-name.mdx} +0 -0
@@ -88,3 +88,73 @@ export default () => {
88
88
  `<Outlet>` is a new API in React Router 6. For details, see [Outlet](https://reactrouter.com/en/main/components/outlet#outlet).
89
89
 
90
90
  :::
91
+
92
+ ## Upgrading to React Router v7
93
+
94
+ React Router v7 reduces bundle size (approximately 15% smaller) compared to React Router v6, provides a more efficient route matching algorithm, and offers better support for React 19 and TypeScript. There are very few breaking changes compared to React Router v6, and Modern.js has made both versions compatible, allowing for a seamless upgrade by simply installing and registering the appropriate plugin.
95
+
96
+ :::info
97
+
98
+ For more changes from React Router v6 to React Router v7, check the [documentation](https://reactrouter.com/upgrading/v6#upgrade-to-v7)
99
+
100
+ :::
101
+
102
+ ### Requirements
103
+
104
+ React Router v7 has certain environment requirements:
105
+
106
+ - Node.js 20+
107
+ - React 18+
108
+ - React DOM 18+
109
+
110
+ ### Install the Plugin
111
+
112
+ First, install the Modern.js React Router v7 plugin:
113
+
114
+ ```bash
115
+ pnpm add @modern-js/plugin-router-v7
116
+ ```
117
+
118
+ ### Configure the Plugin
119
+
120
+ Register the plugin in `modern.config.ts`:
121
+
122
+ ```ts title="modern.config.ts"
123
+ import { routerPlugin } from '@modern-js/plugin-router-v7';
124
+
125
+ export default {
126
+ runtime: {
127
+ router: true,
128
+ },
129
+ plugins: [routerPlugin()],
130
+ };
131
+ ```
132
+
133
+ ### Code Changes
134
+
135
+ In React Router v7, you no longer need to use the `defer` API; you can directly return data in the data loader:
136
+
137
+ ```ts title="routes/page.data.ts"
138
+ import { defer } from '@modern-js/runtime/router';
139
+
140
+ export const loader = async ({ params }) => {
141
+ // Recommended v7 style
142
+ const user = fetchUser(params.id)
143
+ return { user };
144
+
145
+ // v6 style, still compatible with Modern.js
146
+ return defer({ data: 'hello' });
147
+ };
148
+ ```
149
+
150
+ React Router v7 has also deprecated the `json` API:
151
+
152
+ ```ts title="routes/page.data.ts"
153
+ export const loader = async ({ params }) => {
154
+ // Recommended v7 style
155
+ return { data: 'hello' };
156
+
157
+ // v6 style, still compatible with Modern.js
158
+ return json({ data: 'hello' });
159
+ };
160
+ ```
@@ -3,13 +3,20 @@ title: filename
3
3
  configName: output.filename
4
4
  ---
5
5
 
6
+ :::warning
7
+
8
+ In Modern.js `dev` command or use Modern.js server deployment, don't modify the html output filename. This will cause the page to be 404.
9
+
10
+ In common, you don't need to modify the html filename. If you want modify `main.html` to `index.html`, using [source.mainEntryName](/configure/app/source/main-entry-name).
11
+
12
+ :::
13
+
6
14
  # output.filename
7
15
 
8
16
  - **Type:**
9
17
 
10
18
  ```ts
11
19
  type FilenameConfig = {
12
- html?: string;
13
20
  js?:
14
21
  | string
15
22
  | ((pathData: Rspack.PathData, assetInfo: Rspack.JsAssetInfo) => string);
@@ -27,7 +34,6 @@ type FilenameConfig = {
27
34
  ```js
28
35
  // Development mode
29
36
  const devDefaultFilename = {
30
- html: '[name].html',
31
37
  js: '[name].js',
32
38
  css: '[name].css',
33
39
  svg: '[name].[contenthash:8].svg',
@@ -39,7 +45,6 @@ const devDefaultFilename = {
39
45
 
40
46
  // Production mode
41
47
  const prodDefaultFilename = {
42
- html: '[name].html',
43
48
  js: output.target === 'node' ? '[name].js' : '[name].[contenthash:8].js',
44
49
  css: '[name].[contenthash:8].css',
45
50
  svg: '[name].[contenthash:8].svg',
@@ -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 used to configure framework plugins. If you need to configure other types of plugins, please choose the corresponding configuration method:
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
- By default, custom plugins are executed in the order of the `plugins` array, and the execution time of built-in Modern.js plugins is earlier than that of custom plugins.
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
- ## Example
18
+ ## Examples
39
19
 
40
- The following is an example of using CLI plugins.
20
+ Below are examples of using CLI plugins:
41
21
 
42
- ### Use plugins on npm
22
+ ### Using plugins from npm
43
23
 
44
- To use plugins from npm registry, you need to first install the plugins , and import them in `modern.config.ts`.
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
- ### Use local plugins
34
+ ### Using local plugins
55
35
 
56
- To use local plugins, import them directly using a relative path.
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 the plugin provides some custom configuration options, they can be passed in as parameters to the plugin function.
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';
@@ -1,8 +1,4 @@
1
- ---
2
- title: masterApp
3
- ---
4
-
5
- # runtime.masterApp
1
+ # masterApp
6
2
 
7
3
  - **Type:** `Object`
8
4
 
@@ -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,9 +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
- {/* TODO server 配置文件更新 */}
17
- **Server Runtime configuration** can be configured in the `modern.server-runtime.config.(ts|js|mjs)` file in the root path.
18
-
16
+ **Server Runtime configuration** can be configured in the `server/modern.server.(ts|js|mjs)` file.
19
17
 
20
18
  ## Compile Configuration
21
19
 
@@ -23,5 +23,6 @@
23
23
  "label": "server-monitor",
24
24
  "collapsed": true
25
25
  },
26
+ "custom-server",
26
27
  "web-server"
27
28
  ]
@@ -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] (https://github.com/zloirock/core-js) during compilation.
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 in production environment because it directly affects the user experience of online users. In this document, we will introduce some common bundle size optimization methods in Modern.js.
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