@modern-js/main-doc 3.9.3 → 3.10.1
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/apis/app/hooks/api/lambda.mdx +2 -1
- package/docs/en/apis/app/hooks/config/html.mdx +1 -0
- package/docs/en/apis/app/hooks/config/mock.mdx +1 -0
- package/docs/en/apis/app/hooks/config/public.mdx +1 -0
- package/docs/en/apis/app/hooks/config/upload.mdx +2 -3
- package/docs/en/apis/app/hooks/modern-config.mdx +1 -0
- package/docs/en/apis/app/hooks/shared.mdx +1 -0
- package/docs/en/apis/app/hooks/src/modern.runtime.mdx +1 -0
- package/docs/en/apis/app/hooks/src/routes.mdx +1 -0
- package/docs/en/apis/app/hooks/src/server.mdx +2 -1
- package/docs/en/apis/app/runtime/bff/use-hono-context.mdx +1 -0
- package/docs/en/apis/app/runtime/core/create-root.mdx +4 -1
- package/docs/en/apis/app/runtime/core/render.mdx +6 -2
- package/docs/en/apis/app/runtime/core/runtime-context.mdx +17 -17
- package/docs/en/apis/app/runtime/router/router.mdx +9 -6
- package/docs/en/apis/app/runtime/ssr/no-ssr.mdx +1 -0
- package/docs/en/apis/app/runtime/utility/head.mdx +1 -0
- package/docs/en/apis/app/runtime/utility/loadable.mdx +1 -0
- package/docs/en/community/blog/v3-release-note.mdx +36 -27
- package/docs/en/community/contributing-guide.mdx +15 -33
- package/docs/en/components/default-browserslist.mdx +0 -1
- package/docs/en/components/deploy-command.mdx +1 -1
- package/docs/en/components/deploy.mdx +1 -1
- package/docs/en/components/entry-scan-logic.mdx +1 -1
- package/docs/en/components/init-app.mdx +9 -3
- package/docs/en/components/international/custom-instance-code.mdx +0 -1
- package/docs/en/components/micro-runtime-config.mdx +12 -9
- package/docs/en/components/nodeVersion.mdx +2 -2
- package/docs/en/components/rsc-deploy-tip.mdx +0 -1
- package/docs/en/components/ssr-monitor.mdx +1 -1
- package/docs/en/configure/app/bff/cross-project.mdx +2 -2
- package/docs/en/configure/app/bff/prefix.mdx +1 -1
- package/docs/en/configure/app/dev/lazy-compilation.mdx +17 -1
- package/docs/en/configure/app/dev/start-url.mdx +0 -1
- package/docs/en/configure/app/output/css-modules.mdx +1 -5
- package/docs/en/configure/app/output/dist-path.mdx +0 -1
- package/docs/en/configure/app/output/inline-scripts.mdx +1 -2
- package/docs/en/configure/app/output/inline-styles.mdx +1 -2
- package/docs/en/configure/app/output/split-route-chunks.mdx +1 -1
- package/docs/en/configure/app/output/ssg.mdx +1 -1
- package/docs/en/configure/app/output/ssgByEntries.mdx +1 -0
- package/docs/en/configure/app/performance/chunk-split.mdx +1 -4
- package/docs/en/configure/app/runtime/plugins.mdx +6 -4
- package/docs/en/configure/app/server/rsc.mdx +1 -1
- package/docs/en/configure/app/server/ssr.mdx +7 -8
- package/docs/en/configure/app/server/tsconfig-path.mdx +2 -2
- package/docs/en/configure/app/tools/less.mdx +5 -6
- package/docs/en/configure/app/tools/sass.mdx +5 -6
- package/docs/en/configure/app/tools/svgr.mdx +7 -7
- package/docs/en/configure/app/usage.mdx +1 -5
- package/docs/en/guides/advanced-features/bff/cross-project.mdx +5 -4
- package/docs/en/guides/advanced-features/compatibility.mdx +0 -1
- package/docs/en/guides/advanced-features/international/advanced.mdx +1 -1
- package/docs/en/guides/advanced-features/international/api.mdx +34 -28
- package/docs/en/guides/advanced-features/international/best-practices.mdx +15 -15
- package/docs/en/guides/advanced-features/international/configuration.mdx +37 -37
- package/docs/en/guides/advanced-features/international/locale-detection.mdx +37 -28
- package/docs/en/guides/advanced-features/international/resource-loading.mdx +19 -17
- package/docs/en/guides/advanced-features/international/routing.mdx +8 -6
- package/docs/en/guides/advanced-features/international.mdx +8 -8
- package/docs/en/guides/advanced-features/server-monitor/logger.mdx +5 -5
- package/docs/en/guides/advanced-features/server-monitor/metrics.mdx +8 -8
- package/docs/en/guides/advanced-features/server-monitor/monitors.mdx +1 -3
- package/docs/en/guides/advanced-features/source-build.mdx +1 -1
- package/docs/en/guides/advanced-features/web-server.mdx +3 -3
- package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -3
- package/docs/en/guides/basic-features/data/data-write.mdx +24 -28
- package/docs/en/guides/basic-features/debug/mock.mdx +2 -2
- package/docs/en/guides/basic-features/debug/using-storybook.mdx +5 -6
- package/docs/en/guides/basic-features/html.mdx +2 -3
- package/docs/en/guides/basic-features/output-files.mdx +1 -1
- package/docs/en/guides/basic-features/render/overview.mdx +12 -12
- package/docs/en/guides/basic-features/render/rsc.mdx +16 -9
- package/docs/en/guides/basic-features/render/ssr-cache.mdx +5 -5
- package/docs/en/guides/basic-features/render/ssr.mdx +8 -12
- package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -1
- package/docs/en/guides/basic-features/routes/config-routes.mdx +60 -59
- package/docs/en/guides/basic-features/testing/playwright.mdx +14 -8
- package/docs/en/guides/basic-features/testing/rstest.mdx +6 -4
- package/docs/en/guides/get-started/ai-coding-agents.mdx +6 -6
- package/docs/en/guides/get-started/introduction.mdx +0 -1
- package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/en/guides/topic-detail/module-federation/introduce.mdx +0 -1
- package/docs/en/guides/upgrade/config.mdx +12 -0
- package/docs/en/guides/upgrade/other.mdx +4 -4
- package/docs/en/guides/upgrade/tailwindcss.mdx +0 -1
- package/docs/en/guides/upgrade/web-server.md +34 -17
- package/docs/en/index.md +1 -0
- package/docs/en/plugin/cli-plugins/api.mdx +23 -23
- package/docs/en/plugin/cli-plugins/life-cycle.mdx +2 -0
- package/docs/en/plugin/introduction.mdx +6 -6
- package/docs/en/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
- package/docs/en/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
- package/docs/en/plugin/plugin-system.mdx +19 -26
- package/docs/en/plugin/runtime-plugins/life-cycle.mdx +2 -0
- package/docs/en/plugin/server-plugins/api.mdx +11 -14
- package/docs/en/plugin/server-plugins/life-cycle.mdx +2 -0
- package/docs/zh/apis/app/hooks/api/lambda.mdx +1 -1
- package/docs/zh/apis/app/hooks/config/html.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/mock.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/public.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/upload.mdx +2 -3
- package/docs/zh/apis/app/hooks/modern-config.mdx +1 -0
- package/docs/zh/apis/app/hooks/shared.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/routes.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/server.mdx +2 -1
- package/docs/zh/apis/app/runtime/bff/use-hono-context.mdx +1 -1
- package/docs/zh/apis/app/runtime/core/create-root.mdx +4 -1
- package/docs/zh/apis/app/runtime/core/render.mdx +6 -3
- package/docs/zh/apis/app/runtime/core/runtime-context.mdx +17 -17
- package/docs/zh/apis/app/runtime/router/router.mdx +10 -6
- package/docs/zh/apis/app/runtime/ssr/no-ssr.mdx +1 -0
- package/docs/zh/apis/app/runtime/utility/head.mdx +1 -0
- package/docs/zh/apis/app/runtime/utility/loadable.mdx +1 -0
- package/docs/zh/community/blog/v3-release-note.mdx +38 -29
- package/docs/zh/community/contributing-guide.mdx +16 -34
- package/docs/zh/components/default-browserslist.mdx +0 -1
- package/docs/zh/components/deploy-command.mdx +1 -1
- package/docs/zh/components/deploy.mdx +1 -1
- package/docs/zh/components/entry-scan-logic.mdx +1 -1
- package/docs/zh/components/init-app.mdx +9 -3
- package/docs/zh/components/international/custom-instance-code.mdx +0 -1
- package/docs/zh/components/international/install-command.mdx +0 -1
- package/docs/zh/components/micro-runtime-config.mdx +12 -9
- package/docs/zh/components/nodeVersion.mdx +2 -2
- package/docs/zh/components/rsc-deploy-tip.mdx +0 -1
- package/docs/zh/components/ssr-monitor.mdx +1 -1
- package/docs/zh/configure/app/bff/cross-project.mdx +2 -2
- package/docs/zh/configure/app/bff/prefix.mdx +1 -1
- package/docs/zh/configure/app/dev/lazy-compilation.mdx +17 -1
- package/docs/zh/configure/app/html/crossorigin.mdx +0 -1
- package/docs/zh/configure/app/html/favicon.mdx +0 -1
- package/docs/zh/configure/app/output/convert-to-rem.mdx +0 -1
- package/docs/zh/configure/app/output/css-modules.mdx +1 -5
- package/docs/zh/configure/app/output/inline-scripts.mdx +1 -2
- package/docs/zh/configure/app/output/inline-styles.mdx +1 -2
- package/docs/zh/configure/app/output/source-map.mdx +0 -2
- package/docs/zh/configure/app/output/split-route-chunks.mdx +1 -1
- package/docs/zh/configure/app/output/ssg.mdx +1 -0
- package/docs/zh/configure/app/output/ssgByEntries.mdx +1 -1
- package/docs/zh/configure/app/performance/chunk-split.mdx +1 -4
- package/docs/zh/configure/app/resolve/dedupe.mdx +0 -1
- package/docs/zh/configure/app/runtime/plugins.mdx +6 -4
- package/docs/zh/configure/app/server/rsc.mdx +1 -1
- package/docs/zh/configure/app/server/ssr.mdx +6 -7
- package/docs/zh/configure/app/server/tsconfig-path.mdx +2 -2
- package/docs/zh/configure/app/tools/less.mdx +6 -7
- package/docs/zh/configure/app/tools/sass.mdx +6 -7
- package/docs/zh/configure/app/tools/svgr.mdx +11 -11
- package/docs/zh/configure/app/usage.mdx +1 -5
- package/docs/zh/guides/advanced-features/bff.mdx +1 -0
- package/docs/zh/guides/advanced-features/international/advanced.mdx +1 -1
- package/docs/zh/guides/advanced-features/international/api.mdx +28 -27
- package/docs/zh/guides/advanced-features/international/best-practices.mdx +15 -15
- package/docs/zh/guides/advanced-features/international/configuration.mdx +38 -36
- package/docs/zh/guides/advanced-features/international/locale-detection.mdx +37 -28
- package/docs/zh/guides/advanced-features/international/resource-loading.mdx +20 -16
- package/docs/zh/guides/advanced-features/international/routing.mdx +6 -4
- package/docs/zh/guides/advanced-features/international.mdx +9 -9
- package/docs/zh/guides/advanced-features/server-monitor/logger.mdx +4 -6
- package/docs/zh/guides/advanced-features/server-monitor/metrics.mdx +9 -10
- package/docs/zh/guides/advanced-features/source-build.mdx +1 -1
- package/docs/zh/guides/advanced-features/web-server.mdx +3 -3
- package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -3
- package/docs/zh/guides/basic-features/data/data-write.mdx +25 -31
- package/docs/zh/guides/basic-features/debug/mock.mdx +2 -2
- package/docs/zh/guides/basic-features/debug/using-storybook.mdx +5 -5
- package/docs/zh/guides/basic-features/env-vars.mdx +0 -1
- package/docs/zh/guides/basic-features/html.mdx +2 -3
- package/docs/zh/guides/basic-features/render/overview.mdx +12 -13
- package/docs/zh/guides/basic-features/render/rsc.mdx +16 -9
- package/docs/zh/guides/basic-features/render/ssr.mdx +8 -17
- package/docs/zh/guides/basic-features/routes/config-routes.mdx +61 -59
- package/docs/zh/guides/basic-features/testing/playwright.mdx +15 -10
- package/docs/zh/guides/basic-features/testing/rstest.mdx +6 -4
- package/docs/zh/guides/get-started/ai-coding-agents.mdx +7 -7
- package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/zh/guides/upgrade/config.mdx +12 -0
- package/docs/zh/guides/upgrade/other.md +4 -11
- package/docs/zh/guides/upgrade/overview.mdx +1 -4
- package/docs/zh/guides/upgrade/tailwindcss.mdx +0 -1
- package/docs/zh/guides/upgrade/web-server.md +34 -19
- package/docs/zh/index.md +1 -0
- package/docs/zh/plugin/cli-plugins/api.mdx +24 -24
- package/docs/zh/plugin/cli-plugins/life-cycle.mdx +2 -0
- package/docs/zh/plugin/introduction.mdx +6 -6
- package/docs/zh/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
- package/docs/zh/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
- package/docs/zh/plugin/plugin-system.mdx +19 -26
- package/docs/zh/plugin/runtime-plugins/life-cycle.mdx +2 -0
- package/docs/zh/plugin/server-plugins/api.mdx +11 -14
- package/docs/zh/plugin/server-plugins/life-cycle.mdx +2 -0
- package/package.json +11 -13
- package/{rspress.config.ts → rstack.config.mts} +7 -10
- package/src/components/Footer/styles.module.scss +1 -1
- package/src/components/SolutionCards/index.module.scss +3 -1
|
@@ -8,21 +8,21 @@ Modern.js supports multiple rendering modes, and different rendering modes are s
|
|
|
8
8
|
|
|
9
9
|
## Rendering Mode Quick Reference
|
|
10
10
|
|
|
11
|
-
| Rendering Mode
|
|
12
|
-
|
|
13
|
-
| **CSR**
|
|
14
|
-
| **SSR**
|
|
15
|
-
| **Streaming SSR** | Renders and returns progressively, displaying initial UI faster
|
|
16
|
-
| **RSC**
|
|
17
|
-
| **SSG**
|
|
11
|
+
| Rendering Mode | Characteristics | Use Cases |
|
|
12
|
+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
13
|
+
| **CSR** | Executes JavaScript in the browser to render pages | Applications with strong interactivity and low SEO requirements |
|
|
14
|
+
| **SSR** | Pre-renders complete HTML pages on the server | Websites with high requirements for first-screen performance and SEO |
|
|
15
|
+
| **Streaming SSR** | Renders and returns progressively, displaying initial UI faster | Applications requiring faster first-screen perception speed (**Default SSR mode**) |
|
|
16
|
+
| **RSC** | Components render on the server, reducing client JS size; high cohesion between data and component logic, reducing state passing | Projects pursuing optimal performance and needing to reduce client-side code |
|
|
17
|
+
| **SSG** | Generates static pages at build time, can be cached by CDN | Websites with relatively static content, such as blogs and documentation sites |
|
|
18
18
|
|
|
19
19
|
## Performance Comparison
|
|
20
20
|
|
|
21
|
-
| Rendering Technology
|
|
22
|
-
|
|
23
|
-
| **SSR**
|
|
24
|
-
| **Streaming SSR**
|
|
25
|
-
| **Streaming SSR + RSC** | Reduces client JS size
|
|
21
|
+
| Rendering Technology | Core Advantages | Main Bottlenecks |
|
|
22
|
+
| ----------------------- | ------------------------------------------------------ | ------------------------------------------------ |
|
|
23
|
+
| **SSR** | Server-side pre-rendering, beneficial for SEO | Must wait for all data to load before responding |
|
|
24
|
+
| **Streaming SSR** | Renders and returns progressively, faster first screen | JS bundle size is still large |
|
|
25
|
+
| **Streaming SSR + RSC** | Reduces client JS size | - |
|
|
26
26
|
|
|
27
27
|
## How to Choose
|
|
28
28
|
|
|
@@ -239,12 +239,12 @@ In RSC projects, you have two ways to fetch data: directly in Server Components,
|
|
|
239
239
|
|
|
240
240
|
### Comparison of Two Data Fetching Approaches
|
|
241
241
|
|
|
242
|
-
| Feature
|
|
243
|
-
|
|
|
244
|
-
| Avoid Request Waterfall | Requires manual optimization
|
|
245
|
-
| Component Cohesion
|
|
246
|
-
| Maintainability
|
|
247
|
-
| Type Safety
|
|
242
|
+
| Feature | Fetching in Server Component | Fetching in Data Loader |
|
|
243
|
+
| ----------------------- | ------------------------------------ | ---------------------------------------- |
|
|
244
|
+
| Avoid Request Waterfall | Requires manual optimization | ✅ Automatically parallel execution |
|
|
245
|
+
| Component Cohesion | ✅ Data and UI in the same place | Data logic separated into separate files |
|
|
246
|
+
| Maintainability | ✅ Easier to understand and maintain | Requires maintaining additional files |
|
|
247
|
+
| Type Safety | ✅ Natural type inference | Requires manual type management |
|
|
248
248
|
|
|
249
249
|
**Generally, we recommend fetching data in Server Components**, because waterfall requests have less performance impact on the server, and this approach makes components more cohesive, with data fetching logic and UI rendering in the same place, making it easier to understand and maintain. However, if your page has multiple independent data sources and you want to completely avoid request waterfall issues, Data Loader's parallel execution feature will be more advantageous.
|
|
250
250
|
|
|
@@ -268,7 +268,11 @@ In Modern.js RSC projects, Server Components can receive data returned by Data L
|
|
|
268
268
|
|
|
269
269
|
```tsx title="routes/user/page.tsx"
|
|
270
270
|
// Server Component receives loaderData through props
|
|
271
|
-
export default function UserPage({
|
|
271
|
+
export default function UserPage({
|
|
272
|
+
loaderData,
|
|
273
|
+
}: {
|
|
274
|
+
loaderData: { name: string };
|
|
275
|
+
}) {
|
|
272
276
|
return <div>Welcome, {loaderData.name}</div>;
|
|
273
277
|
}
|
|
274
278
|
```
|
|
@@ -276,7 +280,11 @@ export default function UserPage({ loaderData }: { loaderData: { name: string }
|
|
|
276
280
|
```tsx title="routes/user/page.tsx"
|
|
277
281
|
'use client';
|
|
278
282
|
// Client Component can also receive loaderData through props
|
|
279
|
-
export default function UserPage({
|
|
283
|
+
export default function UserPage({
|
|
284
|
+
loaderData,
|
|
285
|
+
}: {
|
|
286
|
+
loaderData: { name: string };
|
|
287
|
+
}) {
|
|
280
288
|
return <div>Welcome, {loaderData.name}</div>;
|
|
281
289
|
}
|
|
282
290
|
```
|
|
@@ -515,7 +523,6 @@ When using React 19, you no longer need to use Helmet. We recommend directly usi
|
|
|
515
523
|
|
|
516
524
|
import DeployTip from '@site-docs/components/rsc-deploy-tip';
|
|
517
525
|
|
|
518
|
-
|
|
519
526
|
<DeployTip />
|
|
520
527
|
|
|
521
528
|
## Common Issues
|
|
@@ -193,9 +193,9 @@ When rendering cache is enabled, Modern.js identifies the cache status of the cu
|
|
|
193
193
|
|
|
194
194
|
The `x-render-cache` header can have the following values:
|
|
195
195
|
|
|
196
|
-
| Name | Description
|
|
197
|
-
| ------- |
|
|
198
|
-
| hit | Cache hit, returned cache content
|
|
196
|
+
| Name | Description |
|
|
197
|
+
| ------- | ----------------------------------------------------------------------------------- |
|
|
198
|
+
| hit | Cache hit, returned cache content |
|
|
199
199
|
| stale | Cache hit, but data is stale, returned cache content and re-rendered asynchronously |
|
|
200
|
-
| expired | Cache expired, re-rendered and returned new content
|
|
201
|
-
| miss | Cache missed
|
|
200
|
+
| expired | Cache expired, re-rendered and returned new content |
|
|
201
|
+
| miss | Cache missed |
|
|
@@ -90,7 +90,7 @@ export async function loader({ params }) {
|
|
|
90
90
|
const data = await res.json();
|
|
91
91
|
return {
|
|
92
92
|
message: data.message,
|
|
93
|
-
}
|
|
93
|
+
};
|
|
94
94
|
}
|
|
95
95
|
```
|
|
96
96
|
|
|
@@ -125,11 +125,7 @@ const Page = () => {
|
|
|
125
125
|
const undefinedVars = data.unDefined;
|
|
126
126
|
const definedVars = data.defined;
|
|
127
127
|
|
|
128
|
-
return
|
|
129
|
-
<div>
|
|
130
|
-
{isNode ? undefinedVars.msg : definedVars.msg}
|
|
131
|
-
</div>
|
|
132
|
-
);
|
|
128
|
+
return <div>{isNode ? undefinedVars.msg : definedVars.msg}</div>;
|
|
133
129
|
};
|
|
134
130
|
|
|
135
131
|
export default Page;
|
|
@@ -214,7 +210,7 @@ document.addEventListener('load', () => {
|
|
|
214
210
|
console.log('document load');
|
|
215
211
|
});
|
|
216
212
|
|
|
217
|
-
export const doSomething = () => {}
|
|
213
|
+
export const doSomething = () => {};
|
|
218
214
|
```
|
|
219
215
|
|
|
220
216
|
Directly referencing this in a component will cause SSR to throw errors, even if you use environment variables to conditionally load the code. The side effects in the dependency will still execute.
|
|
@@ -226,8 +222,8 @@ export const Page = () => {
|
|
|
226
222
|
if (process.env.MODERN_TARGET === 'browser') {
|
|
227
223
|
doSomething();
|
|
228
224
|
}
|
|
229
|
-
return <div>Hello World</div
|
|
230
|
-
}
|
|
225
|
+
return <div>Hello World</div>;
|
|
226
|
+
};
|
|
231
227
|
```
|
|
232
228
|
|
|
233
229
|
Modern.js supports distinguishing between SSR and CSR bundles by using `.server.` suffix files. You can create `.ts` and `.server.ts` files with the same name to create a proxy:
|
|
@@ -243,12 +239,12 @@ export const doSomething: any = () => {};
|
|
|
243
239
|
Import `./a` in the file, and the SSR bundle will prioritize the `.server.ts` files, while the CSR bundle will prioritize the `.ts` files.
|
|
244
240
|
|
|
245
241
|
```tsx title="routes/page.tsx"
|
|
246
|
-
import { doSomething } from './a'
|
|
242
|
+
import { doSomething } from './a';
|
|
247
243
|
|
|
248
244
|
export const Page = () => {
|
|
249
245
|
doSomething();
|
|
250
|
-
return <div>Hello World</div
|
|
251
|
-
}
|
|
246
|
+
return <div>Hello World</div>;
|
|
247
|
+
};
|
|
252
248
|
```
|
|
253
249
|
|
|
254
250
|
## Common Issues
|
|
@@ -245,7 +245,8 @@ Set the header in your middleware to choose the behavior dynamically:
|
|
|
245
245
|
```ts title="middleware example"
|
|
246
246
|
export const middleware = async (ctx, next) => {
|
|
247
247
|
const ua = ctx.req.header('user-agent') || '';
|
|
248
|
-
const shouldWaitAll =
|
|
248
|
+
const shouldWaitAll =
|
|
249
|
+
/Lighthouse|Googlebot/i.test(ua) || ctx.req.path === '/marketing';
|
|
249
250
|
|
|
250
251
|
// Write a boolean string: true -> onAllReady, false -> onShellReady
|
|
251
252
|
ctx.req.headers.set('x-should-stream-all', String(shouldWaitAll));
|
|
@@ -6,7 +6,6 @@ sidebar_position: 3
|
|
|
6
6
|
|
|
7
7
|
By default, Modern.js recommends using [Convention Routes](./routes.mdx) as the way to define routes. At the same time, Modern.js also provides a config-based routing capability that can be used together with convention routes or used separately.
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
## When to Use Config Routes
|
|
11
10
|
|
|
12
11
|
Config routes are particularly useful in the following scenarios:
|
|
@@ -22,27 +21,26 @@ Config routes are particularly useful in the following scenarios:
|
|
|
22
21
|
In the `src` directory or each entry directory, you can define a `modern.routes.ts` file to configure routes:
|
|
23
22
|
|
|
24
23
|
```ts
|
|
25
|
-
import { defineRoutes } from '@modern-js/runtime/config-routes'
|
|
24
|
+
import { defineRoutes } from '@modern-js/runtime/config-routes';
|
|
26
25
|
|
|
27
26
|
export default defineRoutes(({ route, layout, page, $ }, fileRoutes) => {
|
|
28
|
-
return [
|
|
29
|
-
|
|
30
|
-
]
|
|
31
|
-
})
|
|
27
|
+
return [route('home.tsx', '/')];
|
|
28
|
+
});
|
|
32
29
|
```
|
|
33
30
|
|
|
34
31
|
### Function Signature Description
|
|
35
32
|
|
|
36
33
|
`defineRoutes` accepts a callback function with two parameters:
|
|
34
|
+
|
|
37
35
|
1. `routeFunctions`: An object containing `route`, `layout`, `page`, `$` functions
|
|
38
36
|
2. `fileRoutes`: An array of route configurations generated by convention routes
|
|
39
37
|
|
|
40
38
|
Basic signature of route functions:
|
|
39
|
+
|
|
41
40
|
- First parameter: File path relative to `modern.routes.ts`
|
|
42
41
|
- Second parameter: Route path (optional, must be a string)
|
|
43
42
|
- Third parameter: Array of child routes (optional)
|
|
44
43
|
|
|
45
|
-
|
|
46
44
|
## Route Functions
|
|
47
45
|
|
|
48
46
|
Modern.js provides four main route configuration functions:
|
|
@@ -50,6 +48,7 @@ Modern.js provides four main route configuration functions:
|
|
|
50
48
|
:::tip Path Description
|
|
51
49
|
|
|
52
50
|
The first parameter (path) of all route functions is a **relative path**, which will be concatenated with the parent path to generate the final route path:
|
|
51
|
+
|
|
53
52
|
- **Root path**: `"/"` or `""` represents the root path of the current level
|
|
54
53
|
- **Relative path**: Child route paths will be concatenated relative to the parent path
|
|
55
54
|
- **Dynamic path**: Use `:param` syntax to represent dynamic parameters
|
|
@@ -72,27 +71,28 @@ The `route` function is a general-purpose route configuration function that auto
|
|
|
72
71
|
export default defineRoutes(({ route }, fileRoutes) => {
|
|
73
72
|
return [
|
|
74
73
|
// When no child routes, automatically generates page route
|
|
75
|
-
route(
|
|
76
|
-
route(
|
|
74
|
+
route('home.tsx', '/'),
|
|
75
|
+
route('about.tsx', 'about'),
|
|
77
76
|
|
|
78
77
|
// When has child routes, automatically generates layout route
|
|
79
78
|
// dashboard/layout.tsx needs to contain <Outlet> to render child routes
|
|
80
|
-
route(
|
|
81
|
-
route(
|
|
82
|
-
route(
|
|
79
|
+
route('dashboard/layout.tsx', 'dashboard', [
|
|
80
|
+
route('dashboard/overview.tsx', 'overview'), // Generated path: /dashboard/overview
|
|
81
|
+
route('dashboard/settings.tsx', 'settings'), // Generated path: /dashboard/settings
|
|
83
82
|
]),
|
|
84
83
|
|
|
85
84
|
// Dynamic routes
|
|
86
|
-
route(
|
|
85
|
+
route('products/detail.tsx', 'products/:id'),
|
|
87
86
|
|
|
88
87
|
// Multiple paths pointing to the same component
|
|
89
|
-
route(
|
|
90
|
-
route(
|
|
91
|
-
]
|
|
92
|
-
})
|
|
88
|
+
route('user/profile.tsx', 'user'),
|
|
89
|
+
route('user/profile.tsx', 'profile'),
|
|
90
|
+
];
|
|
91
|
+
});
|
|
93
92
|
```
|
|
94
93
|
|
|
95
94
|
**Use cases**:
|
|
95
|
+
|
|
96
96
|
- Quick route configuration without explicitly specifying page or layout
|
|
97
97
|
- Simplify the complexity of route configuration
|
|
98
98
|
|
|
@@ -104,15 +104,16 @@ The `layout` function is specifically used to configure layout routes, always ge
|
|
|
104
104
|
export default defineRoutes(({ layout, page }, fileRoutes) => {
|
|
105
105
|
return [
|
|
106
106
|
// Generate layout route with path "/auth", must contain child routes
|
|
107
|
-
layout(
|
|
108
|
-
page(
|
|
109
|
-
page(
|
|
107
|
+
layout('auth/layout.tsx', 'auth', [
|
|
108
|
+
page('auth/login/page.tsx', 'login'), // Generated path: /auth/login
|
|
109
|
+
page('auth/register/page.tsx', 'register'), // Generated path: /auth/register
|
|
110
110
|
]),
|
|
111
|
-
]
|
|
112
|
-
})
|
|
111
|
+
];
|
|
112
|
+
});
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
**Use cases**:
|
|
116
|
+
|
|
116
117
|
- Need to explicitly specify a component as a layout component
|
|
117
118
|
- Provide common layout structure for multiple pages
|
|
118
119
|
- Need to share navigation, sidebar and other UI components across multiple routes
|
|
@@ -124,15 +125,16 @@ The `page` function is specifically used to configure page routes, always genera
|
|
|
124
125
|
```ts
|
|
125
126
|
export default defineRoutes(({ layout, page }, fileRoutes) => {
|
|
126
127
|
return [
|
|
127
|
-
layout(
|
|
128
|
-
page(
|
|
129
|
-
page(
|
|
128
|
+
layout('dashboard/layout.tsx', 'dashboard', [
|
|
129
|
+
page('dashboard/overview.tsx', 'overview'), // Generated path: /dashboard/overview
|
|
130
|
+
page('dashboard/settings.tsx', 'settings'), // Generated path: /dashboard/settings
|
|
130
131
|
]),
|
|
131
|
-
]
|
|
132
|
-
})
|
|
132
|
+
];
|
|
133
|
+
});
|
|
133
134
|
```
|
|
134
135
|
|
|
135
136
|
**Use cases**:
|
|
137
|
+
|
|
136
138
|
- Need to explicitly specify a component as a page component
|
|
137
139
|
- Ensure the component does not contain `<Outlet>` child component rendering
|
|
138
140
|
- Provide clearer semantic expression
|
|
@@ -144,16 +146,17 @@ The `$` function is specifically used to configure wildcard routes for handling
|
|
|
144
146
|
```ts
|
|
145
147
|
export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
|
|
146
148
|
return [
|
|
147
|
-
layout(
|
|
148
|
-
page(
|
|
149
|
-
page(
|
|
150
|
-
$(
|
|
149
|
+
layout('blog/layout.tsx', 'blog', [
|
|
150
|
+
page('blog/page.tsx', ''), // Generated path: /blog
|
|
151
|
+
page('blog/[id]/page.tsx', ':id'), // Generated path: /blog/:id
|
|
152
|
+
$('blog/$.tsx', '*'), // Wildcard route, matches all unmatched paths under /blog
|
|
151
153
|
]),
|
|
152
|
-
]
|
|
153
|
-
})
|
|
154
|
+
];
|
|
155
|
+
});
|
|
154
156
|
```
|
|
155
157
|
|
|
156
158
|
**Use cases**:
|
|
159
|
+
|
|
157
160
|
- Custom 404 pages
|
|
158
161
|
- Handle all unmatched requests under specific paths
|
|
159
162
|
|
|
@@ -161,7 +164,6 @@ export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
|
|
|
161
164
|
The `$` function has the same functionality as the `$.tsx` file in convention routes, used to catch unmatched route requests.
|
|
162
165
|
:::
|
|
163
166
|
|
|
164
|
-
|
|
165
167
|
## Configuring Routes
|
|
166
168
|
|
|
167
169
|
### Basic Example
|
|
@@ -170,11 +172,11 @@ The `$` function has the same functionality as the `$.tsx` file in convention ro
|
|
|
170
172
|
export default defineRoutes(({ page }, fileRoutes) => {
|
|
171
173
|
return [
|
|
172
174
|
// Use page function to explicitly specify page route
|
|
173
|
-
page(
|
|
174
|
-
page(
|
|
175
|
-
page(
|
|
176
|
-
]
|
|
177
|
-
})
|
|
175
|
+
page('home.tsx', '/'),
|
|
176
|
+
page('about.tsx', 'about'),
|
|
177
|
+
page('contact.tsx', 'contact'),
|
|
178
|
+
];
|
|
179
|
+
});
|
|
178
180
|
```
|
|
179
181
|
|
|
180
182
|
### Routes Without Path
|
|
@@ -186,15 +188,16 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
|
|
|
186
188
|
return [
|
|
187
189
|
// Use layout function to explicitly specify layout route
|
|
188
190
|
// auth/layout.tsx needs to contain <Outlet> to render child routes
|
|
189
|
-
layout(
|
|
190
|
-
page(
|
|
191
|
-
page(
|
|
191
|
+
layout('auth/layout.tsx', [
|
|
192
|
+
page('login/page.tsx', 'login'),
|
|
193
|
+
page('register/page.tsx', 'register'),
|
|
192
194
|
]),
|
|
193
|
-
]
|
|
194
|
-
})
|
|
195
|
+
];
|
|
196
|
+
});
|
|
195
197
|
```
|
|
196
198
|
|
|
197
199
|
The above configuration will generate:
|
|
200
|
+
|
|
198
201
|
- `/login` → `auth/layout.tsx` + `login/page.tsx`
|
|
199
202
|
- `/register` → `auth/layout.tsx` + `register/page.tsx`
|
|
200
203
|
|
|
@@ -203,14 +206,13 @@ The above configuration will generate:
|
|
|
203
206
|
```ts
|
|
204
207
|
export default defineRoutes(({ page }, fileRoutes) => {
|
|
205
208
|
return [
|
|
206
|
-
page(
|
|
207
|
-
page(
|
|
208
|
-
page(
|
|
209
|
-
]
|
|
210
|
-
})
|
|
209
|
+
page('user.tsx', 'user'),
|
|
210
|
+
page('user.tsx', 'profile'),
|
|
211
|
+
page('user.tsx', 'account'),
|
|
212
|
+
];
|
|
213
|
+
});
|
|
211
214
|
```
|
|
212
215
|
|
|
213
|
-
|
|
214
216
|
### Dynamic Routes
|
|
215
217
|
|
|
216
218
|
Config routes support dynamic route parameters:
|
|
@@ -219,15 +221,14 @@ Config routes support dynamic route parameters:
|
|
|
219
221
|
export default defineRoutes(({ page }, fileRoutes) => {
|
|
220
222
|
return [
|
|
221
223
|
// Required parameter
|
|
222
|
-
page(
|
|
224
|
+
page('blog/detail.tsx', 'blog/:id'),
|
|
223
225
|
|
|
224
226
|
// Optional parameter
|
|
225
|
-
page(
|
|
226
|
-
]
|
|
227
|
-
})
|
|
227
|
+
page('blog/index.tsx', 'blog/:slug?'),
|
|
228
|
+
];
|
|
229
|
+
});
|
|
228
230
|
```
|
|
229
231
|
|
|
230
|
-
|
|
231
232
|
## Automatic Route-Related File Discovery
|
|
232
233
|
|
|
233
234
|
Config routes automatically discover component-related files without manual configuration. For any component file specified in `modern.routes.ts`, Modern.js will automatically find the following related files:
|
|
@@ -236,10 +237,10 @@ Config routes automatically discover component-related files without manual conf
|
|
|
236
237
|
// modern.routes.ts
|
|
237
238
|
export default defineRoutes(({ route }, fileRoutes) => {
|
|
238
239
|
return [
|
|
239
|
-
route(
|
|
240
|
-
route(
|
|
241
|
-
]
|
|
242
|
-
})
|
|
240
|
+
route('pages/profile.tsx', 'profile'),
|
|
241
|
+
route('pages/user/detail.tsx', 'user/:id'),
|
|
242
|
+
];
|
|
243
|
+
});
|
|
243
244
|
```
|
|
244
245
|
|
|
245
246
|
Modern.js will automatically find and load:
|
|
@@ -6,7 +6,13 @@ To use Playwright in Modern.js, you need to install the dependencies first. You
|
|
|
6
6
|
|
|
7
7
|
import { PackageManagerTabs } from '@theme';
|
|
8
8
|
|
|
9
|
-
<PackageManagerTabs
|
|
9
|
+
<PackageManagerTabs
|
|
10
|
+
command={{
|
|
11
|
+
npm: 'npm init playwright',
|
|
12
|
+
yarn: 'yarn create playwright',
|
|
13
|
+
pnpm: 'pnpm create playwright',
|
|
14
|
+
}}
|
|
15
|
+
/>
|
|
10
16
|
|
|
11
17
|
The above commands will automatically install Playwright dependencies and help you install and configure it in your project through a series of prompts, including adding a `playwright.config.ts` file.
|
|
12
18
|
|
|
@@ -74,18 +80,18 @@ export default Index;
|
|
|
74
80
|
Next, add test cases to ensure the links on your pages work properly.
|
|
75
81
|
|
|
76
82
|
```ts title="tests/example.spec.ts"
|
|
77
|
-
import { test, expect } from '@playwright/test'
|
|
83
|
+
import { test, expect } from '@playwright/test';
|
|
78
84
|
|
|
79
85
|
test('should navigate to the about page', async ({ page }) => {
|
|
80
86
|
// Start from the index page (the baseURL is set via the webServer in the playwright.config.ts)
|
|
81
|
-
await page.goto('http://localhost:8080/')
|
|
87
|
+
await page.goto('http://localhost:8080/');
|
|
82
88
|
// Find an element with the text 'About' and click on it
|
|
83
|
-
await page.click('text=About')
|
|
89
|
+
await page.click('text=About');
|
|
84
90
|
// The new URL should be "/about" (baseURL is used there)
|
|
85
|
-
await expect(page).toHaveURL('http://localhost:8080/about')
|
|
91
|
+
await expect(page).toHaveURL('http://localhost:8080/about');
|
|
86
92
|
// The new page should contain an h1 with "About"
|
|
87
|
-
await expect(page.locator('h1')).toContainText('About')
|
|
88
|
-
})
|
|
93
|
+
await expect(page.locator('h1')).toContainText('About');
|
|
94
|
+
});
|
|
89
95
|
```
|
|
90
96
|
|
|
91
97
|
## Run Test Cases
|
|
@@ -108,4 +114,4 @@ Running 3 tests using 3 workers
|
|
|
108
114
|
To open last HTML report run:
|
|
109
115
|
|
|
110
116
|
npx playwright show-report
|
|
111
|
-
```
|
|
117
|
+
```
|
|
@@ -84,9 +84,9 @@ test('Page', async () => {
|
|
|
84
84
|
</Router>,
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
await expect
|
|
88
|
-
page.getByRole('heading', { level: 1, name: 'Home' })
|
|
89
|
-
|
|
87
|
+
await expect
|
|
88
|
+
.element(page.getByRole('heading', { level: 1, name: 'Home' }))
|
|
89
|
+
.toBeVisible();
|
|
90
90
|
});
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -181,12 +181,14 @@ First install and use the migrate-to-rstest skill. If it is not installed, insta
|
|
|
181
181
|
npx skills add rstackjs/agent-skills --skill migrate-to-rstest
|
|
182
182
|
|
|
183
183
|
Follow the migrate-to-rstest skill instructions and the official Rstest migration guides:
|
|
184
|
+
|
|
184
185
|
- Jest: https://rstest.rs/guide/migration/jest
|
|
185
186
|
- Vitest: https://rstest.rs/guide/migration/vitest
|
|
186
187
|
|
|
187
188
|
Modern.js-specific requirement:
|
|
189
|
+
|
|
188
190
|
- Install and use @modern-js/adapter-rstest together with @rstest/core.
|
|
189
191
|
- Create or update rstest.config.ts to import withModernConfig from @modern-js/adapter-rstest.
|
|
190
192
|
- Reuse the Modern.js app configuration with extends: withModernConfig().
|
|
191
193
|
- Do not replace this with a plain Rstest config unless the project explicitly does not need Modern.js config integration.`}
|
|
192
|
-
/>
|
|
194
|
+
/>
|
|
@@ -15,10 +15,10 @@ AI agents use them to get APIs, config, and conventions that exactly match your
|
|
|
15
15
|
|
|
16
16
|
## AGENTS.md
|
|
17
17
|
|
|
18
|
-
`AGENTS.md` gives AI coding agents project-level guidance — telling them to read the bundled docs before making changes and to follow Modern.js conventions.
|
|
18
|
+
`AGENTS.md` gives AI coding agents project-level guidance — telling them to read the bundled docs before making changes and to follow Modern.js conventions.
|
|
19
19
|
|
|
20
|
-
- **New projects**: `npx @modern-js/create` generates
|
|
21
|
-
- **Existing projects**: run `npx @modern-js/create --agents-md-only` at the project root to create or update
|
|
20
|
+
- **New projects**: `npx @modern-js/create` generates `AGENTS.md` by default; pass `--no-agents-md` to skip it.
|
|
21
|
+
- **Existing projects**: run `npx @modern-js/create --agents-md-only` at the project root to create or update `AGENTS.md`. Re-run it any time; your own additions are preserved.
|
|
22
22
|
|
|
23
23
|
Modern.js only maintains the content inside the `<!-- BEGIN:modernjs-agent-rules -->` markers in `AGENTS.md`; anything you write outside them is left untouched.
|
|
24
24
|
|
|
@@ -35,9 +35,9 @@ Use it when you need content beyond the bundled docs — just let your agent ret
|
|
|
35
35
|
|
|
36
36
|
Skills are on-demand AI capabilities following the [Agent Skills open standard](https://github.com/vercel-labs/skills). User-facing Skills:
|
|
37
37
|
|
|
38
|
-
| Skill
|
|
39
|
-
|
|
40
|
-
| Upgrade to v3
|
|
38
|
+
| Skill | Identifier | Description |
|
|
39
|
+
| --------------- | ------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
40
|
+
| Upgrade to v3 | `modernjs-migrate-to-v3` | Migrate a v2 app to v3: safe rewrites + manual checklist + migration report |
|
|
41
41
|
| Enable features | `modernjs-feature-enable` | Enable BFF / SSG / styled-components for v3 apps, and scaffold Tailwind CSS / custom Web Server |
|
|
42
42
|
|
|
43
43
|
> Skills are not force-installed or implicitly installed — you install them explicitly. RSC and micro-frontend setups are configuration or architecture decisions, not one-click `modernjs-feature-enable` actions.
|
|
@@ -63,9 +63,9 @@ At this point, the `publicPath` defined in the producer's build output `mf-manif
|
|
|
63
63
|
"name": "remote",
|
|
64
64
|
"publicPath": "https://my-remote-module/"
|
|
65
65
|
},
|
|
66
|
-
"shared": [
|
|
66
|
+
"shared": [/* xxx */],
|
|
67
67
|
"remotes": [],
|
|
68
|
-
"exposes": [
|
|
68
|
+
"exposes": [/* xxx */]
|
|
69
69
|
}
|
|
70
70
|
```
|
|
71
71
|
|
|
@@ -33,4 +33,3 @@ For more details, refer to [Using Module Federation](/guides/topic-detail/module
|
|
|
33
33
|
Module Federation 2.0 offers the [Bridge](https://module-federation.io/practice/bridge/overview.html) capability to load application-level modules.
|
|
34
34
|
|
|
35
35
|
Modern.js, based on Bridge and its internal implementation, provides APIs to easily export application-level modules. For more details, refer to [Application-Level Modules](/guides/topic-detail/module-federation/application).
|
|
36
|
-
|
|
@@ -22,6 +22,18 @@ server: {
|
|
|
22
22
|
}
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
### dev.lazyCompilation
|
|
26
|
+
|
|
27
|
+
**Change**: The default value in development has changed. Pure CSR and streaming SSR applications enable lazy compilation by default with `{ imports: true, entries: false }`; applications using string SSR, RSC or SSG keep it disabled by default. This only affects development and does not change production build output.
|
|
28
|
+
|
|
29
|
+
**Migration Example**: To keep the 2.0 behavior, disable it explicitly:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
dev: {
|
|
33
|
+
lazyCompilation: false;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
25
37
|
## html
|
|
26
38
|
|
|
27
39
|
### html.appIcon
|
|
@@ -22,10 +22,10 @@ If your project's deployment configuration specifies a particular entry file nam
|
|
|
22
22
|
|
|
23
23
|
Modern.js 3.0 has adjusted some runtime paths, and related import paths need to be updated. The path mapping is as follows:
|
|
24
24
|
|
|
25
|
-
| Old Path
|
|
26
|
-
|
|
27
|
-
| `@modern-js/runtime/bff`
|
|
28
|
-
| `@modern-js/runtime/server` | `@modern-js/server-runtime`
|
|
25
|
+
| Old Path | New Path | Description |
|
|
26
|
+
| --------------------------- | ------------------------------- | ------------------------ |
|
|
27
|
+
| `@modern-js/runtime/bff` | `@modern-js/plugin-bff/runtime` | BFF runtime path |
|
|
28
|
+
| `@modern-js/runtime/server` | `@modern-js/server-runtime` | Server-side runtime path |
|
|
29
29
|
|
|
30
30
|
## useRuntimeContext Deprecated
|
|
31
31
|
|