@modern-js/main-doc 3.0.1 → 3.0.3
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/_nav.json +1 -1
- package/docs/en/apis/app/commands.mdx +1 -1
- package/docs/en/community/blog/_meta.json +7 -1
- package/docs/en/community/blog/v3-release-note.mdx +628 -0
- package/docs/en/components/rsbuild.mdx +1 -1
- package/docs/en/configure/app/builder-plugins.mdx +1 -1
- package/docs/en/configure/app/dev/server.mdx +5 -5
- package/docs/en/configure/app/resolve/alias-strategy.mdx +1 -1
- package/docs/en/configure/app/resolve/dedupe.mdx +1 -1
- package/docs/en/configure/app/security/sri.mdx +1 -1
- package/docs/en/configure/app/server/rsc.mdx +2 -2
- package/docs/en/configure/app/source/decorators.mdx +1 -1
- package/docs/en/configure/app/tools/bundler-chain.mdx +1 -1
- package/docs/en/configure/app/tools/swc.mdx +2 -2
- package/docs/en/guides/advanced-features/compatibility.mdx +1 -1
- package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
- package/docs/en/guides/basic-features/css/css.mdx +4 -4
- package/docs/en/guides/basic-features/css/tailwindcss.mdx +2 -2
- package/docs/en/guides/basic-features/render/rsc.mdx +137 -8
- package/docs/en/guides/concept/builder.mdx +3 -3
- package/docs/en/guides/get-started/tech-stack.mdx +3 -3
- package/docs/en/guides/topic-detail/module-federation/application.mdx +6 -6
- package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/en/guides/topic-detail/module-federation/i18n.mdx +12 -12
- package/docs/en/guides/topic-detail/module-federation/introduce.mdx +1 -1
- package/docs/en/guides/topic-detail/module-federation/ssr.mdx +4 -4
- package/docs/en/guides/topic-detail/module-federation/usage.mdx +7 -7
- package/docs/en/guides/troubleshooting/builder.mdx +4 -4
- package/docs/en/guides/upgrade/config.mdx +31 -3
- package/docs/en/guides/upgrade/other.mdx +50 -0
- package/docs/en/guides/upgrade/overview.mdx +1 -1
- package/docs/en/guides/upgrade/tailwindcss.mdx +1 -1
- package/docs/en/plugin/cli-plugins/api.mdx +9 -9
- package/docs/en/plugin/introduction.mdx +5 -5
- package/docs/zh/_nav.json +1 -1
- package/docs/zh/apis/app/commands.mdx +1 -1
- package/docs/zh/community/blog/_meta.json +7 -1
- package/docs/zh/community/blog/v3-release-note.mdx +628 -0
- package/docs/zh/components/rsbuild.mdx +1 -1
- package/docs/zh/configure/app/builder-plugins.mdx +1 -1
- package/docs/zh/configure/app/dev/server.mdx +5 -5
- package/docs/zh/configure/app/resolve/alias-strategy.mdx +1 -1
- package/docs/zh/configure/app/resolve/dedupe.mdx +1 -1
- package/docs/zh/configure/app/security/sri.mdx +1 -1
- package/docs/zh/configure/app/server/rsc.mdx +2 -2
- package/docs/zh/configure/app/source/decorators.mdx +1 -1
- package/docs/zh/configure/app/tools/bundler-chain.mdx +1 -1
- package/docs/zh/configure/app/tools/swc.mdx +2 -2
- package/docs/zh/guides/advanced-features/compatibility.mdx +1 -1
- package/docs/zh/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
- package/docs/zh/guides/basic-features/css/css.mdx +4 -4
- package/docs/zh/guides/basic-features/css/tailwindcss.mdx +2 -2
- package/docs/zh/guides/basic-features/render/rsc.mdx +222 -8
- package/docs/zh/guides/concept/builder.mdx +3 -3
- package/docs/zh/guides/get-started/tech-stack.mdx +3 -3
- package/docs/zh/guides/topic-detail/module-federation/application.mdx +6 -6
- package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/zh/guides/topic-detail/module-federation/i18n.mdx +12 -12
- package/docs/zh/guides/topic-detail/module-federation/introduce.mdx +1 -1
- package/docs/zh/guides/topic-detail/module-federation/ssr.mdx +4 -4
- package/docs/zh/guides/topic-detail/module-federation/usage.mdx +7 -7
- package/docs/zh/guides/troubleshooting/builder.mdx +4 -4
- package/docs/zh/guides/upgrade/config.mdx +31 -3
- package/docs/zh/guides/upgrade/other.md +50 -0
- package/docs/zh/guides/upgrade/overview.mdx +1 -1
- package/docs/zh/guides/upgrade/tailwindcss.mdx +1 -1
- package/docs/zh/plugin/cli-plugins/api.mdx +9 -9
- package/docs/zh/plugin/introduction.mdx +5 -5
- package/package.json +3 -3
- package/src/components/RsbuildLink/index.tsx +1 -1
- package/src/i18n/enUS.ts +5 -1
- package/src/i18n/zhCN.ts +5 -1
- package/src/pages/index.module.scss +93 -0
- package/src/pages/index.tsx +13 -1
package/docs/en/_nav.json
CHANGED
|
@@ -150,7 +150,7 @@ Options:
|
|
|
150
150
|
|
|
151
151
|
## modern inspect
|
|
152
152
|
|
|
153
|
-
The `modern inspect` command is used to view the Modern.js config, [Rsbuild config](https://rsbuild.rs/config/index) and Rspack config of the project.
|
|
153
|
+
The `modern inspect` command is used to view the Modern.js config, [Rsbuild config](https://v2.rsbuild.rs/config/index) and Rspack config of the project.
|
|
154
154
|
|
|
155
155
|
```bash
|
|
156
156
|
Usage: modern inspect [options]
|
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Modern.js v3 Release
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Modern.js v3 Release: Focused on web framework, embracing ecosystem development
|
|
7
|
+
|
|
8
|
+
> Published on 2025.02.06
|
|
9
|
+
|
|
10
|
+
## Introduction
|
|
11
|
+
|
|
12
|
+
It has been three years since the [Modern.js 2.0 release](./v2-release-note.mdx). We sincerely thank the community developers for using and trusting Modern.js. Modern.js has maintained a steady iteration pace, with over 100 versions released.
|
|
13
|
+
|
|
14
|
+
In Bytedance, the web development framework based on Modern.js has become mainstream. The proportion of active web projects in the company has grown from 43% at the beginning of 2025 to nearly 70% now.
|
|
15
|
+
|
|
16
|
+
Over these three years, we have continuously added new features, performed code refactoring and optimizations, and received extensive community feedback. These experiences have become important references for the improvements in version 3.0. After careful consideration, we decided to release Modern.js 3.0, delivering a comprehensive upgrade to the framework.
|
|
17
|
+
|
|
18
|
+
## The Evolution from Modern.js 2.0 to 3.0
|
|
19
|
+
|
|
20
|
+
From Modern.js 2.0 to 3.0, there are two core transformations:
|
|
21
|
+
|
|
22
|
+
**More Focused: Dedicated to Being a Web Framework**
|
|
23
|
+
|
|
24
|
+
- Modern.js 2.0: Included Modern.js App, Modern.js Module, and Modern.js Doc
|
|
25
|
+
- Modern.js 3.0: Represents only Modern.js App. Modern.js Module and Modern.js Doc have been incubated into [Rslib](https://rslib.rs) and [Rspress](https://rspress.dev)
|
|
26
|
+
|
|
27
|
+
**More Open: Actively Embracing Community Tools**
|
|
28
|
+
|
|
29
|
+
- Modern.js 2.0: Built-in various tools with framework-specific API designs
|
|
30
|
+
- Modern.js 3.0: Strengthened plugin system, improved integration capabilities, and recommends high-quality community solutions
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What's New in Modern.js 3.0
|
|
35
|
+
|
|
36
|
+
### React Server Component
|
|
37
|
+
|
|
38
|
+
:::tip TL;DR
|
|
39
|
+
Modern.js 3.0 integrates React Server Component, supporting both CSR and SSR projects with progressive migration.
|
|
40
|
+
:::
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
#### What is React Server Component
|
|
45
|
+
|
|
46
|
+
React Server Components (RSC) are a new type of component that allows **component logic to execute entirely on the server**, streaming the rendered UI directly to the client. Compared to traditional client components, Server Components offer the following benefits:
|
|
47
|
+
|
|
48
|
+
| Feature | Description |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Zero Client Bundle Size | Component code is not included in the client JS bundle — it only executes on the server, speeding up initial page load and rendering |
|
|
51
|
+
| Higher Cohesion | Components can directly access databases, call internal APIs, and read local files, improving development efficiency |
|
|
52
|
+
| Progressive Enhancement | Can be seamlessly mixed with client components, selectively offloading interactive logic to the client while maintaining high performance and supporting complex interactions |
|
|
53
|
+
|
|
54
|
+
It's important to clarify that RSC and SSR are **fundamentally different concepts**:
|
|
55
|
+
|
|
56
|
+
- **RSC**: Describes the **component type** — where the component executes (server vs. client)
|
|
57
|
+
- **SSR**: Describes the **rendering mode** — where the HTML is generated (server vs. client)
|
|
58
|
+
|
|
59
|
+
The two can be used together: Server Components can be used in SSR projects as well as CSR projects. In Modern.js 3.0, we support both modes, allowing developers to choose based on their needs.
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
#### Out of the Box
|
|
64
|
+
|
|
65
|
+
In Modern.js 3.0, simply enable RSC in the configuration:
|
|
66
|
+
|
|
67
|
+
```ts title="modern.config.ts"
|
|
68
|
+
export default defineConfig({
|
|
69
|
+
server: {
|
|
70
|
+
rsc: true,
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
:::info
|
|
76
|
+
Once enabled, all route components will default to Server Components. Some components in your project may not be able to run on the server — you can add the `'use client'` directive to those components to preserve their original behavior, and then migrate gradually.
|
|
77
|
+
:::
|
|
78
|
+
|
|
79
|
+
<video src="https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/rsc.mp4" controls autoplay loop muted style={{ width: '100%', borderRadius: 8 }} />
|
|
80
|
+
|
|
81
|
+
#### RSC Features in Modern.js 3.0
|
|
82
|
+
|
|
83
|
+
Modern.js has always chosen React Router as its routing solution. Last year, React Router v7 [announced support](https://remix.run/blog/rsc-preview) for React Server Components, which provided the foundation for implementing RSC in SPA applications for Modern.js.
|
|
84
|
+
|
|
85
|
+
Compared to other frameworks in the community, Modern.js has made several optimizations for RSC:
|
|
86
|
+
|
|
87
|
+
- Uses Rspack's latest RSC plugin for building, significantly improving RSC project build speed and further optimizing bundle size.
|
|
88
|
+
- Unlike mainstream community frameworks that only support RSC + SSR, Modern.js 3.0's RSC also supports CSR projects.
|
|
89
|
+
- During route navigation, the framework automatically merges multiple Data Loader and Server Component requests into a single request with streaming responses, improving page performance.
|
|
90
|
+
- In nested routing scenarios, the route component type is not affected by the parent route component type — developers can adopt Server Components starting from any route level.
|
|
91
|
+
|
|
92
|
+
#### Progressive Migration
|
|
93
|
+
|
|
94
|
+
With flexible component boundary control, Modern.js 3.0 provides a progressive migration path. Modern.js 3.0 allows Server Component migration at the **route component level**, without needing to migrate the entire component tree.
|
|
95
|
+
|
|
96
|
+

|
|
97
|
+
|
|
98
|
+
:::info
|
|
99
|
+
For more details on React Server Component, see: [React Server Component](/guides/basic-features/render/rsc)
|
|
100
|
+
:::
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Embracing Rspack
|
|
105
|
+
|
|
106
|
+
:::tip TL;DR
|
|
107
|
+
Modern.js 3.0 removes webpack support, fully embraces Rspack, and upgrades to the latest Rspack & Rsbuild 2.0.
|
|
108
|
+
:::
|
|
109
|
+
|
|
110
|
+
In 2023, we open-sourced Rspack and added support for Rspack as an optional bundler in Modern.js. Internally at ByteDance, over 60% of Modern.js projects have already switched to Rspack for building.
|
|
111
|
+
|
|
112
|
+
After more than two years of development, Rspack has surpassed 10 million monthly downloads in the community, becoming a widely adopted bundler in the industry. Meanwhile, Modern.js's Rspack build mode has also been continuously improved.
|
|
113
|
+
|
|
114
|
+

|
|
115
|
+
|
|
116
|
+
In Modern.js 3.0, we decided to remove webpack support, making Modern.js lighter and more efficient, while taking full advantage of Rspack's new features.
|
|
117
|
+
|
|
118
|
+
#### Smoother Development Experience
|
|
119
|
+
|
|
120
|
+
After removing webpack, Modern.js 3.0 better follows Rspack best practices, with improvements in build performance, installation speed, and more:
|
|
121
|
+
|
|
122
|
+
**Underlying Dependency Upgrades**
|
|
123
|
+
|
|
124
|
+
Modern.js 3.0 upgrades its underlying Rspack and Rsbuild dependencies to version 2.0, and optimizes default build configurations based on the new versions for more consistent behavior.
|
|
125
|
+
|
|
126
|
+
Refer to the following docs for details on underlying behavior changes:
|
|
127
|
+
|
|
128
|
+
- [Rsbuild 2.0 Upgrade Guide](https://v2.rsbuild.rs/guide/upgrade/v1-to-v2)
|
|
129
|
+
- [Rspack 2.0 Breaking Changes](https://github.com/web-infra-dev/rspack/discussions/9270)
|
|
130
|
+
|
|
131
|
+
**Faster Build Speed**
|
|
132
|
+
|
|
133
|
+
Modern.js leverages multiple Rspack features to reduce build time:
|
|
134
|
+
|
|
135
|
+
- Barrel file optimization enabled by default: 20% faster component library builds
|
|
136
|
+
- Persistent caching enabled by default: 50%+ faster non-initial builds
|
|
137
|
+
|
|
138
|
+
**Faster Installation**
|
|
139
|
+
|
|
140
|
+
After removing webpack-related dependencies, Modern.js 3.0 has significantly fewer build dependencies:
|
|
141
|
+
|
|
142
|
+
- 40% fewer npm dependencies
|
|
143
|
+
- 31 MB reduction in installation size
|
|
144
|
+
|
|
145
|
+
#### Smaller Build Output
|
|
146
|
+
|
|
147
|
+
Modern.js now enables multiple Rspack output optimization strategies by default, producing smaller bundles than webpack. For example:
|
|
148
|
+
|
|
149
|
+
**Enhanced Tree Shaking**
|
|
150
|
+
|
|
151
|
+
Enhanced tree shaking analysis can handle more dynamic import patterns, such as destructuring:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// Destructuring in parameters
|
|
155
|
+
import('./module').then(({ value }) => {
|
|
156
|
+
console.log(value);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Destructuring in function body
|
|
160
|
+
import('./module').then((mod) => {
|
|
161
|
+
const { value } = mod;
|
|
162
|
+
console.log(value);
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Constant Inlining**
|
|
167
|
+
|
|
168
|
+
Cross-module constant inlining helps minifiers perform more accurate static analysis, eliminating dead code branches:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
// constants.js
|
|
172
|
+
export const ENABLED = true;
|
|
173
|
+
|
|
174
|
+
// index.js
|
|
175
|
+
import { ENABLED } from './constants';
|
|
176
|
+
if (ENABLED) {
|
|
177
|
+
doSomething();
|
|
178
|
+
} else {
|
|
179
|
+
doSomethingElse();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Build output - dead branch eliminated
|
|
183
|
+
doSomething();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### Full-Chain Extensibility
|
|
189
|
+
|
|
190
|
+
:::tip TL;DR
|
|
191
|
+
Modern.js 3.0 officially opens its complete plugin system, providing runtime and server plugins, along with flexible application entry handling.
|
|
192
|
+
:::
|
|
193
|
+
|
|
194
|
+
Modern.js 2.0 offered CLI plugins and a beta version of runtime plugins, allowing developers to extend their projects. However, in practice, we found the existing capabilities insufficient for complex business scenarios.
|
|
195
|
+
|
|
196
|
+
Modern.js 3.0 provides more flexible customization capabilities, allowing full-lifecycle plugins for applications to help teams unify business logic and reduce duplicate code:
|
|
197
|
+
|
|
198
|
+
- **CLI Plugins**: Extend functionality during the build phase, such as adding commands and modifying configurations
|
|
199
|
+
- **Runtime Plugins**: Extend functionality during the rendering phase, such as data prefetching and component wrapping
|
|
200
|
+
- **Server Plugins**: Extend server-side functionality, such as adding middleware and modifying request/response
|
|
201
|
+
|
|
202
|
+
#### Runtime Plugins
|
|
203
|
+
|
|
204
|
+
Runtime plugins run during both CSR and SSR processes. The new version provides two core hooks:
|
|
205
|
+
|
|
206
|
+
- `onBeforeRender`: Execute logic before rendering, useful for data prefetching and injecting global data
|
|
207
|
+
- `wrapRoot`: Wrap the root component to add global Providers, layout components, etc.
|
|
208
|
+
|
|
209
|
+
You can register plugins in `src/modern.runtime.ts`. Compared to manually importing higher-order components at the entry point, runtime plugins are pluggable, easy to update, and don't need to be imported repeatedly in multi-entry scenarios:
|
|
210
|
+
|
|
211
|
+
```ts title="src/modern.runtime.tsx"
|
|
212
|
+
import { defineRuntimeConfig } from "@modern-js/runtime";
|
|
213
|
+
|
|
214
|
+
export default defineRuntimeConfig({
|
|
215
|
+
plugins: [
|
|
216
|
+
{
|
|
217
|
+
name: "my-runtime-plugin",
|
|
218
|
+
setup: (api) => {
|
|
219
|
+
api.onBeforeRender((context) => {
|
|
220
|
+
context.globalData = { theme: "dark" };
|
|
221
|
+
});
|
|
222
|
+
api.wrapRoot((App) => (props) => <App {...props} />);
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
:::info
|
|
230
|
+
For more on runtime plugin usage, see the docs: [Runtime Plugins](/plugin/runtime-plugins/api)
|
|
231
|
+
:::
|
|
232
|
+
|
|
233
|
+
#### Server Middleware
|
|
234
|
+
|
|
235
|
+
In practice, we found that some projects need to extend the Web Server — for example, authentication, data prefetching, fallback handling, dynamic HTML script injection, and more.
|
|
236
|
+
|
|
237
|
+
In Modern.js 3.0, we rebuilt the Web Server using [Hono](https://hono.dev) and officially opened up server middleware and plugin capabilities. Developers can use Hono middleware to meet their needs:
|
|
238
|
+
|
|
239
|
+
```ts title="server/modern.server.ts"
|
|
240
|
+
import { defineServerConfig, type MiddlewareHandler } from "@modern-js/server-runtime";
|
|
241
|
+
|
|
242
|
+
const timingMiddleware: MiddlewareHandler = async (c, next) => {
|
|
243
|
+
const start = Date.now();
|
|
244
|
+
await next();
|
|
245
|
+
const duration = Date.now() - start;
|
|
246
|
+
c.header('X-Response-Time', `${duration}ms`);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const htmlMiddleware: MiddlewareHandler = async (c, next) => {
|
|
250
|
+
await next();
|
|
251
|
+
const html = await c.res.text();
|
|
252
|
+
const modified = html.replace(
|
|
253
|
+
"<head>",
|
|
254
|
+
'<head><meta name="generator" content="Modern.js">'
|
|
255
|
+
);
|
|
256
|
+
c.res = c.body(modified, { status: c.res.status, headers: c.res.headers });
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export default defineServerConfig({
|
|
260
|
+
middlewares: [timingMiddleware],
|
|
261
|
+
renderMiddlewares: [htmlMiddleware],
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
:::info
|
|
266
|
+
For more on server plugin usage, see the docs: [Custom Web Server](/guides/advanced-features/web-server)
|
|
267
|
+
:::
|
|
268
|
+
|
|
269
|
+
#### Custom Entry
|
|
270
|
+
|
|
271
|
+
In Modern.js 3.0, we redesigned the custom entry API to be clearer and more flexible than the previous version:
|
|
272
|
+
|
|
273
|
+
```ts title="src/entry.tsx"
|
|
274
|
+
import { createRoot } from '@modern-js/runtime/react';
|
|
275
|
+
import { render } from '@modern-js/runtime/browser';
|
|
276
|
+
|
|
277
|
+
const ModernRoot = createRoot();
|
|
278
|
+
|
|
279
|
+
async function beforeRender() {
|
|
280
|
+
// Async operations before rendering, such as initializing SDKs or fetching user info
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
beforeRender().then(() => {
|
|
284
|
+
render(<ModernRoot />);
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
:::info
|
|
289
|
+
For more on entry usage, see the docs: [Entries](/guides/concept/entries)
|
|
290
|
+
:::
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
### Routing Improvements
|
|
295
|
+
|
|
296
|
+
:::tip TL;DR
|
|
297
|
+
Modern.js 3.0 includes React Router v7 built-in, provides config-based routing, and AI-friendly debugging capabilities.
|
|
298
|
+
:::
|
|
299
|
+
|
|
300
|
+
#### Built-in React Router v7
|
|
301
|
+
|
|
302
|
+
In Modern.js 3.0, we upgraded to React Router v7 and deprecated built-in support for v5 and v6. This decision was based on the following considerations:
|
|
303
|
+
|
|
304
|
+
**Version Evolution and Stability**
|
|
305
|
+
|
|
306
|
+
React Router v6 was an important transitional version that introduced many new features (such as data loading and error boundaries). v7 further optimizes performance, stability, and developer experience while maintaining v6 API compatibility. As the React Router team positions Remix as an independent framework, the React Router core library is likely to be maintained long-term on v7, making it a more reliable choice.
|
|
307
|
+
|
|
308
|
+
**Upgrade Path**
|
|
309
|
+
|
|
310
|
+
- **From v6**: React Router v7 is a non-breaking upgrade for v6 developers. In Modern.js 2.0, we already provided React Router v7 plugin support, allowing you to progressively upgrade via the plugin, verify compatibility, and then migrate to Modern.js 3.0.
|
|
311
|
+
- **From v5**: There are significant API changes from v5 to v7. We recommend following the [React Router official migration guide](https://reactrouter.com/upgrading/v5).
|
|
312
|
+
|
|
313
|
+
#### Config-Based Routing
|
|
314
|
+
|
|
315
|
+
In Modern.js, we recommend using convention-based routing to organize code. However, in real-world scenarios, developers occasionally encounter situations like:
|
|
316
|
+
|
|
317
|
+
- Multiple paths pointing to the same component
|
|
318
|
+
- Flexible route control
|
|
319
|
+
- Conditional routing
|
|
320
|
+
- Legacy project migration
|
|
321
|
+
|
|
322
|
+
Therefore, Modern.js 3.0 provides full config-based routing support, which can be used alongside convention-based routing or independently.
|
|
323
|
+
|
|
324
|
+
```ts title="src/modern.routes.ts"
|
|
325
|
+
import { defineRoutes } from "@modern-js/runtime/config-routes";
|
|
326
|
+
|
|
327
|
+
export default defineRoutes(({ route, layout, page }) => {
|
|
328
|
+
return [
|
|
329
|
+
route("home.tsx", "/"),
|
|
330
|
+
route("about.tsx", "about"),
|
|
331
|
+
route("blog.tsx", "blog/:id"),
|
|
332
|
+
];
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
:::info
|
|
337
|
+
For more on config-based routing, see the docs: [Config-Based Routing](/guides/basic-features/routes/config-routes)
|
|
338
|
+
:::
|
|
339
|
+
|
|
340
|
+
#### Route Debugging
|
|
341
|
+
|
|
342
|
+
Run the `npx modern routes` command to generate a complete route structure analysis report in the `dist/routes-inspect.json` file.
|
|
343
|
+
|
|
344
|
+
The report displays each route's path, component file, data loader, error boundary, loading component, and other details, helping developers quickly understand the project's route configuration and troubleshoot routing issues. The structured JSON format is also easy for AI agents to understand and analyze, improving the efficiency of AI-assisted development.
|
|
345
|
+
|
|
346
|
+
:::info
|
|
347
|
+
For usage details, see the docs: [Route Debugging](/guides/basic-features/routes/config-routes#debugging-routes)
|
|
348
|
+
:::
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
### Server-Side Rendering
|
|
353
|
+
|
|
354
|
+
:::tip TL;DR
|
|
355
|
+
Modern.js 3.0 redesigned SSG capabilities, provides flexible caching mechanisms, and further improved fallback strategies.
|
|
356
|
+
:::
|
|
357
|
+
|
|
358
|
+
#### Static Site Generation (SSG)
|
|
359
|
+
|
|
360
|
+
In Modern.js 2.0, we provided static site generation capabilities. This feature is well-suited for pages that can be statically rendered, significantly improving first-screen performance.
|
|
361
|
+
|
|
362
|
+
In the new version, we redesigned SSG:
|
|
363
|
+
|
|
364
|
+
- Data fetching uses Data Loader, consistent with non-SSG scenarios
|
|
365
|
+
- Simplified API with lower learning curve
|
|
366
|
+
- Better integration with convention-based routing
|
|
367
|
+
|
|
368
|
+
In the new version, you can use data loaders for data fetching, consistent with non-SSG scenarios. Then simply specify the routes to render in the `ssg.routes` configuration:
|
|
369
|
+
|
|
370
|
+
```ts title="modern.config.ts"
|
|
371
|
+
export default defineConfig({
|
|
372
|
+
output: {
|
|
373
|
+
ssg: {
|
|
374
|
+
routes: ['/blog'],
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
```ts title="routes/blog/page.data.ts"
|
|
381
|
+
export const loader = async () => {
|
|
382
|
+
const articles = await fetchArticles();
|
|
383
|
+
return { articles };
|
|
384
|
+
};
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
:::info
|
|
388
|
+
For more on SSG usage, see the docs: [SSG](/guides/basic-features/render/ssg)
|
|
389
|
+
:::
|
|
390
|
+
|
|
391
|
+
#### Caching Mechanism
|
|
392
|
+
|
|
393
|
+
Modern.js 3.0 provides caching mechanisms at different levels to help improve first-screen performance. All caches support flexible configuration, such as HTTP-like `stale-while-revalidate` strategies:
|
|
394
|
+
|
|
395
|
+
**Render Cache**
|
|
396
|
+
|
|
397
|
+
Supports caching the entire SSR result page, configured in `server/cache.ts`:
|
|
398
|
+
|
|
399
|
+
```ts title="server/cache.ts"
|
|
400
|
+
import type { CacheOption } from '@modern-js/server-runtime';
|
|
401
|
+
|
|
402
|
+
export const cacheOption: CacheOption = {
|
|
403
|
+
maxAge: 500, // ms
|
|
404
|
+
staleWhileRevalidate: 1000, // ms
|
|
405
|
+
};
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
:::info
|
|
409
|
+
For render cache usage, see the docs: [Render Cache](/guides/basic-features/render/ssr-cache)
|
|
410
|
+
:::
|
|
411
|
+
|
|
412
|
+
**Data Cache**
|
|
413
|
+
|
|
414
|
+
The new version provides a `cache` function that offers finer-grained data-level control compared to render cache. When multiple data requests depend on the same data, `cache` can avoid duplicate requests:
|
|
415
|
+
|
|
416
|
+
```ts title="server/loader.ts"
|
|
417
|
+
import { cache } from "@modern-js/runtime/cache";
|
|
418
|
+
import { fetchUserData, fetchUserProjects, fetchUserTeam } from "./api";
|
|
419
|
+
|
|
420
|
+
// Cache user data to avoid duplicate requests
|
|
421
|
+
const getUser = cache(fetchUserData);
|
|
422
|
+
|
|
423
|
+
const getProjects = async () => {
|
|
424
|
+
const user = await getUser("test-user");
|
|
425
|
+
return fetchUserProjects(user.id);
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const getTeam = async () => {
|
|
429
|
+
const user = await getUser("test-user"); // Reuses cache, no duplicate request
|
|
430
|
+
return fetchUserTeam(user.id);
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
export const loader = async () => {
|
|
434
|
+
// Both getProjects and getTeam depend on getUser, but getUser only executes once
|
|
435
|
+
const [projects, team] = await Promise.all([getProjects(), getTeam()]);
|
|
436
|
+
return { projects, team };
|
|
437
|
+
};
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
:::info
|
|
441
|
+
For more on data cache usage, see the docs: [Data Cache](/guides/basic-features/data/data-cache)
|
|
442
|
+
:::
|
|
443
|
+
|
|
444
|
+
#### Flexible Fallback Strategies
|
|
445
|
+
|
|
446
|
+
Through practice, we have developed multi-dimensional fallback strategies:
|
|
447
|
+
|
|
448
|
+
| Type | Trigger | Fallback Behavior | Use Case |
|
|
449
|
+
| --- | --- | --- | --- |
|
|
450
|
+
| Error Fallback | Data Loader execution error | Triggers ErrorBoundary | Data request error handling |
|
|
451
|
+
| Render Error | Server-side rendering error | Falls back to CSR, reusing existing data for rendering | SSR error handling |
|
|
452
|
+
| Business Fallback | Loader throws `throw Response` | Triggers ErrorBoundary with corresponding HTTP status code | 404, permission checks, and other business scenarios |
|
|
453
|
+
| Client Loader | Configure Client Loader | Bypasses SSR, requests data source directly | Scenarios requiring client-side data fetching |
|
|
454
|
+
| Forced Fallback | Query parameter `?__csr=true` | Skips SSR, returns CSR page | Debugging, temporary fallback |
|
|
455
|
+
| Forced Fallback | Request header `x-modern-ssr-fallback` | Skips SSR, returns CSR page | Gateway-level fallback control |
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
### Lightweight BFF
|
|
460
|
+
|
|
461
|
+
:::tip TL;DR
|
|
462
|
+
Modern.js 3.0 rebuilt the Web Server based on Hono, provides Hono-based integrated functions, and supports cross-project invocation.
|
|
463
|
+
:::
|
|
464
|
+
|
|
465
|
+
#### Hono Integrated Functions
|
|
466
|
+
|
|
467
|
+
In Modern.js 3.0, we use [Hono](https://hono.dev) as the BFF runtime framework, allowing developers to extend the BFF Server using the Hono ecosystem and enjoy Hono's lightweight, high-performance advantages.
|
|
468
|
+
|
|
469
|
+
With `useHonoContext`, you can access the full Hono context, including request information and response headers:
|
|
470
|
+
|
|
471
|
+
```ts title="api/lambda/user.ts"
|
|
472
|
+
import { useHonoContext } from '@modern-js/server-runtime';
|
|
473
|
+
|
|
474
|
+
export const get = async () => {
|
|
475
|
+
const c = useHonoContext();
|
|
476
|
+
const token = c.req.header('Authorization');
|
|
477
|
+
c.header('X-Custom-Header', 'modern-js');
|
|
478
|
+
const id = c.req.query('id');
|
|
479
|
+
|
|
480
|
+
return { userId: id, authenticated: !!token };
|
|
481
|
+
};
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### Cross-Project Invocation
|
|
485
|
+
|
|
486
|
+
Previously, Modern.js BFF could only be used within the current project. We received developer feedback requesting the ability to use BFF across different projects. This is mostly due to migration and operation costs — reusing existing services is clearly more practical than extracting code and deploying a separate service.
|
|
487
|
+
|
|
488
|
+
To ensure developers get an experience similar to local integrated calls, we provide cross-project invocation capabilities.
|
|
489
|
+
|
|
490
|
+
:::info
|
|
491
|
+
For more on BFF usage, see the docs: [BFF](/guides/advanced-features/bff)
|
|
492
|
+
:::
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### Deep Integration with Module Federation
|
|
497
|
+
|
|
498
|
+
:::tip TL;DR
|
|
499
|
+
Modern.js 3.0 deeply integrates with [Module Federation 2.0](https://module-federation.io), supporting MF SSR and application-level module exports.
|
|
500
|
+
:::
|
|
501
|
+
|
|
502
|
+
#### MF SSR
|
|
503
|
+
|
|
504
|
+
Modern.js 3.0 supports using Module Federation in SSR applications, combining module federation with server-side rendering to deliver better first-screen performance.
|
|
505
|
+
|
|
506
|
+
```ts title="modern.config.ts"
|
|
507
|
+
export default defineConfig({
|
|
508
|
+
server: {
|
|
509
|
+
ssr: {
|
|
510
|
+
mode: 'stream',
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
});
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Combined with Module Federation's [data fetching](https://module-federation.io/guide/basic/data-fetch/index.html) capabilities, each remote module can define its own data fetching logic:
|
|
517
|
+
|
|
518
|
+
```ts title="src/components/Button.data.ts"
|
|
519
|
+
export const fetchData = async () => {
|
|
520
|
+
return {
|
|
521
|
+
data: `Server time: ${new Date().toISOString()}`,
|
|
522
|
+
};
|
|
523
|
+
};
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
```tsx title="src/components/Button.tsx"
|
|
527
|
+
export const Button = (props: { mfData: { data: string } }) => {
|
|
528
|
+
return <button>{props.mfData?.data}</button>;
|
|
529
|
+
};
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
#### Application-Level Modules
|
|
533
|
+
|
|
534
|
+
Unlike traditional component-level sharing, Modern.js 3.0 supports exporting **application-level modules** — modules with full routing capabilities that can run like independent applications. This is a key capability for micro-frontend scenarios.
|
|
535
|
+
|
|
536
|
+
**Producer Exports Application**
|
|
537
|
+
|
|
538
|
+
```ts title="src/export-App.tsx"
|
|
539
|
+
import '@modern-js/runtime/registry/index';
|
|
540
|
+
import { render } from '@modern-js/runtime/browser';
|
|
541
|
+
import { createRoot } from '@modern-js/runtime/react';
|
|
542
|
+
import { createBridgeComponent } from '@module-federation/modern-js/react';
|
|
543
|
+
|
|
544
|
+
const ModernRoot = createRoot();
|
|
545
|
+
export const provider = createBridgeComponent({
|
|
546
|
+
rootComponent: ModernRoot,
|
|
547
|
+
render: (Component, dom) => render(Component, dom),
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
export default provider;
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Consumer Loads Application**
|
|
554
|
+
|
|
555
|
+
```tsx title="src/routes/remote/$.tsx"
|
|
556
|
+
import { createRemoteAppComponent } from '@module-federation/modern-js/react';
|
|
557
|
+
import { loadRemote } from '@module-federation/modern-js/runtime';
|
|
558
|
+
|
|
559
|
+
const RemoteApp = createRemoteAppComponent({
|
|
560
|
+
loader: () => loadRemote('remote/app'),
|
|
561
|
+
fallback: ({ error }) => <div>Error: {error.message}</div>,
|
|
562
|
+
loading: <div>Loading...</div>,
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
export default RemoteApp;
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Through the wildcard route `$.tsx`, all requests to `/remote/*` are handled by the remote application, and the remote application's internal routing works normally.
|
|
569
|
+
|
|
570
|
+
:::info
|
|
571
|
+
For more on Module Federation usage, see the docs: [Module Federation](/guides/topic-detail/module-federation/introduce)
|
|
572
|
+
:::
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
### Tech Stack Updates
|
|
577
|
+
|
|
578
|
+
:::tip TL;DR
|
|
579
|
+
Modern.js 3.0 upgrades to React 19, with Node.js 20 as the minimum supported version.
|
|
580
|
+
:::
|
|
581
|
+
|
|
582
|
+
#### React 19
|
|
583
|
+
|
|
584
|
+
Modern.js 3.0 uses React 19 by default for new projects, with React 18 as the minimum supported version.
|
|
585
|
+
|
|
586
|
+
If your project is still using React 16 or React 17, please first complete the version upgrade following the [React 19 official upgrade guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide).
|
|
587
|
+
|
|
588
|
+
#### Node.js 20
|
|
589
|
+
|
|
590
|
+
As Node.js continues to evolve, Node.js 18 has reached EOL. In Modern.js 3.0, we recommend using Node.js 22 LTS and no longer guarantee support for Node.js 18.
|
|
591
|
+
|
|
592
|
+
#### Storybook Rsbuild
|
|
593
|
+
|
|
594
|
+
In Modern.js 3.0, we implemented Storybook for Modern.js applications based on [Storybook Rsbuild](https://github.com/rspack-contrib/storybook-rsbuild).
|
|
595
|
+
|
|
596
|
+
Through a Storybook Addon, we convert and merge Modern.js configuration into Rsbuild configuration, and use Storybook Rsbuild to drive the build, keeping Storybook debugging aligned with development command configurations.
|
|
597
|
+
|
|
598
|
+
:::info
|
|
599
|
+
For more on Storybook usage, see the docs: [Using Storybook](/guides/basic-features/debug/using-storybook)
|
|
600
|
+
:::
|
|
601
|
+
|
|
602
|
+
#### Using Biome
|
|
603
|
+
|
|
604
|
+
As community tooling continues to evolve, faster and simpler toolchains have matured. In Modern.js 3.0, new projects use [Biome](https://biomejs.dev/) by default for code linting and formatting.
|
|
605
|
+
|
|
606
|
+
---
|
|
607
|
+
|
|
608
|
+
## Upgrading from Modern.js 2.0 to 3.0
|
|
609
|
+
|
|
610
|
+
### Key Changes
|
|
611
|
+
|
|
612
|
+
Upgrading to Modern.js 3.0 means embracing a lighter, more standards-aligned modern development paradigm. By fully aligning with mainstream ecosystems like Rspack and React 19, it eliminates maintenance pain points caused by legacy dependencies and significantly improves build and runtime performance.
|
|
613
|
+
|
|
614
|
+
Going forward, we will also provide more AI integrations and best practices based on Modern.js 3.0. Combined with the flexible full-stack plugin system, developers can reuse community knowledge with minimal learning cost, achieving a transformative improvement in development efficiency and modern application architecture.
|
|
615
|
+
|
|
616
|
+
:::info
|
|
617
|
+
For more improvements and changes, see the docs: [Upgrade Guide](/guides/upgrade/overview)
|
|
618
|
+
:::
|
|
619
|
+
|
|
620
|
+
## Feedback and Community
|
|
621
|
+
|
|
622
|
+
Finally, we once again thank every developer who has given us feedback and support. We will continue to communicate with the community and grow together.
|
|
623
|
+
|
|
624
|
+
If you encounter any issues, feel free to reach out through the following channels:
|
|
625
|
+
|
|
626
|
+
- [GitHub Issues](https://github.com/web-infra-dev/modern.js/issues)
|
|
627
|
+
- [Discord](https://discord.gg/qPCqYg38De)
|
|
628
|
+
- [Lark](https://applink.larkoffice.com/client/chat/chatter/add_by_link?link_token=d21hc667-9403-48a9-ba32-bc1440a80279)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
[Rsbuild](https://rsbuild.rs/) is an Rspack-based build tool for the web. The main goal of Rsbuild is to provide out-of-the-box build capabilities for Rspack users, allowing developers to start a web project with zero configuration.
|
|
1
|
+
[Rsbuild](https://v2.rsbuild.rs/) is an Rspack-based build tool for the web. The main goal of Rsbuild is to provide out-of-the-box build capabilities for Rspack users, allowing developers to start a web project with zero configuration.
|
|
2
2
|
|
|
3
3
|
Rsbuild integrates high-performance Rust-based tools from the community, including Rspack and SWC, to provide first-class build speed and development experience.
|
|
@@ -9,7 +9,7 @@ sidebar_position: 21
|
|
|
9
9
|
|
|
10
10
|
Used to configure the Rsbuild plugin.
|
|
11
11
|
|
|
12
|
-
Rsbuild is the build tool of Modern.js, please read [Build Engine](/guides/concept/builder) for background. If you want to know how to write Rsbuild plugins, you can refer to [Rsbuild - Plugin System](https://rsbuild.rs/plugins/dev/index).
|
|
12
|
+
Rsbuild is the build tool of Modern.js, please read [Build Engine](/guides/concept/builder) for background. If you want to know how to write Rsbuild plugins, you can refer to [Rsbuild - Plugin System](https://v2.rsbuild.rs/plugins/dev/index).
|
|
13
13
|
|
|
14
14
|
## Precautions
|
|
15
15
|
|