@modern-js/main-doc 3.0.0-alpha.0 → 3.0.0-alpha.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/commands.mdx +6 -30
- package/docs/en/components/bff-upload.mdx +3 -5
- package/docs/en/components/bundler.mdx +1 -1
- package/docs/en/components/enable-bff.mdx +6 -2
- package/docs/en/components/enable-ssg.mdx +1 -0
- package/docs/en/components/esbuild.mdx +2 -2
- package/docs/en/components/extend-bff-function.mdx +2 -4
- package/docs/en/components/hono.mdx +119 -0
- package/docs/en/components/international/custom-instance-code.mdx +16 -0
- package/docs/en/components/international/init-options-desc.mdx +1 -0
- package/docs/en/components/international/install-command.mdx +15 -1
- package/docs/en/components/international/instance-code.mdx +26 -0
- package/docs/en/configure/app/builder-plugins.mdx +1 -2
- package/docs/en/configure/app/dev/server.mdx +108 -0
- package/docs/en/configure/app/experiments/source-build.mdx +0 -1
- package/docs/en/configure/app/output/assets-retry.mdx +1 -1
- package/docs/en/configure/app/output/disable-inline-runtime-chunk.mdx +2 -2
- package/docs/en/configure/app/output/filename.mdx +2 -4
- package/docs/en/configure/app/output/temp-dir.mdx +3 -3
- package/docs/en/configure/app/performance/build-cache.mdx +1 -1
- package/docs/en/configure/app/performance/profile.mdx +1 -1
- package/docs/en/configure/app/plugins.mdx +1 -3
- package/docs/en/configure/app/runtime/router.mdx +0 -4
- package/docs/en/configure/app/security/sri.mdx +0 -1
- package/docs/en/configure/app/source/alias.mdx +1 -1
- package/docs/en/configure/app/source/enable-async-entry.mdx +1 -1
- package/docs/en/configure/app/source/include.mdx +2 -14
- package/docs/en/configure/app/tools/dev-server.mdx +8 -8
- package/docs/en/configure/app/usage.mdx +0 -12
- package/docs/en/guides/_meta.json +5 -0
- package/docs/en/guides/advanced-features/bff/_meta.json +9 -1
- package/docs/en/guides/advanced-features/bff/cross-project.mdx +1 -1
- package/docs/en/guides/advanced-features/bff/frameworks.mdx +2 -15
- package/docs/en/guides/advanced-features/bff/function.mdx +4 -4
- package/docs/en/guides/advanced-features/bff/operators.mdx +628 -0
- package/docs/en/guides/advanced-features/bff/sdk.mdx +17 -9
- package/docs/en/guides/advanced-features/bff/upload.mdx +3 -1
- package/docs/en/guides/advanced-features/international/configuration.mdx +7 -16
- package/docs/en/guides/advanced-features/international/quick-start.mdx +4 -32
- package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
- package/docs/en/guides/advanced-features/page-performance/react-compiler.mdx +18 -4
- package/docs/en/guides/advanced-features/rspack-start.mdx +1 -1
- package/docs/en/guides/advanced-features/server-monitor/monitors.mdx +62 -5
- package/docs/en/guides/basic-features/data/data-cache.mdx +60 -76
- package/docs/en/guides/basic-features/data/data-fetch.mdx +15 -14
- package/docs/en/guides/basic-features/debug/proxy.mdx +6 -9
- package/docs/en/guides/basic-features/render/rsc.mdx +24 -19
- package/docs/en/guides/basic-features/render/ssg.mdx +4 -9
- package/docs/en/guides/basic-features/render/ssr-cache.mdx +0 -4
- package/docs/en/guides/basic-features/static-assets/svg-assets.mdx +0 -4
- package/docs/en/guides/get-started/tech-stack.mdx +1 -1
- package/docs/en/guides/upgrade/_meta.json +1 -0
- package/docs/en/guides/upgrade/config.mdx +936 -0
- package/docs/en/guides/upgrade/entry.mdx +463 -0
- package/docs/en/guides/upgrade/other.mdx +83 -0
- package/docs/en/guides/upgrade/overview.mdx +33 -0
- package/docs/en/guides/upgrade/tailwindcss.mdx +130 -0
- package/docs/en/guides/upgrade/web-server.mdx +91 -0
- package/docs/en/plugin/_meta.json +5 -0
- package/docs/en/plugin/cli-plugins/_meta.json +1 -1
- package/docs/en/plugin/cli-plugins/api.mdx +13 -63
- package/docs/en/plugin/cli-plugins/life-cycle.mdx +0 -4
- package/docs/en/plugin/introduction.mdx +8 -20
- package/docs/en/plugin/plugin-system.mdx +3 -3
- package/docs/en/plugin/runtime-plugins/_meta.json +1 -1
- package/docs/en/plugin/runtime-plugins/api.mdx +1 -1
- package/docs/en/plugin/server-plugins/_meta.json +1 -0
- package/docs/en/plugin/server-plugins/api.mdx +210 -1
- package/docs/en/plugin/server-plugins/life-cycle.mdx +41 -1
- package/docs/zh/apis/app/commands.mdx +6 -30
- package/docs/zh/components/bff-operator-code.mdx +5 -0
- package/docs/zh/components/bff-upload.mdx +0 -2
- package/docs/zh/components/bundler.mdx +1 -1
- package/docs/zh/components/enable-bff.mdx +6 -2
- package/docs/zh/components/enable-ssg.mdx +3 -1
- package/docs/zh/components/esbuild.mdx +2 -2
- package/docs/zh/components/extend-bff-function.mdx +2 -4
- package/docs/zh/components/hono.mdx +119 -0
- package/docs/zh/components/international/custom-instance-code.mdx +16 -0
- package/docs/zh/components/international/init-options-desc.mdx +1 -0
- package/docs/zh/components/international/install-command.mdx +15 -0
- package/docs/zh/components/international/instance-code.mdx +26 -0
- package/docs/zh/configure/app/builder-plugins.mdx +1 -2
- package/docs/zh/configure/app/dev/server.mdx +109 -2
- package/docs/zh/configure/app/experiments/source-build.mdx +0 -1
- package/docs/zh/configure/app/output/assets-retry.mdx +1 -1
- package/docs/zh/configure/app/output/disable-inline-runtime-chunk.mdx +2 -2
- package/docs/zh/configure/app/output/filename.mdx +2 -4
- package/docs/zh/configure/app/output/temp-dir.mdx +3 -3
- package/docs/zh/configure/app/performance/build-cache.mdx +1 -1
- package/docs/zh/configure/app/performance/profile.mdx +1 -1
- package/docs/zh/configure/app/plugins.mdx +1 -2
- package/docs/zh/configure/app/runtime/router.mdx +0 -4
- package/docs/zh/configure/app/security/sri.mdx +0 -1
- package/docs/zh/configure/app/source/alias.mdx +1 -1
- package/docs/zh/configure/app/source/enable-async-entry.mdx +1 -1
- package/docs/zh/configure/app/source/include.mdx +2 -16
- package/docs/zh/configure/app/tools/dev-server.mdx +5 -5
- package/docs/zh/configure/app/usage.mdx +0 -12
- package/docs/zh/guides/advanced-features/bff/_meta.json +9 -1
- package/docs/zh/guides/advanced-features/bff/frameworks.mdx +2 -16
- package/docs/zh/guides/advanced-features/bff/operators.mdx +628 -0
- package/docs/zh/guides/advanced-features/bff/sdk.mdx +19 -12
- package/docs/zh/guides/advanced-features/bff/upload.mdx +3 -1
- package/docs/zh/guides/advanced-features/international/configuration.mdx +7 -16
- package/docs/zh/guides/advanced-features/international/quick-start.mdx +2 -25
- package/docs/zh/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
- package/docs/zh/guides/advanced-features/page-performance/react-compiler.mdx +18 -4
- package/docs/zh/guides/advanced-features/server-monitor/monitors.mdx +60 -5
- package/docs/zh/guides/basic-features/data/data-cache.mdx +47 -54
- package/docs/zh/guides/basic-features/data/data-fetch.mdx +9 -12
- package/docs/zh/guides/basic-features/debug/proxy.mdx +4 -7
- package/docs/zh/guides/basic-features/render/rsc.mdx +23 -37
- package/docs/zh/guides/basic-features/render/ssr-cache.mdx +0 -4
- package/docs/zh/guides/basic-features/static-assets/svg-assets.mdx +0 -4
- package/docs/zh/guides/get-started/tech-stack.mdx +1 -1
- package/docs/zh/guides/troubleshooting/builder.mdx +1 -1
- package/docs/zh/guides/upgrade/config.mdx +132 -1
- package/docs/zh/plugin/_meta.json +5 -0
- package/docs/zh/plugin/cli-plugins/_meta.json +1 -1
- package/docs/zh/plugin/cli-plugins/api.mdx +15 -65
- package/docs/zh/plugin/cli-plugins/life-cycle.mdx +0 -4
- package/docs/zh/plugin/introduction.mdx +4 -16
- package/docs/zh/plugin/plugin-system.mdx +3 -14
- package/docs/zh/plugin/runtime-plugins/_meta.json +1 -1
- package/docs/zh/plugin/runtime-plugins/api.mdx +1 -1
- package/docs/zh/plugin/server-plugins/_meta.json +1 -0
- package/docs/zh/plugin/server-plugins/api.mdx +210 -1
- package/docs/zh/plugin/server-plugins/life-cycle.mdx +41 -1
- package/package.json +2 -2
- package/src/components/FrameworkCode/index.tsx +605 -0
- package/docs/en/configure/app/performance/bundle-analyze.mdx +0 -24
- package/docs/en/configure/app/tools/babel.mdx +0 -225
- package/docs/en/plugin/cli-plugins/migration.mdx +0 -83
- package/docs/en/plugin/runtime-plugins/migration.mdx +0 -110
- package/docs/zh/components/default-mwa-generate.mdx +0 -4
- package/docs/zh/configure/app/performance/bundle-analyze.mdx +0 -24
- package/docs/zh/configure/app/tools/babel.mdx +0 -224
- package/docs/zh/plugin/cli-plugins/migration.mdx +0 -83
- package/docs/zh/plugin/runtime-plugins/migration.mdx +0 -110
- /package/docs/en/components/{router-legacy-tip.mdx → upgrade-config-deploy.mdx} +0 -0
- /package/docs/zh/components/{router-legacy-tip.mdx → upgrade-config-deploy.mdx} +0 -0
|
@@ -335,29 +335,20 @@ export default defineRuntimeConfig({
|
|
|
335
335
|
|
|
336
336
|
### i18nInstance 配置
|
|
337
337
|
|
|
338
|
-
如果需要使用自定义的
|
|
338
|
+
如果需要使用自定义的 i18n 实例,可以在运行时配置中提供:
|
|
339
339
|
|
|
340
|
-
|
|
341
|
-
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
342
|
-
import i18next from 'i18next';
|
|
340
|
+
import CustomInstanceCode from '@site-docs/components/international/custom-instance-code';
|
|
343
341
|
|
|
344
|
-
|
|
345
|
-
const customI18n = i18next.createInstance({
|
|
346
|
-
// 自定义配置
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
export default defineRuntimeConfig({
|
|
350
|
-
i18n: {
|
|
351
|
-
i18nInstance: customI18n,
|
|
352
|
-
},
|
|
353
|
-
});
|
|
354
|
-
```
|
|
342
|
+
<CustomInstanceCode />
|
|
355
343
|
|
|
356
344
|
### initOptions 配置
|
|
357
345
|
|
|
358
|
-
|
|
346
|
+
import InitOptionsDesc from '@site-docs/components/international/init-options-desc';
|
|
347
|
+
|
|
348
|
+
<InitOptionsDesc />
|
|
359
349
|
|
|
360
350
|
:::info
|
|
351
|
+
|
|
361
352
|
如果启用了 `localePathRedirect`,`detection` 配置应该在 CLI 配置中设置,而不是在 `initOptions` 中。这是因为服务端插件需要读取 CLI 配置中的 `detection` 选项来进行语言检测和路径重定向。
|
|
362
353
|
:::
|
|
363
354
|
|
|
@@ -51,32 +51,9 @@ export default defineConfig({
|
|
|
51
51
|
|
|
52
52
|
### 在 `src/modern.runtime.ts` 中配置运行时选项
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
import InstanceCode from '@site-docs/components/international/instance-code';
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
58
|
-
import i18next from 'i18next';
|
|
59
|
-
|
|
60
|
-
// 建议创建一个新的 i18next 实例,避免使用全局默认实例
|
|
61
|
-
const i18nInstance = i18next.createInstance();
|
|
62
|
-
|
|
63
|
-
export default defineRuntimeConfig({
|
|
64
|
-
i18n: {
|
|
65
|
-
i18nInstance: i18nInstance,
|
|
66
|
-
initOptions: {
|
|
67
|
-
fallbackLng: 'en',
|
|
68
|
-
supportedLngs: ['zh', 'en'],
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
:::info
|
|
75
|
-
`modern.runtime.ts` 是运行时配置文件,用于配置 i18next 的初始化选项。即使是最基础的配置,也建议创建此文件以确保插件正常工作。
|
|
76
|
-
|
|
77
|
-
建议使用 `i18next.createInstance()` 创建一个新的实例,而不是直接使用默认导出的 `i18next`,这样可以避免全局状态污染,并确保每个应用都有独立的 i18n 实例。
|
|
78
|
-
|
|
79
|
-
:::
|
|
56
|
+
<InstanceCode />
|
|
80
57
|
|
|
81
58
|
### 创建语言资源文件
|
|
82
59
|
|
|
@@ -6,11 +6,25 @@ React Compiler 是 React 19 引入的一个实验性编译器,它可以自动
|
|
|
6
6
|
|
|
7
7
|
## 如何使用
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### React 19
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
如果你使用的是 React 19,Modern.js 已内置支持 React Compiler,无需额外配置即可使用。
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### React 17 或 18
|
|
14
|
+
|
|
15
|
+
如果你使用的是 React 17 或 18,需要按照以下步骤配置:
|
|
16
|
+
|
|
17
|
+
1. 安装 `react-compiler-runtime`,以允许编译后的代码在 19 之前的版本上运行:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react-compiler-runtime
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. 安装 `babel-plugin-react-compiler`:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install babel-plugin-react-compiler
|
|
27
|
+
```
|
|
14
28
|
|
|
15
29
|
3. 在你的 Modern.js 配置文件中注册 Babel 插件:
|
|
16
30
|
|
|
@@ -24,7 +38,7 @@ export default defineConfig({
|
|
|
24
38
|
[
|
|
25
39
|
'babel-plugin-react-compiler',
|
|
26
40
|
{
|
|
27
|
-
target: '18',
|
|
41
|
+
target: '18', // 或 '17',根据你使用的 React 版本
|
|
28
42
|
},
|
|
29
43
|
],
|
|
30
44
|
]);
|
|
@@ -73,11 +73,7 @@ Modern.js 内置了默认的 Monitor,不同的事件会触发内置 Monitor
|
|
|
73
73
|
|
|
74
74
|
## 注册 Monitors
|
|
75
75
|
|
|
76
|
-
开发者可以通过 Monitors 的 `push` API 注册自己的 Monitor,但只能在[服务端中间件](/guides/advanced-features/web-server#unstable-middleware)
|
|
77
|
-
|
|
78
|
-
:::note
|
|
79
|
-
目前暂未开放服务端插件,后续会补充相关文档。
|
|
80
|
-
:::
|
|
76
|
+
开发者可以通过 Monitors 的 `push` API 注册自己的 Monitor,但只能在[服务端中间件](/guides/advanced-features/web-server#unstable-middleware)或[服务端插件](/plugin/server-plugins/api)中注册,在 Data Loader、组件、init 函数中无法注册。
|
|
81
77
|
|
|
82
78
|
```ts title="server/modern.server.ts"
|
|
83
79
|
import {
|
|
@@ -114,6 +110,65 @@ export default defineServerConfig({
|
|
|
114
110
|
});
|
|
115
111
|
```
|
|
116
112
|
|
|
113
|
+
在服务端插件中注册 Monitor:
|
|
114
|
+
|
|
115
|
+
```ts title="server/plugins/my-monitor-plugin.ts"
|
|
116
|
+
import type { ServerPlugin } from '@modern-js/server-runtime';
|
|
117
|
+
import type { MonitorEvent } from '@modern-js/types';
|
|
118
|
+
|
|
119
|
+
const myMonitorPlugin = (): ServerPlugin => ({
|
|
120
|
+
name: '@my-org/my-monitor-plugin',
|
|
121
|
+
setup(api) {
|
|
122
|
+
api.onPrepare(() => {
|
|
123
|
+
const { middlewares } = api.getServerContext();
|
|
124
|
+
|
|
125
|
+
// 定义 monitor,确保只创建一次
|
|
126
|
+
const myMonitor = (event: MonitorEvent) => {
|
|
127
|
+
if (event.type === 'log') {
|
|
128
|
+
// 处理日志事件
|
|
129
|
+
console.log(`[${event.payload.level}] ${event.payload.message}`);
|
|
130
|
+
} else if (event.type === 'timing') {
|
|
131
|
+
// 处理性能指标事件
|
|
132
|
+
console.log(`Timing: ${event.payload.name} = ${event.payload.dur}ms`);
|
|
133
|
+
} else if (event.type === 'counter') {
|
|
134
|
+
// 处理计数事件
|
|
135
|
+
console.log(`Counter: ${event.payload.name}`);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// 使用标志确保 monitor 只注册一次
|
|
140
|
+
let monitorRegistered = false;
|
|
141
|
+
|
|
142
|
+
middlewares.push({
|
|
143
|
+
name: 'inject-monitor',
|
|
144
|
+
handler: async (c, next) => {
|
|
145
|
+
const monitors = c.get('monitors');
|
|
146
|
+
// 只在第一次请求时注册 monitor
|
|
147
|
+
if (!monitorRegistered) {
|
|
148
|
+
monitors.push(myMonitor);
|
|
149
|
+
monitorRegistered = true;
|
|
150
|
+
}
|
|
151
|
+
await next();
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
export default myMonitorPlugin;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
然后在 `server/modern.server.ts` 中配置插件:
|
|
162
|
+
|
|
163
|
+
```ts title="server/modern.server.ts"
|
|
164
|
+
import { defineServerConfig } from '@modern-js/server-runtime';
|
|
165
|
+
import myMonitorPlugin from './plugins/my-monitor-plugin';
|
|
166
|
+
|
|
167
|
+
export default defineServerConfig({
|
|
168
|
+
plugins: [myMonitorPlugin()],
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
117
172
|
## 调用 Monitors
|
|
118
173
|
|
|
119
174
|
Modern.js 允许开发者在 Data Loader、组件中调用 Monitors。
|
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
title: 数据缓存
|
|
3
3
|
sidebar_position: 4
|
|
4
4
|
---
|
|
5
|
+
|
|
5
6
|
# 数据缓存
|
|
6
7
|
|
|
7
8
|
`cache` 函数可以让你缓存数据获取或计算的结果,相比整页[渲染缓存](/guides/basic-features/render/ssr-cache),它提供了更精细的数据粒度控制,并且适用于客户端渲染(CSR)、服务端渲染(SSR)、API 服务(BFF)等多种场景。
|
|
8
9
|
|
|
9
|
-
:::info
|
|
10
|
-
需要 x.65.5 及以上版本
|
|
11
|
-
:::
|
|
12
|
-
|
|
13
10
|
## 基本用法
|
|
14
11
|
|
|
15
12
|
:::note
|
|
@@ -79,7 +76,6 @@ Modern.js 提供的 `cache` 函数可以在任意的前端或服务端的代码
|
|
|
79
76
|
无 `options` 参数时,可以看作是 react [`cache`](https://react.dev/reference/react/cache) 函数的替代品,可以在任意服务端代码中使用(比如可以在 SSR 项目的 data loader 中),不局限于 server component。
|
|
80
77
|
:::
|
|
81
78
|
|
|
82
|
-
|
|
83
79
|
```ts
|
|
84
80
|
import { cache } from '@modern-js/runtime/cache';
|
|
85
81
|
import { fetchUserData } from './api';
|
|
@@ -108,8 +104,8 @@ const getDashboardStats = cache(
|
|
|
108
104
|
return await fetchComplexStatistics();
|
|
109
105
|
},
|
|
110
106
|
{
|
|
111
|
-
maxAge: CacheTime.MINUTE * 2,
|
|
112
|
-
}
|
|
107
|
+
maxAge: CacheTime.MINUTE * 2, // 在 2 分钟内调用该函数会返回缓存的数据
|
|
108
|
+
},
|
|
113
109
|
);
|
|
114
110
|
```
|
|
115
111
|
|
|
@@ -133,7 +129,7 @@ const getDashboardStats = cache(
|
|
|
133
129
|
{
|
|
134
130
|
maxAge: CacheTime.MINUTE * 2,
|
|
135
131
|
revalidate: CacheTime.MINUTE * 1,
|
|
136
|
-
}
|
|
132
|
+
},
|
|
137
133
|
);
|
|
138
134
|
```
|
|
139
135
|
|
|
@@ -150,7 +146,7 @@ const getDashboardStats = cache(
|
|
|
150
146
|
},
|
|
151
147
|
{
|
|
152
148
|
tag: 'dashboard',
|
|
153
|
-
}
|
|
149
|
+
},
|
|
154
150
|
);
|
|
155
151
|
|
|
156
152
|
const getComplexStatistics = cache(
|
|
@@ -159,7 +155,7 @@ const getComplexStatistics = cache(
|
|
|
159
155
|
},
|
|
160
156
|
{
|
|
161
157
|
tag: 'dashboard',
|
|
162
|
-
}
|
|
158
|
+
},
|
|
163
159
|
);
|
|
164
160
|
|
|
165
161
|
await revalidateTag('dashboard'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
|
|
@@ -184,7 +180,7 @@ const getUser = cache(
|
|
|
184
180
|
maxAge: CacheTime.MINUTE * 5,
|
|
185
181
|
// 只使用第一个参数(userId)作为缓存键
|
|
186
182
|
getKey: (userId, options) => userId,
|
|
187
|
-
}
|
|
183
|
+
},
|
|
188
184
|
);
|
|
189
185
|
|
|
190
186
|
// 下面两次调用会共享缓存,因为 getKey 只使用了 userId
|
|
@@ -214,11 +210,10 @@ const getUser = cache(
|
|
|
214
210
|
{
|
|
215
211
|
maxAge: CacheTime.MINUTE * 5,
|
|
216
212
|
getKey: (userId, options) => generateKey(userId),
|
|
217
|
-
}
|
|
213
|
+
},
|
|
218
214
|
);
|
|
219
215
|
```
|
|
220
216
|
|
|
221
|
-
|
|
222
217
|
#### `customKey` 参数
|
|
223
218
|
|
|
224
219
|
`customKey` 参数用于**完全定制**缓存的键,它是一个函数,接收一个包含以下属性的对象,返回值必须是字符串类型。
|
|
@@ -232,6 +227,7 @@ const getUser = cache(
|
|
|
232
227
|
:::info
|
|
233
228
|
|
|
234
229
|
一般在以下场景,缓存会失效:
|
|
230
|
+
|
|
235
231
|
1. 函数的入参发生变化
|
|
236
232
|
2. 不满足 maxAge 条件
|
|
237
233
|
3. 调用了 `revalidateTag`
|
|
@@ -247,16 +243,13 @@ import { cache } from '@modern-js/runtime/cache';
|
|
|
247
243
|
import { fetchUserData } from './api';
|
|
248
244
|
|
|
249
245
|
// 不同的函数引用,但是通过 customKey 可以使它们共享一个缓存
|
|
250
|
-
const getUserA = cache(
|
|
251
|
-
|
|
252
|
-
{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
},
|
|
258
|
-
}
|
|
259
|
-
);
|
|
246
|
+
const getUserA = cache(fetchUserData, {
|
|
247
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
248
|
+
customKey: ({ params }) => {
|
|
249
|
+
// 返回一个稳定的字符串作为缓存的键
|
|
250
|
+
return `user-${params[0]}`;
|
|
251
|
+
},
|
|
252
|
+
});
|
|
260
253
|
|
|
261
254
|
// 即使函数引用变了,只要 customKey 返回相同的值,也会命中缓存
|
|
262
255
|
const getUserB = cache(
|
|
@@ -267,7 +260,7 @@ const getUserB = cache(
|
|
|
267
260
|
// 返回与 getUserA 相同的键
|
|
268
261
|
return `user-${params[0]}`;
|
|
269
262
|
},
|
|
270
|
-
}
|
|
263
|
+
},
|
|
271
264
|
);
|
|
272
265
|
|
|
273
266
|
// 现在你可以在不同的函数实现间共享缓存
|
|
@@ -275,12 +268,9 @@ await getUserA(123); // 获取数据并使用键 "user-123" 缓存
|
|
|
275
268
|
await getUserB(123); // 缓存命中,返回缓存的数据
|
|
276
269
|
|
|
277
270
|
// 可以利用 generatedKey 参数在默认键的基础上进行修改
|
|
278
|
-
const getUserC = cache(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
customKey: ({ generatedKey }) => `prefix-${generatedKey}`,
|
|
282
|
-
}
|
|
283
|
-
);
|
|
271
|
+
const getUserC = cache(fetchUserData, {
|
|
272
|
+
customKey: ({ generatedKey }) => `prefix-${generatedKey}`,
|
|
273
|
+
});
|
|
284
274
|
|
|
285
275
|
// 用于可预测的缓存键,便于外部管理
|
|
286
276
|
const getUserD = cache(
|
|
@@ -290,7 +280,7 @@ const getUserD = cache(
|
|
|
290
280
|
{
|
|
291
281
|
maxAge: CacheTime.MINUTE * 5,
|
|
292
282
|
customKey: ({ params }) => `app:user:${params[0]}`,
|
|
293
|
-
}
|
|
283
|
+
},
|
|
294
284
|
);
|
|
295
285
|
```
|
|
296
286
|
|
|
@@ -307,30 +297,31 @@ const stats = {
|
|
|
307
297
|
hits: 0,
|
|
308
298
|
misses: 0,
|
|
309
299
|
stales: 0,
|
|
310
|
-
hitRate: () => stats.hits / stats.total
|
|
300
|
+
hitRate: () => stats.hits / stats.total,
|
|
311
301
|
};
|
|
312
302
|
|
|
313
|
-
const getUser = cache(
|
|
314
|
-
|
|
315
|
-
{
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
} else if (status === 'stale') {
|
|
326
|
-
stats.stales++;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
console.log(`缓存${status === 'hit' ? '命中' : status === 'miss' ? '未命中' : '陈旧'},键:${String(key)}`);
|
|
330
|
-
console.log(`当前命中率:${stats.hitRate() * 100}%`);
|
|
303
|
+
const getUser = cache(fetchUserData, {
|
|
304
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
305
|
+
onCache({ status, key, params, result }) {
|
|
306
|
+
// status 可以是 'hit'、'miss' 或 'stale'
|
|
307
|
+
stats.total++;
|
|
308
|
+
|
|
309
|
+
if (status === 'hit') {
|
|
310
|
+
stats.hits++;
|
|
311
|
+
} else if (status === 'miss') {
|
|
312
|
+
stats.misses++;
|
|
313
|
+
} else if (status === 'stale') {
|
|
314
|
+
stats.stales++;
|
|
331
315
|
}
|
|
332
|
-
|
|
333
|
-
|
|
316
|
+
|
|
317
|
+
console.log(
|
|
318
|
+
`缓存${
|
|
319
|
+
status === 'hit' ? '命中' : status === 'miss' ? '未命中' : '陈旧'
|
|
320
|
+
},键:${String(key)}`,
|
|
321
|
+
);
|
|
322
|
+
console.log(`当前命中率:${stats.hitRate() * 100}%`);
|
|
323
|
+
},
|
|
324
|
+
});
|
|
334
325
|
|
|
335
326
|
// 使用示例
|
|
336
327
|
await getUser(1); // 缓存未命中
|
|
@@ -351,6 +342,7 @@ await getUser(2); // 缓存未命中
|
|
|
351
342
|
这个回调只在提供 `options` 参数时被调用。当使用无 options 的缓存函数时,不会调用 `onCache` 回调。
|
|
352
343
|
|
|
353
344
|
`onCache` 回调对以下场景非常有用:
|
|
345
|
+
|
|
354
346
|
- 监控缓存性能
|
|
355
347
|
- 计算命中率
|
|
356
348
|
- 记录缓存操作
|
|
@@ -408,11 +400,13 @@ configureCache({
|
|
|
408
400
|
##### 使用 `customKey` 确保缓存键稳定性
|
|
409
401
|
|
|
410
402
|
:::warning 重要建议
|
|
403
|
+
|
|
411
404
|
当使用自定义存储容器(如 Redis)时,**建议配置 `customKey`** 来确保缓存键的稳定性。这样可以确保:
|
|
412
405
|
|
|
413
406
|
1. **跨进程共享**:不同服务器实例能够共享相同的缓存
|
|
414
407
|
2. **应用重启后缓存有效**:重启应用后仍能命中之前的缓存
|
|
415
408
|
3. **代码部署后缓存保持**:代码更新后相同逻辑的缓存仍然有效
|
|
409
|
+
|
|
416
410
|
:::
|
|
417
411
|
|
|
418
412
|
默认的缓存键生成机制基于函数引用,在分布式环境中可能不够稳定。建议使用 `customKey` 提供稳定的缓存键:
|
|
@@ -434,7 +428,7 @@ const getUser = cache(
|
|
|
434
428
|
maxAge: CacheTime.MINUTE * 5,
|
|
435
429
|
// 使用被缓存函数相关的稳定标识符作为缓存键
|
|
436
430
|
customKey: () => `fetchUserData`,
|
|
437
|
-
}
|
|
431
|
+
},
|
|
438
432
|
);
|
|
439
433
|
```
|
|
440
434
|
|
|
@@ -502,4 +496,3 @@ configureCache({
|
|
|
502
496
|
1. **序列化**:所有的缓存数据都会被序列化为字符串存储,容器只需要处理字符串的存取操作。
|
|
503
497
|
|
|
504
498
|
2. **TTL 支持**:如果你的存储后端支持 TTL(生存时间),可以在 `set` 方法中使用 `options.ttl` 参数(单位为秒)。
|
|
505
|
-
|
|
@@ -9,10 +9,6 @@ Modern.js 中提供了开箱即用的数据获取能力,开发者可以通过
|
|
|
9
9
|
|
|
10
10
|
## 什么是 Data Loader
|
|
11
11
|
|
|
12
|
-
:::note
|
|
13
|
-
Modern.js v1 项目通过 `useLoader` 获取数据,这已经不是我们推荐的用法,建议迁移到 Data Loader。
|
|
14
|
-
:::
|
|
15
|
-
|
|
16
12
|
Modern.js 推荐使用[约定式路由](/guides/basic-features/routes/routes)做路由的管理,每个路由组件(`layout.ts`,`page.ts` 或 `$.tsx`)都可以有一个同名的 `.data` 文件。这些文件可以导出一个 `loader` 函数,我们称为 Data Loader,它会在对应的路由组件渲染之前执行,为组件提供数据。如下面示例:
|
|
17
13
|
|
|
18
14
|
```bash
|
|
@@ -40,17 +36,19 @@ export const loader = async (): Promise<ProfileData> => {
|
|
|
40
36
|
```
|
|
41
37
|
|
|
42
38
|
:::warning 兼容性
|
|
39
|
+
|
|
43
40
|
- 在之前的版本中,Data Loader 是定义在 `.loader` 文件中的。当前版本中,我们推荐定义在 `.data` 文件中,同时我们会保持对 `.loader` 文件的兼容。
|
|
44
41
|
- 在 `.loader` 文件中,Data Loader 可以默认导出。但在 `data` 文件中,Data Loader 需要以 `loader` 具名导出。
|
|
42
|
+
|
|
45
43
|
```ts
|
|
46
|
-
|
|
47
|
-
export default () => {}
|
|
44
|
+
// xxx.loader.ts
|
|
45
|
+
export default () => {};
|
|
48
46
|
|
|
49
47
|
// xxx.data.ts
|
|
50
|
-
export const loader = () => {}
|
|
48
|
+
export const loader = () => {};
|
|
51
49
|
```
|
|
52
|
-
:::
|
|
53
50
|
|
|
51
|
+
:::
|
|
54
52
|
|
|
55
53
|
在路由组件中,你可以通过 `useLoaderData` 函数获取数据:
|
|
56
54
|
|
|
@@ -162,8 +160,8 @@ export async function loader() {
|
|
|
162
160
|
const res = await fetch('URL_ADDRESS');
|
|
163
161
|
const data = await res.json();
|
|
164
162
|
return {
|
|
165
|
-
message: data.message
|
|
166
|
-
}
|
|
163
|
+
message: data.message,
|
|
164
|
+
};
|
|
167
165
|
}
|
|
168
166
|
```
|
|
169
167
|
|
|
@@ -208,7 +206,7 @@ export default ErrorBoundary;
|
|
|
208
206
|
// routes/user/profile/page.data.ts
|
|
209
207
|
export async function loader() {
|
|
210
208
|
const user = await fetchUser();
|
|
211
|
-
if(!user){
|
|
209
|
+
if (!user) {
|
|
212
210
|
throw new Response('The user was not found', { status: 404 });
|
|
213
211
|
}
|
|
214
212
|
return user;
|
|
@@ -261,7 +259,6 @@ export function UserLayout() {
|
|
|
261
259
|
|
|
262
260
|
如果想获取 `entry1/routes/layout.tsx` 中 `loader` 返回的数据,`routeId` 的值就是 `entry1_layout`。
|
|
263
261
|
|
|
264
|
-
|
|
265
262
|
## Loading UI (Experimental)
|
|
266
263
|
|
|
267
264
|
:::info Experimental
|
|
@@ -4,19 +4,16 @@ sidebar_position: 6
|
|
|
4
4
|
|
|
5
5
|
# 网络代理
|
|
6
6
|
|
|
7
|
-
Modern.js 在 [`
|
|
7
|
+
Modern.js 在 [`dev.server.proxy`](/configure/app/dev/server) 中提供了配置开发环境代理的方式。例如,将本地开发接口,代理到线上某个地址:
|
|
8
8
|
|
|
9
9
|
```ts title="modern.config.ts"
|
|
10
10
|
import { defineConfig } from '@modern-js/app-tools';
|
|
11
11
|
|
|
12
12
|
export default defineConfig({
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
dev: {
|
|
14
|
+
server: {
|
|
15
15
|
proxy: {
|
|
16
|
-
'/go/api':
|
|
17
|
-
target: 'http://www.example.com/',
|
|
18
|
-
changeOrigin: true,
|
|
19
|
-
},
|
|
16
|
+
'/go/api': 'http://www.example.com/',
|
|
20
17
|
},
|
|
21
18
|
},
|
|
22
19
|
},
|