@modern-js/main-doc 0.0.0-nightly-20250506160336 → 0.0.0-nightly-20250508160349
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.
|
@@ -12,6 +12,15 @@ X.65.5 and above versions are required
|
|
|
12
12
|
|
|
13
13
|
## Basic Usage
|
|
14
14
|
|
|
15
|
+
:::note
|
|
16
|
+
|
|
17
|
+
If you use the `cache` function in BFF, you should import the cache funtion from `@modern-js/server-runtime/cache`
|
|
18
|
+
|
|
19
|
+
`import { cache } from '@modern-js/server-runtime/cache'`
|
|
20
|
+
|
|
21
|
+
:::
|
|
22
|
+
|
|
23
|
+
|
|
15
24
|
```ts
|
|
16
25
|
import { cache } from '@modern-js/runtime/cache';
|
|
17
26
|
import { fetchUserData } from './api';
|
|
@@ -34,6 +43,7 @@ const loader = async () => {
|
|
|
34
43
|
- `tag`: Tag to identify the cache, which can be used to invalidate the cache
|
|
35
44
|
- `maxAge`: Cache validity period (milliseconds)
|
|
36
45
|
- `revalidate`: Time window for revalidating the cache (milliseconds), similar to HTTP Cache-Control's stale-while-revalidate functionality
|
|
46
|
+
- `getKey`: Simplified cache key generation function based on function parameters
|
|
37
47
|
- `customKey`: Custom cache key function
|
|
38
48
|
|
|
39
49
|
The type of the `options` parameter is as follows:
|
|
@@ -43,6 +53,7 @@ interface CacheOptions {
|
|
|
43
53
|
tag?: string | string[];
|
|
44
54
|
maxAge?: number;
|
|
45
55
|
revalidate?: number;
|
|
56
|
+
getKey?: <Args extends any[]>(...args: Args) => string;
|
|
46
57
|
customKey?: <Args extends any[]>(options: {
|
|
47
58
|
params: Args;
|
|
48
59
|
fn: (...args: Args) => any;
|
|
@@ -159,6 +170,72 @@ revalidateTag('dashboard-stats'); // Invalidates the cache for both getDashboard
|
|
|
159
170
|
```
|
|
160
171
|
|
|
161
172
|
|
|
173
|
+
#### `getKey` Parameter
|
|
174
|
+
|
|
175
|
+
The `getKey` parameter simplifies cache key generation, especially useful when you only need to rely on part of the function parameters to differentiate caches. It's a function that receives the same parameters as the original function and returns a string or number as the cache key:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
179
|
+
import { fetchUserData } from './api';
|
|
180
|
+
|
|
181
|
+
const getUser = cache(
|
|
182
|
+
async (userId, options) => {
|
|
183
|
+
// Here options might contain many configurations, but we only want to cache based on userId
|
|
184
|
+
return await fetchUserData(userId, options);
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
188
|
+
// Only use the first parameter (userId) as the cache key
|
|
189
|
+
getKey: (userId, options) => userId,
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// The following two calls will share the cache because getKey only uses userId
|
|
194
|
+
await getUser(123, { language: 'en' });
|
|
195
|
+
await getUser(123, { language: 'fr' }); // Cache hit, won't request again
|
|
196
|
+
|
|
197
|
+
// Different userId will use different cache
|
|
198
|
+
await getUser(456, { language: 'en' }); // Won't hit cache, will request again
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
You can also use Modern.js's `generateKey` function together with getKey to generate the cache key:
|
|
202
|
+
|
|
203
|
+
:::info
|
|
204
|
+
|
|
205
|
+
The `generateKey` function in Modern.js ensures that a consistent and unique key is generated even if object property orders change, guaranteeing stable caching.
|
|
206
|
+
|
|
207
|
+
:::
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { cache, CacheTime, generateKey } from '@modern-js/runtime/cache';
|
|
211
|
+
import { fetchUserData } from './api';
|
|
212
|
+
|
|
213
|
+
const getUser = cache(
|
|
214
|
+
async (userId, options) => {
|
|
215
|
+
return await fetchUserData(userId, options);
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
219
|
+
getKey: (userId, options) => generateKey(userId),
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Additionally, `getKey` can also return a numeric type as a cache key:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
const getUserById = cache(
|
|
228
|
+
fetchUserDataById,
|
|
229
|
+
{
|
|
230
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
231
|
+
// Directly use the numeric ID as the cache key
|
|
232
|
+
getKey: (id) => id,
|
|
233
|
+
}
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
await getUserById(42); // Uses 42 as the cache key
|
|
237
|
+
```
|
|
238
|
+
|
|
162
239
|
#### `customKey` parameter
|
|
163
240
|
|
|
164
241
|
The `customKey` parameter is used to customize the cache key. It is a function that receives an object with the following properties and returns a string or Symbol type as the cache key:
|
|
@@ -167,6 +244,18 @@ The `customKey` parameter is used to customize the cache key. It is a function t
|
|
|
167
244
|
- `fn`: Reference to the original function being cached
|
|
168
245
|
- `generatedKey`: Cache key automatically generated by the framework based on input parameters
|
|
169
246
|
|
|
247
|
+
:::info
|
|
248
|
+
|
|
249
|
+
Generally, the cache will be invalidated in the following scenarios:
|
|
250
|
+
1. The referenced cached function changes
|
|
251
|
+
2. The function's input parameters change
|
|
252
|
+
3. The maxAge condition is no longer satisfied
|
|
253
|
+
4. The `revalidateTag` method has been called
|
|
254
|
+
|
|
255
|
+
`customKey` can be used in scenarios where function references are different but shared caching is desired. If it's just for customizing the cache key, it is recommended to use `getKey`.
|
|
256
|
+
|
|
257
|
+
:::
|
|
258
|
+
|
|
170
259
|
This is very useful in some scenarios, such as when the function reference changes , but you want to still return the cached data.
|
|
171
260
|
|
|
172
261
|
```ts
|
|
@@ -271,7 +360,7 @@ The `onCache` callback receives an object with the following properties:
|
|
|
271
360
|
- `params`: The parameters passed to the cached function
|
|
272
361
|
- `result`: The result data (either from cache or newly computed)
|
|
273
362
|
|
|
274
|
-
This callback is only invoked when the `options` parameter is provided. When using the cache function without options
|
|
363
|
+
This callback is only invoked when the `options` parameter is provided. When using the cache function without options, the `onCache` callback is not called.
|
|
275
364
|
|
|
276
365
|
The `onCache` callback is useful for:
|
|
277
366
|
- Monitoring cache performance
|
|
@@ -136,13 +136,14 @@ Full-stack projects refer to projects that use Custom Web Server, SSR or BFF. Th
|
|
|
136
136
|
:::info
|
|
137
137
|
1. Currently, Modern.js does not support deployment on Netlify Edge Functions. We will support it in future versions.
|
|
138
138
|
2. You can refer to the [deployment project example](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/modern-js-deploy-ssr).
|
|
139
|
+
|
|
139
140
|
:::
|
|
140
141
|
|
|
141
142
|
|
|
142
143
|
### Monorepo
|
|
143
144
|
|
|
144
145
|
:::info
|
|
145
|
-
The following guide is mainly for full-stack projects, for pure CSR projects, just follow [Pure Frontend Project](#
|
|
146
|
+
The following guide is mainly for full-stack projects, for pure CSR projects, just follow [Pure Frontend Project](#pure-front-end-project-1) to deploy.
|
|
146
147
|
:::
|
|
147
148
|
|
|
148
149
|
For Monorepo projects, in addition to building our current project, you also need to build other sub-projects in the repository that the current project depends on.
|
|
@@ -330,6 +331,7 @@ For branch deployment, follow these steps:
|
|
|
330
331
|
:::info
|
|
331
332
|
1. Running `MODERNJS_DEPLOY=ghPages modern deploy` will build the production output for GitHub in the .output directory.
|
|
332
333
|
2. You can refer to the [project](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/modern-js-deploy-csr)
|
|
334
|
+
|
|
333
335
|
:::
|
|
334
336
|
|
|
335
337
|
For GitHub Actions deployment, select Settings > Pages > Source > GitHub Actions, and add a workflow file to the project. You can refer to the [example](https://github.com/web-infra-dev/modern-js-examples/tree/main/examples/modern-js-deploy-csr).
|
|
@@ -148,7 +148,7 @@ info Starting production server...
|
|
|
148
148
|
> Network: http://192.168.0.1:8080/
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
Open `http://localhost:
|
|
151
|
+
Open `http://localhost:8080/` in the browser, and the content should be consistent with that of `pnpm run dev`.
|
|
152
152
|
|
|
153
153
|
## Deployment
|
|
154
154
|
|
|
@@ -12,6 +12,14 @@ sidebar_position: 4
|
|
|
12
12
|
|
|
13
13
|
## 基本用法
|
|
14
14
|
|
|
15
|
+
:::note
|
|
16
|
+
|
|
17
|
+
如果在 BFF 中使用 `cache` 函数,应该从 `@modern-js/server-runtime/cache` 导入相关函数
|
|
18
|
+
|
|
19
|
+
`import { cache } from '@modern-js/server-runtime/cache'`
|
|
20
|
+
|
|
21
|
+
:::
|
|
22
|
+
|
|
15
23
|
```ts
|
|
16
24
|
import { cache } from '@modern-js/runtime/cache';
|
|
17
25
|
import { fetchUserData } from './api';
|
|
@@ -33,6 +41,7 @@ const loader = async () => {
|
|
|
33
41
|
- `tag`: 用于标识缓存的标签,可以基于这个标签使缓存失效
|
|
34
42
|
- `maxAge`: 缓存的有效期 (毫秒)
|
|
35
43
|
- `revalidate`: 重新验证缓存的时间窗口(毫秒),与 HTTP Cache-Control 的 stale-while-revalidate 功能一致
|
|
44
|
+
- `getKey`: 简化的缓存键生成函数,根据函数参数生成缓存键
|
|
36
45
|
- `customKey`: 自定义缓存键生成函数,用于在函数引用变化时保持缓存
|
|
37
46
|
|
|
38
47
|
`options` 参数的类型如下:
|
|
@@ -42,6 +51,7 @@ interface CacheOptions {
|
|
|
42
51
|
tag?: string | string[];
|
|
43
52
|
maxAge?: number;
|
|
44
53
|
revalidate?: number;
|
|
54
|
+
getKey?: <Args extends any[]>(...args: Args) => string;
|
|
45
55
|
customKey?: <Args extends any[]>(options: {
|
|
46
56
|
params: Args;
|
|
47
57
|
fn: (...args: Args) => any;
|
|
@@ -152,6 +162,58 @@ const getComplexStatistics = cache(
|
|
|
152
162
|
revalidateTag('dashboard-stats'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
|
|
153
163
|
```
|
|
154
164
|
|
|
165
|
+
#### `getKey` 参数
|
|
166
|
+
|
|
167
|
+
`getKey` 参数用于自定义缓存键的生成方式,例如你可能只需要依赖函数参数的一部分来区分缓存。它是一个函数,接收与原始函数相同的参数,返回一个字符串作为缓存键:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
171
|
+
import { fetchUserData } from './api';
|
|
172
|
+
|
|
173
|
+
const getUser = cache(
|
|
174
|
+
async (userId, options) => {
|
|
175
|
+
// 这里 options 可能包含很多配置,但我们只想根据 userId 缓存
|
|
176
|
+
return await fetchUserData(userId, options);
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
180
|
+
// 只使用第一个参数(userId)作为缓存键
|
|
181
|
+
getKey: (userId, options) => userId,
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// 下面两次调用会共享缓存,因为 getKey 只使用了 userId
|
|
186
|
+
await getUser(123, { language: 'zh' });
|
|
187
|
+
await getUser(123, { language: 'en' }); // 命中缓存,不会重新请求
|
|
188
|
+
|
|
189
|
+
// 不同的 userId 会使用不同的缓存
|
|
190
|
+
await getUser(456, { language: 'zh' }); // 不会命中缓存,会重新请求
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
你也可以使用 Modern.js 提供的 `generateKey` 函数配合 getKey 生成缓存的键:
|
|
194
|
+
|
|
195
|
+
:::info
|
|
196
|
+
|
|
197
|
+
Modern.js 中的 `generateKey` 函数确保即使对象属性顺序发生变化,也能生成一致的唯一键值,保证稳定的缓存
|
|
198
|
+
|
|
199
|
+
:::
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { cache, CacheTime, generateKey } from '@modern-js/runtime/cache';
|
|
203
|
+
import { fetchUserData } from './api';
|
|
204
|
+
|
|
205
|
+
const getUser = cache(
|
|
206
|
+
async (userId, options) => {
|
|
207
|
+
return await fetchUserData(userId, options);
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
maxAge: CacheTime.MINUTE * 5,
|
|
211
|
+
getKey: (userId, options) => generateKey(userId),
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
|
|
155
217
|
#### `customKey` 参数
|
|
156
218
|
|
|
157
219
|
`customKey` 参数用于定制缓存的键,它是一个函数,接收一个包含以下属性的对象,返回值必须是字符串或 Symbol 类型,将作为缓存的键:
|
|
@@ -160,6 +222,18 @@ revalidateTag('dashboard-stats'); // 会使 getDashboardStats 函数和 getCompl
|
|
|
160
222
|
- `fn`:原始被缓存的函数引用
|
|
161
223
|
- `generatedKey`:框架基于入参自动生成的原始缓存键
|
|
162
224
|
|
|
225
|
+
:::info
|
|
226
|
+
|
|
227
|
+
一般在以下场景,缓存会失效:
|
|
228
|
+
1. 缓存的函数引用发生变化
|
|
229
|
+
2. 函数的入参发生变化
|
|
230
|
+
3. 不满足 maxAge
|
|
231
|
+
4. 调用了 `revalidateTag`
|
|
232
|
+
|
|
233
|
+
`customKey` 可以用在函数引用不同,但希望共享缓存的场景,如果只是自定义缓存键,推荐使用 `getKey`
|
|
234
|
+
|
|
235
|
+
:::
|
|
236
|
+
|
|
163
237
|
这在某些场景下非常有用,比如当函数引用发生变化时,但你希望仍然返回缓存的数据。
|
|
164
238
|
|
|
165
239
|
```ts
|
|
@@ -268,7 +342,7 @@ await getUser(2); // 缓存未命中
|
|
|
268
342
|
- `params`: 传递给缓存函数的参数
|
|
269
343
|
- `result`: 结果数据(来自缓存或新计算的)
|
|
270
344
|
|
|
271
|
-
这个回调只在提供 `options`
|
|
345
|
+
这个回调只在提供 `options` 参数时被调用。当使用无 options 的缓存函数时,不会调用 `onCache` 回调。
|
|
272
346
|
|
|
273
347
|
`onCache` 回调对以下场景非常有用:
|
|
274
348
|
- 监控缓存性能
|
package/package.json
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "0.0.0-nightly-
|
|
18
|
+
"version": "0.0.0-nightly-20250508160349",
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"registry": "https://registry.npmjs.org/",
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"mermaid": "^11.4.1",
|
|
25
|
-
"@modern-js/sandpack-react": "0.0.0-nightly-
|
|
25
|
+
"@modern-js/sandpack-react": "0.0.0-nightly-20250508160349"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@rspress/shared": "1.43.11",
|