@modern-js/main-doc 3.1.5 → 3.2.0
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/components/international/init-options-desc.mdx +1 -1
- package/docs/en/components/international/install-command.mdx +4 -17
- package/docs/en/components/international/instance-code.mdx +4 -14
- package/docs/en/components/international/introduce.mdx +4 -1
- package/docs/en/configure/app/source/enable-async-pre-entry.mdx +30 -0
- package/docs/en/configure/app/tools/dev-server.mdx +0 -4
- package/docs/en/guides/advanced-features/international/_meta.json +0 -1
- package/docs/en/guides/advanced-features/international/advanced.mdx +48 -109
- package/docs/en/guides/advanced-features/international/api.mdx +125 -290
- package/docs/en/guides/advanced-features/international/best-practices.mdx +203 -48
- package/docs/en/guides/advanced-features/international/configuration.mdx +108 -315
- package/docs/en/guides/advanced-features/international/locale-detection.mdx +62 -208
- package/docs/en/guides/advanced-features/international/quick-start.mdx +41 -55
- package/docs/en/guides/advanced-features/international/resource-loading.mdx +63 -322
- package/docs/en/guides/advanced-features/international/routing.mdx +60 -138
- package/docs/en/guides/advanced-features/international.mdx +19 -27
- package/docs/en/guides/basic-features/alias.mdx +1 -1
- package/docs/en/guides/basic-features/html.mdx +2 -2
- package/docs/en/guides/basic-features/static-assets.mdx +1 -2
- package/docs/en/guides/concept/entries.mdx +2 -2
- package/docs/zh/components/international/init-options-desc.mdx +1 -1
- package/docs/zh/components/international/install-command.mdx +4 -16
- package/docs/zh/components/international/instance-code.mdx +4 -14
- package/docs/zh/components/international/introduce.mdx +5 -2
- package/docs/zh/configure/app/source/enable-async-pre-entry.mdx +77 -0
- package/docs/zh/configure/app/tools/dev-server.mdx +0 -4
- package/docs/zh/guides/advanced-features/bff/function.mdx +2 -2
- package/docs/zh/guides/advanced-features/international/_meta.json +0 -1
- package/docs/zh/guides/advanced-features/international/advanced.mdx +48 -109
- package/docs/zh/guides/advanced-features/international/api.mdx +126 -292
- package/docs/zh/guides/advanced-features/international/best-practices.mdx +204 -49
- package/docs/zh/guides/advanced-features/international/configuration.mdx +105 -318
- package/docs/zh/guides/advanced-features/international/locale-detection.mdx +62 -236
- package/docs/zh/guides/advanced-features/international/quick-start.mdx +40 -54
- package/docs/zh/guides/advanced-features/international/resource-loading.mdx +62 -324
- package/docs/zh/guides/advanced-features/international/routing.mdx +58 -136
- package/docs/zh/guides/advanced-features/international.mdx +19 -26
- package/docs/zh/guides/basic-features/alias.mdx +1 -1
- package/docs/zh/guides/basic-features/html.mdx +2 -2
- package/docs/zh/guides/basic-features/static-assets.mdx +1 -2
- package/docs/zh/guides/concept/entries.mdx +2 -2
- package/package.json +4 -4
- package/docs/en/components/rspackPrecautions.mdx +0 -6
- package/docs/en/guides/advanced-features/international/basic.mdx +0 -417
- package/docs/zh/components/rspackPrecautions.mdx +0 -6
- package/docs/zh/guides/advanced-features/international/basic.mdx +0 -416
|
@@ -4,149 +4,101 @@ title: Routing Integration
|
|
|
4
4
|
|
|
5
5
|
# Routing Integration
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Enable Locale Path Prefixes
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
After setting `localePathRedirect: true`, the plugin takes over language recognition and navigation in the URL. It does four things:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
**
|
|
11
|
+
1. **Recognizes the locale prefix in the URL**: When visiting `/zh/detail`, the plugin extracts `zh` from the path as the current language.
|
|
12
|
+
2. **Automatically redirects paths without prefixes**: When visiting `/detail`, it first detects the language with the detector. If detection fails, it uses `fallbackLanguage`, then redirects to `/en/detail` or `/zh/detail`.
|
|
13
|
+
3. **Synchronizes the URL when switching language**: If the current URL is `/en/detail`, calling `changeLanguage('zh')` automatically changes the URL to `/zh/detail`, instead of only changing i18next's internal language state.
|
|
14
|
+
4. **Avoids duplicate path detection**: The plugin automatically removes `path` from the i18next detector `order`, because path language recognition is already handled by the plugin itself.
|
|
14
15
|
|
|
15
16
|
```ts
|
|
17
|
+
// modern.config.ts
|
|
16
18
|
i18nPlugin({
|
|
17
19
|
localeDetection: {
|
|
18
20
|
localePathRedirect: true,
|
|
19
21
|
languages: ['zh', 'en'],
|
|
20
22
|
fallbackLanguage: 'en',
|
|
21
|
-
// Optional: ignore automatic redirection for certain routes
|
|
22
|
-
ignoreRedirectRoutes: ['/api', '/admin'],
|
|
23
23
|
},
|
|
24
24
|
});
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Some routes (such as API routes, static resources, etc.) don't need language prefixes. You can use the `ignoreRedirectRoutes` configuration to ignore automatic redirection for these routes:
|
|
27
|
+
**Result:**
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
fallbackLanguage: 'en',
|
|
37
|
-
// String array: supports exact match and prefix match
|
|
38
|
-
ignoreRedirectRoutes: ['/api', '/admin', '/static'],
|
|
39
|
-
// Or use function for more flexible judgment
|
|
40
|
-
ignoreRedirectRoutes: pathname => {
|
|
41
|
-
return pathname.startsWith('/api') || pathname.startsWith('/admin');
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
```
|
|
29
|
+
| Visited path | Result |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `/about` | Redirects to `/en/about` |
|
|
32
|
+
| `/en/about` | Visits normally, language is `en` |
|
|
33
|
+
| `/zh/about` | Visits normally, language is `zh` |
|
|
46
34
|
|
|
47
|
-
|
|
35
|
+
Some paths, such as API routes and static assets, do not need locale prefixes. Use `ignoreRedirectRoutes` to skip redirects. See [Locale Detection -> ignoreRedirectRoutes](./locale-detection.md#ignoreredirectroutes).
|
|
48
36
|
|
|
49
37
|
## Route Configuration
|
|
50
38
|
|
|
51
|
-
After enabling
|
|
39
|
+
After enabling `localePathRedirect`, add a `[lang]` dynamic parameter in routes to receive the locale prefix.
|
|
52
40
|
|
|
53
|
-
###
|
|
41
|
+
### File-system Routes
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
Create a `[lang]` directory under `routes/`:
|
|
56
44
|
|
|
57
|
-
```
|
|
45
|
+
```
|
|
58
46
|
routes/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
│ └── contact/
|
|
65
|
-
│ └── page.tsx # Contact page
|
|
47
|
+
└── [lang]/
|
|
48
|
+
├── layout.tsx <- You can read params.lang here.
|
|
49
|
+
├── page.tsx
|
|
50
|
+
└── about/
|
|
51
|
+
└── page.tsx
|
|
66
52
|
```
|
|
67
53
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
import { Outlet } from '@modern-js/runtime/router';
|
|
54
|
+
Generated route structure:
|
|
72
55
|
|
|
73
|
-
export default function Layout() {
|
|
74
|
-
return <Outlet />;
|
|
75
|
-
}
|
|
76
56
|
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
export default function Home() {
|
|
82
|
-
return <div>Home</div>;
|
|
83
|
-
}
|
|
57
|
+
/:lang -> page.tsx
|
|
58
|
+
/:lang/about -> about/page.tsx
|
|
84
59
|
```
|
|
85
60
|
|
|
86
|
-
|
|
61
|
+
If you need to read the current language parameter in a layout or page:
|
|
87
62
|
|
|
88
63
|
```tsx
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**routes/[lang]/contact/page.tsx**:
|
|
64
|
+
// routes/[lang]/layout.tsx
|
|
65
|
+
import { Outlet, useParams } from '@modern-js/runtime/router';
|
|
95
66
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
67
|
+
export default function Layout() {
|
|
68
|
+
const { lang } = useParams();
|
|
69
|
+
// lang is the language code in the current URL, such as 'en' or 'zh'.
|
|
70
|
+
// Usually you do not need to use it manually. useModernI18n() manages it automatically.
|
|
71
|
+
return <Outlet />;
|
|
99
72
|
}
|
|
100
73
|
```
|
|
101
74
|
|
|
102
|
-
|
|
75
|
+
### Custom Routes
|
|
103
76
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/:lang/contact → Contact page
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
When accessing `/` or `/about`, it will automatically redirect to `/en` or `/en/about` (using the default language).
|
|
111
|
-
|
|
112
|
-
### Custom Routing
|
|
77
|
+
:::info
|
|
78
|
+
Custom routes are only needed when you are not using the Modern.js file-system routing system. File-system routes are recommended for most projects.
|
|
79
|
+
:::
|
|
113
80
|
|
|
114
|
-
If
|
|
81
|
+
If you use a custom route file (`modern.routes.ts`), add the `:lang` parameter manually:
|
|
115
82
|
|
|
116
83
|
```tsx
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Outlet,
|
|
122
|
-
} from '@modern-js/runtime/router';
|
|
123
|
-
|
|
124
|
-
function App() {
|
|
84
|
+
// modern.routes.ts
|
|
85
|
+
import { Route, Routes, Outlet } from '@modern-js/runtime/router';
|
|
86
|
+
|
|
87
|
+
export default function App() {
|
|
125
88
|
return (
|
|
126
|
-
<
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
<Route path="
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
<Route path="contact" element={<Contact />} />
|
|
133
|
-
</Route>
|
|
134
|
-
</Routes>
|
|
135
|
-
</BrowserRouter>
|
|
89
|
+
<Routes>
|
|
90
|
+
<Route path=":lang" element={<Outlet />}>
|
|
91
|
+
<Route index element={<Home />} />
|
|
92
|
+
<Route path="about" element={<About />} />
|
|
93
|
+
</Route>
|
|
94
|
+
</Routes>
|
|
136
95
|
);
|
|
137
96
|
}
|
|
138
97
|
```
|
|
139
98
|
|
|
140
|
-
:::info
|
|
141
|
-
Convention-based routing will automatically generate corresponding routes based on the file structure. It's recommended to use convention-based routing. Only use custom routing when special route control is needed.
|
|
142
|
-
|
|
143
|
-
:::
|
|
144
|
-
|
|
145
99
|
## I18nLink Component
|
|
146
100
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
### Basic Usage
|
|
101
|
+
`I18nLink` is a locale-aware link component. It automatically adds the current locale prefix to the target path, so you do not need to concatenate it manually.
|
|
150
102
|
|
|
151
103
|
```tsx
|
|
152
104
|
import { I18nLink } from '@modern-js/plugin-i18n/runtime';
|
|
@@ -156,57 +108,27 @@ function Navigation() {
|
|
|
156
108
|
<nav>
|
|
157
109
|
<I18nLink to="/">Home</I18nLink>
|
|
158
110
|
<I18nLink to="/about">About</I18nLink>
|
|
159
|
-
<I18nLink to="/contact">Contact</I18nLink>
|
|
111
|
+
<I18nLink to="/contact" replace>Contact</I18nLink>
|
|
160
112
|
</nav>
|
|
161
113
|
);
|
|
162
114
|
}
|
|
163
115
|
```
|
|
164
116
|
|
|
165
|
-
**When current language is `en
|
|
166
|
-
|
|
167
|
-
- `<I18nLink to="/">` → Actual link: `/en`
|
|
168
|
-
- `<I18nLink to="/about">` → Actual link: `/en/about`
|
|
169
|
-
|
|
170
|
-
**When current language is `zh`**:
|
|
117
|
+
**When the current language is `en`:**
|
|
171
118
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
119
|
+
```
|
|
120
|
+
<I18nLink to="/about"> -> Actual link: /en/about
|
|
121
|
+
<I18nLink to="/"> -> Actual link: /en
|
|
122
|
+
```
|
|
176
123
|
|
|
177
|
-
|
|
124
|
+
**Notes:**
|
|
178
125
|
|
|
179
126
|
```tsx
|
|
180
|
-
//
|
|
127
|
+
// Correct: no need to add the locale prefix manually.
|
|
181
128
|
<I18nLink to="/about">About</I18nLink>
|
|
182
129
|
|
|
183
|
-
//
|
|
130
|
+
// Incorrect: do not add the locale prefix manually, or it becomes /en/en/about.
|
|
184
131
|
<I18nLink to="/en/about">About</I18nLink>
|
|
185
132
|
```
|
|
186
133
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`I18nLink` accepts all `Link` component props and additionally supports:
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
interface I18nLinkProps {
|
|
193
|
-
/** Target path (no need to include language prefix) */
|
|
194
|
-
to: string;
|
|
195
|
-
/** Child elements */
|
|
196
|
-
children: React.ReactNode;
|
|
197
|
-
/** Other Link component props */
|
|
198
|
-
[key: string]: any;
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
**Example**:
|
|
203
|
-
|
|
204
|
-
```tsx
|
|
205
|
-
<I18nLink to="/about" replace>
|
|
206
|
-
About
|
|
207
|
-
</I18nLink>
|
|
208
|
-
|
|
209
|
-
<I18nLink to="/contact" state={{ from: 'home' }}>
|
|
210
|
-
Contact
|
|
211
|
-
</I18nLink>
|
|
212
|
-
```
|
|
134
|
+
`I18nLink` extends the `Link` component from `@modern-js/runtime/router` and supports all standard Link props such as `replace`, `state`, and `className`. For the full Props type, see [API Reference](./api.md#i18nlink-component).
|
|
@@ -8,30 +8,22 @@ import I18nPluginIntroduce from '@site-docs/components/international/introduce';
|
|
|
8
8
|
|
|
9
9
|
<I18nPluginIntroduce />
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
- [Quick Start](./international/quick-start) - Detailed installation and configuration guide
|
|
31
|
-
- [Configuration](./international/configuration) - CLI and runtime configuration details
|
|
32
|
-
- [Locale Detection](./international/locale-detection) - Multiple language detection methods and priorities
|
|
33
|
-
- [Resource Loading](./international/resource-loading) - HTTP, FS, and SDK backend usage
|
|
34
|
-
- [Routing Integration](./international/routing) - Path redirection and I18nLink component
|
|
35
|
-
- [API Reference](./international/api) - Complete API documentation and type definitions
|
|
36
|
-
- [Advanced Usage](./international/advanced) - SSR, multi-entry, custom instances, and more
|
|
37
|
-
- [Best Practices](./international/best-practices) - Resource organization, error handling, type safety
|
|
11
|
+
## Where to start?
|
|
12
|
+
|
|
13
|
+
| What you want to do | Documentation |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Integrate for the first time and run an example | [Quick Start](./international/quick-start.md) |
|
|
16
|
+
| Learn all configuration options | [Configuration](./international/configuration.md) |
|
|
17
|
+
| Detect language from URL / Cookie / Header | [Locale Detection](./international/locale-detection.md) |
|
|
18
|
+
| Implement paths with locale prefixes, such as `/en/about` | [Routing Integration](./international/routing.md) |
|
|
19
|
+
| Load translation resources from a remote service or platform | [Resource Loading -> Custom Backend](./international/resource-loading.md#custom-backend) |
|
|
20
|
+
| SSR, multiple entries, or custom instances | [Advanced Usage](./international/advanced.md) |
|
|
21
|
+
| Look up Hooks / components / type definitions | [API Reference](./international/api.md) |
|
|
22
|
+
|
|
23
|
+
## Core Capabilities
|
|
24
|
+
|
|
25
|
+
- **Locale detection**: Supports detection from URL path, Cookie, LocalStorage, request headers, browser settings, and other sources, with configurable priority.
|
|
26
|
+
- **Resource loading**: Supports HTTP static files, file system loading for SSR, custom SDK functions, and chained backend progressive loading.
|
|
27
|
+
- **Routing integration**: Automatically adds locale path prefixes such as `/en/about`, and provides the `I18nLink` component for locale-aware navigation.
|
|
28
|
+
- **SSR support**: Detects the language on the server and injects it into the page so the client can reuse it directly and avoid language flicker.
|
|
29
|
+
- **TypeScript support**: Provides complete type definitions and supports type-safe translation keys.
|
|
@@ -37,7 +37,7 @@ You can refer to the [TypeScript - paths](https://www.typescriptlang.org/tsconfi
|
|
|
37
37
|
|
|
38
38
|
## Use `source.alias` Configuration
|
|
39
39
|
|
|
40
|
-
Modern.js provides the [source.alias](/configure/app/source/alias) configuration option
|
|
40
|
+
Modern.js provides the [source.alias](/configure/app/source/alias) configuration option. You can configure this option using an object or a function.
|
|
41
41
|
|
|
42
42
|
### Use Cases
|
|
43
43
|
|
|
@@ -190,7 +190,7 @@ Under the application root directory, create the `config/html/` directory, which
|
|
|
190
190
|
<head>
|
|
191
191
|
<%= topTemplate %>
|
|
192
192
|
<%= headTemplate %>
|
|
193
|
-
{/*
|
|
193
|
+
{/* rspack inject css */}
|
|
194
194
|
</head>
|
|
195
195
|
<body>
|
|
196
196
|
<noscript>
|
|
@@ -199,7 +199,7 @@ Under the application root directory, create the `config/html/` directory, which
|
|
|
199
199
|
</noscript>
|
|
200
200
|
<div id="<%= mountId %>"></div>
|
|
201
201
|
<%= bodyTemplate %>
|
|
202
|
-
{/*
|
|
202
|
+
{/* rspack inject js */}
|
|
203
203
|
{/* <?- bottomTemplate ?> */}
|
|
204
204
|
</body>
|
|
205
205
|
</html>
|
|
@@ -123,7 +123,7 @@ After adding the type declaration, if the type error still exists, you can try t
|
|
|
123
123
|
|
|
124
124
|
## Extend Asset Types
|
|
125
125
|
|
|
126
|
-
If the built-in asset types in Modern.js cannot meet your requirements, you can modify the built-in
|
|
126
|
+
If the built-in asset types in Modern.js cannot meet your requirements, you can modify the built-in Rspack configuration and extend the asset types you need using [tools.bundlerChain](/configure/app/tools/bundler-chain).
|
|
127
127
|
|
|
128
128
|
For example, if you want to treat `*.pdf` files as assets and directly output them to the dist directory, you can add the following configuration:
|
|
129
129
|
|
|
@@ -151,7 +151,6 @@ console.log(myFile); // "/static/myFile.6c12aba3.pdf"
|
|
|
151
151
|
For more information about asset modules, please refer to:
|
|
152
152
|
|
|
153
153
|
- [Rspack Documentation - Asset modules](https://rspack.rs/guide/asset-module.html#asset-modules)
|
|
154
|
-
- [webpack Documentation - Asset modules](https://webpack.js.org/guides/asset-modules/)
|
|
155
154
|
|
|
156
155
|
## Image Format
|
|
157
156
|
|
|
@@ -273,13 +273,13 @@ export default defineConfig({
|
|
|
273
273
|
|
|
274
274
|
## In-Depth
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
Pages usually correspond to HTML output files, meaning each additional entry will eventually generate a corresponding HTML file in the output. The modules imported by the entry will be compiled and packaged into multiple Chunk outputs. For example, JavaScript modules may ultimately generate several file outputs similar to `dist/static/js/index.ea39u8.js`.
|
|
277
277
|
|
|
278
278
|
It's important to distinguish the relationships between concepts such as entry and route:
|
|
279
279
|
|
|
280
280
|
- **Entry**: Contains multiple modules used for startup execution.
|
|
281
281
|
- **Client Router**: In Modern.js, it is usually implemented by `react-router`, using the History API to determine which React component to load and display based on the browser's current URL.
|
|
282
|
-
- **Server Router**:
|
|
282
|
+
- **Server Router**: Determines what content the server returns based on the request URL. For traditional multi-page applications, different URLs usually return different HTML pages directly. For single-page applications that use client-side routing, the server generally falls back non-static asset requests to the entry HTML, and then the frontend takes over subsequent route matching and page rendering.
|
|
283
283
|
|
|
284
284
|
Their corresponding relationships are as follows:
|
|
285
285
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
支持所有 [i18next 初始化选项](https://www.i18next.com/overview/configuration-options),常用选项说明如下:
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
pnpm add @modern-js/plugin-i18n i18next react-i18next
|
|
3
|
-
```
|
|
1
|
+
`i18next` 和 `react-i18next` 是 **Peer Dependency**,需要手动安装。
|
|
4
2
|
|
|
5
|
-
:::
|
|
6
|
-
|
|
3
|
+
:::note 版本一致性
|
|
4
|
+
`@modern-js/plugin-i18n` 需要与项目中 `@modern-js/app-tools` 版本保持一致。
|
|
5
|
+
:::
|
|
7
6
|
|
|
8
|
-
请先检查 `@modern-js/app-tools` 的版本,然后安装相同版本的 `@modern-js/plugin-i18n`:
|
|
9
7
|
|
|
10
8
|
```bash
|
|
11
|
-
# 检查当前 @modern-js/app-tools 的版本
|
|
12
9
|
pnpm list @modern-js/app-tools
|
|
13
|
-
|
|
14
|
-
# 安装相同版本的 @modern-js/plugin-i18n
|
|
15
10
|
pnpm add @modern-js/plugin-i18n@<version> i18next react-i18next
|
|
16
11
|
```
|
|
17
|
-
|
|
18
|
-
:::
|
|
19
|
-
|
|
20
|
-
:::info
|
|
21
|
-
`i18next` 和 `react-i18next` 是 peer dependencies,需要手动安装。
|
|
22
|
-
|
|
23
|
-
:::
|
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
创建 `src/modern.runtime.ts
|
|
1
|
+
创建 `src/modern.runtime.ts`:
|
|
2
2
|
|
|
3
3
|
```ts
|
|
4
4
|
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
5
5
|
import i18next from 'i18next';
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// i18next 默认导出一个全局单例,多个应用共用会互相影响。
|
|
8
|
+
// createInstance() 创建独立实例,确保每个应用有独立的语言状态。
|
|
8
9
|
const i18nInstance = i18next.createInstance();
|
|
9
10
|
|
|
10
11
|
export default defineRuntimeConfig({
|
|
11
12
|
i18n: {
|
|
12
|
-
i18nInstance
|
|
13
|
-
initOptions: {
|
|
14
|
-
fallbackLng: 'en',
|
|
15
|
-
supportedLngs: ['zh', 'en'],
|
|
16
|
-
},
|
|
13
|
+
i18nInstance,
|
|
17
14
|
},
|
|
18
15
|
});
|
|
19
16
|
```
|
|
20
|
-
|
|
21
|
-
:::info
|
|
22
|
-
`modern.runtime.ts` 是运行时配置文件,用于配置 i18next 的初始化选项。即使是最基础的配置,也建议创建此文件以确保插件正常工作。
|
|
23
|
-
|
|
24
|
-
建议使用 `i18next.createInstance()` 创建一个新的实例,而不是直接使用默认导出的 `i18next`,这样可以避免全局状态污染,并确保每个应用都有独立的 i18n 实例。
|
|
25
|
-
|
|
26
|
-
:::
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
`@modern-js/plugin-i18n` 是 Modern.js 的国际化插件,基于
|
|
2
|
-
|
|
1
|
+
`@modern-js/plugin-i18n` 是 Modern.js 的国际化插件,基于 [i18next](https://www.i18next.com/) 和 [react-i18next](https://react.i18next.com/) 构建。
|
|
2
|
+
|
|
3
|
+
- **插件本身**:负责与 Modern.js 框架的集成,如 SSR 语言传递、路由前缀处理等
|
|
4
|
+
- **i18next**:核心翻译能力,如 `t()` 函数、插值、复数、命名空间。
|
|
5
|
+
- **react-i18next**:React 组件和 Hook,如 `useTranslation`,实现与 React 生命周期的结合。
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: enableAsyncPreEntry
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# source.enableAsyncPreEntry
|
|
6
|
+
|
|
7
|
+
- **类型:** `boolean`
|
|
8
|
+
- **默认值:** `false`
|
|
9
|
+
|
|
10
|
+
开启后,Modern.js 会在自动生成的入口文件(`index.jsx`)最上方依次插入 `source.preEntry` 中配置的模块 import。
|
|
11
|
+
|
|
12
|
+
该配置仅在 `source.enableAsyncEntry` 开启时生效;如果未开启异步入口,则不会启用该行为(并保持 `source.preEntry` 原有的构建器注入逻辑不受影响)。
|
|
13
|
+
|
|
14
|
+
该配置主要用于配合 `source.enableAsyncEntry` 使用:当启用异步入口时,最终的构建 entry 会变为 `bootstrap.jsx`,这会导致构建器侧的 `source.preEntry` 不一定能注入到真正的入口代码中。开启 `source.enableAsyncPreEntry` 后,`preEntry` 会注入到 `index.jsx`(真正的入口代码)顶部,从而保证在异步入口场景下也能生效。
|
|
15
|
+
|
|
16
|
+
同时,当 `source.enableAsyncPreEntry` 开启时,Modern.js 不会将 `source.preEntry` 传递给构建器配置,避免重复注入或注入到不期望的 entry 中。
|
|
17
|
+
|
|
18
|
+
## 示例
|
|
19
|
+
|
|
20
|
+
```ts title="modern.config.ts"
|
|
21
|
+
import { defineConfig } from '@modern-js/app-tools';
|
|
22
|
+
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
source: {
|
|
25
|
+
enableAsyncEntry: true,
|
|
26
|
+
enableAsyncPreEntry: true,
|
|
27
|
+
preEntry: ['./src/pre-a.ts', './src/pre-b.ts'],
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 编译效果
|
|
33
|
+
|
|
34
|
+
在开启 `source.enableAsyncEntry` 后,Modern.js 会为每个入口生成一个异步边界文件 `bootstrap.jsx`,并由它去动态加载真正的入口代码 `index.jsx`。
|
|
35
|
+
|
|
36
|
+
当同时开启 `source.enableAsyncPreEntry` 时,Modern.js 会把 `source.preEntry` 以 `import` 的形式注入到 **`index.jsx` 的最顶部**(而不是注入到 `bootstrap.jsx`),保证异步入口场景下 `preEntry` 一定会在入口代码之前执行。
|
|
37
|
+
|
|
38
|
+
### 生成文件结构
|
|
39
|
+
|
|
40
|
+
以单入口 `main` 为例,生成的文件结构大致如下(位于 `node_modules/.modern-js/main/`):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
node_modules
|
|
44
|
+
└─ .modern-js
|
|
45
|
+
└─ main
|
|
46
|
+
├─ bootstrap.jsx # 最终用于构建的 entry(异步边界)
|
|
47
|
+
├─ index.jsx # 真正的入口代码(会被注入 preEntry import)
|
|
48
|
+
├─ register.js
|
|
49
|
+
├─ runtime-register.js
|
|
50
|
+
└─ runtime-global-context.js
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### bootstrap.jsx
|
|
54
|
+
|
|
55
|
+
`bootstrap.jsx` 的核心逻辑是通过 dynamic import 加载 `index.jsx`:
|
|
56
|
+
|
|
57
|
+
```js title="node_modules/.modern-js/main/bootstrap.jsx"
|
|
58
|
+
import(/* webpackChunkName: "async-main" */ './index');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### index.jsx(会注入 preEntry)
|
|
62
|
+
|
|
63
|
+
开启 `source.enableAsyncPreEntry` 后,`index.jsx` 文件的最上方会被注入 `source.preEntry` 对应的 import,随后才是 Modern.js 生成的入口逻辑,例如:
|
|
64
|
+
|
|
65
|
+
```js title="node_modules/.modern-js/main/index.jsx"
|
|
66
|
+
import '@_modern_js_src/pre-a.ts';
|
|
67
|
+
import '@_modern_js_src/pre-b.ts';
|
|
68
|
+
|
|
69
|
+
import '@modern-js/runtime/registry/main';
|
|
70
|
+
// ...后续为 Modern.js 自动生成的入口逻辑
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
其中 `@_modern_js_src` 是 Modern.js 内部用于指向项目 `src` 目录的别名(实际值会随项目 metaName 等信息变化)。
|
|
74
|
+
|
|
75
|
+
### 与 builder 的关系
|
|
76
|
+
|
|
77
|
+
当 `source.enableAsyncEntry` 与 `source.enableAsyncPreEntry` 同时开启时,Modern.js **不会再把 `source.preEntry` 传递给构建器配置**,避免构建器重复注入或注入到不期望的 entry 中。
|
|
@@ -9,10 +9,6 @@ title: devServer
|
|
|
9
9
|
|
|
10
10
|
通过 `tools.devServer` 可以修改开发环境服务器的配置。
|
|
11
11
|
|
|
12
|
-
:::tip
|
|
13
|
-
Modern.js 中并没有直接使用 [webpack-dev-server](https://webpack.js.org/api/webpack-dev-server/) 或 [@rspack/dev-server](https://rspack.rs/guide/dev-server.html), 而是基于 [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) 实现 DevServer。
|
|
14
|
-
:::
|
|
15
|
-
|
|
16
12
|
### 选项
|
|
17
13
|
|
|
18
14
|
#### compress
|
|
@@ -188,7 +188,7 @@ Dynamic Path 之后的参数是包含 querystring、request body 的对象 `Requ
|
|
|
188
188
|
在不存在动态路由的普通函数中,可以从第一个入参中获取传入的 `data` 和 `query`,例如:
|
|
189
189
|
|
|
190
190
|
```ts title="api/lambda/hello.ts"
|
|
191
|
-
import type { RequestOption } from '@modern-js/server
|
|
191
|
+
import type { RequestOption } from '@modern-js/plugin-bff/server';
|
|
192
192
|
|
|
193
193
|
export async function post({
|
|
194
194
|
query,
|
|
@@ -201,7 +201,7 @@ export async function post({
|
|
|
201
201
|
这里你也可以使用自定义类型:
|
|
202
202
|
|
|
203
203
|
```ts title="api/lambda/hello.ts"
|
|
204
|
-
import type { RequestOption } from '@modern-js/server
|
|
204
|
+
import type { RequestOption } from '@modern-js/plugin-bff/server';
|
|
205
205
|
|
|
206
206
|
type IQuery = {
|
|
207
207
|
// some types
|