@modern-js/main-doc 2.20.0 → 2.21.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -58,3 +58,40 @@ import appTools, { defineConfig } from '@modern-js/app-tools';
58
58
  :::tip
59
59
  从 webpack 迁移至 Rspack 时,存在一些构建能力和配置上的差异,详情可参考:[配置差异](https://modernjs.dev/builder/guide/advanced/rspack-start.html#从-webpack-迁移到-rspack)
60
60
  :::
61
+
62
+ ## Rspack 和 Modern.js 的版本关系
63
+
64
+ 通常情况下,Modern.js 内会集成 Rspack 的最新版本,通过 `npx modern upgrade` 即可将当前项目中的 Modern.js 相关依赖以及内置的 Rspack 更新至最新版本。
65
+
66
+ 但 Modern.js 对于 Rspack 的依赖方式为锁版本方式(非自动升级),由于发版周期不同步等原因,可能会出现 Modern.js 内集成的 Rspack 版本落后于 Rspack 最新版本的情况。
67
+
68
+ 当你执行 dev / build 命令时,Modern.js 会自动打印当前使用的 Rspack 版本:
69
+
70
+ ![rspack_version_log](https://lf3-static.bytednsdoc.com/obj/eden-cn/6221eh7uhbfvhn/modern/img_v2_dfcf051f-21db-4741-a108-d9f7a82c3abg.png)
71
+
72
+ #### 修改内置 Rspack 版本
73
+
74
+ 可以使用 pnpm / yarn / npm 等包管理工具自带的依赖升级功能来将 Rspack 强制升级到指定版本。
75
+
76
+ 以 pnpm 为例,可通过 `overrides` 以下依赖更新 Rspack 版本:
77
+
78
+ ```json title=package.json
79
+ {
80
+ "pnpm": {
81
+ "overrides": {
82
+ "@rspack/core": "nightly",
83
+ "@rspack/dev-client": "nightly",
84
+ "@rspack/dev-middleware": "nightly",
85
+ "@rspack/plugin-html": "nightly",
86
+ "@rspack/postcss-loader": "nightly"
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ :::tip Nightly 版本介绍
93
+ 每天,Rspack 会自动构建基于最新代码的 nightly 版本,用于测试和及早发现错误。
94
+ 通常情况下,这些版本是可用的。如果发现问题,我们会及时进行修复。但是,如果 Rspack 有一些 break change,需要 Modern.js 同步修改代码,那么我们建议等待下一个 Modern.js 版本再进行更新。
95
+ :::
96
+
97
+ 如果想了解其他包管理工具锁定依赖版本的示例,可以参考:[锁定子依赖](/guides/get-started/upgrade.html#%E9%94%81%E5%AE%9A%E5%AD%90%E4%BE%9D%E8%B5%96)。
@@ -14,7 +14,7 @@ Modern.js 中提供了开箱即用的数据获取能力,开发者可以通过
14
14
  Modern.js 推荐使用约定式路由做路由的管理,通过 Modern.js 的[约定式(嵌套)路由](/guides/basic-features/routes#约定式路由),每个路由组件(`layout.ts` 或 `page.ts`)可以有一个同名的 `loader` 文件,该 `loader` 文件需要导出一个函数,函数会在组件渲染之前执行,为路由组件提供数据。
15
15
 
16
16
  :::info
17
- Modern.js v1 支持通过 [useLoader](#useloader旧版) 获取数据,这已经不是我们推荐的用法,除迁移过程外,不推荐两者混用。
17
+ Modern.js v1 支持通过 [useLoader](#useloader(旧版)) 获取数据,这已经不是我们推荐的用法,除迁移过程外,不推荐两者混用。
18
18
 
19
19
  :::
20
20
 
@@ -22,7 +22,7 @@ Modern.js v1 支持通过 [useLoader](#useloader旧版) 获取数据,这已经
22
22
 
23
23
  路由组件如 `layout.ts` 或 `page.ts`,可以定义同名的 `loader` 文件,`loader` 文件中导出一个函数,该函数提供组件所需的数据,然后在路由组件中通过 `useLoaderData` 函数获取数据,如下面示例:
24
24
 
25
- ```
25
+ ```bash
26
26
  .
27
27
  └── routes
28
28
  ├── layout.tsx
@@ -66,19 +66,19 @@ export default async (): Promise<ProfileData> => {
66
66
  在 SSR 环境下,不管是首屏,还是在客户端的导航,`loader` 函数只会在服务端执行,这里可以调用任意的 Node.js API,同时这里使用的任何依赖和代码都不会包含在客户端的 bundle 中。
67
67
 
68
68
  :::info
69
- 在以后的版本中,Modern.js 可能会支持在 CSR 环境下,`loader` 函数也在服务端运行,以提高性能和安全性,所以这里建议尽可能地保证 loader 的纯粹,只做数据获取的场景。
69
+ 在以后的版本中,Modern.js 可能会支持在 CSR 环境下,`loader` 函数也在服务端运行,以提高性能和安全性,所以这里建议尽可能地保证 `loader` 的纯粹,只做数据获取的场景。
70
70
 
71
71
  :::
72
72
 
73
- 当在客户端导航时,基于 Modern.js 的[约定式路由](/guides/basic-features/routes),所有的 loader 函数会并行执行(请求),即当访问 `/user/profile` 时,`/user` 和 `/user/profile` 下的 loader 函数都会并行执行(请求),以提高客户端的性能。
73
+ 当在客户端导航时,基于 Modern.js 的[约定式路由](/guides/basic-features/routes),所有的 `loader` 函数会并行执行(请求),即当访问 `/user/profile` 时,`/user` 和 `/user/profile` 下的 loader 函数都会并行执行(请求),以提高客户端的性能。
74
74
 
75
75
  ### `loader` 函数
76
76
 
77
77
  `loader` 函数有两个入参:
78
78
 
79
- #### `Params`
79
+ #### `params`
80
80
 
81
- 当路由文件通过 `[]` 时,会作为[动态路由](/guides/basic-features/routes#动态路由),动态路由片段会作为参数传入 loader 函数:
81
+ 当路由文件通过 `[]` 时,会作为[动态路由](/guides/basic-features/routes#动态路由),动态路由片段会作为参数传入 `loader` 函数:
82
82
 
83
83
  ```tsx
84
84
  // routes/user/[id]/page.loader.ts
@@ -149,7 +149,7 @@ async function loader() {
149
149
 
150
150
  ### 错误处理
151
151
 
152
- 在 `loader` 函数中,可以通过 `throw error` 或者 `throw response` 的方式处理错误,当 `loader` 函数中有错误被抛出时,Modern.js 会停止执行当前 loader 中的代码,并将前端 UI 切换到定义的 [`ErrorBoundary`](/guides/basic-features/routes#错误处理) 组件:
152
+ 在 `loader` 函数中,可以通过 `throw error` 或者 `throw response` 的方式处理错误,当 `loader` 函数中有错误被抛出时,Modern.js 会停止执行当前 `loader` 中的代码,并将前端 UI 切换到定义的 [`ErrorBoundary`](/guides/basic-features/routes#错误处理) 组件:
153
153
 
154
154
  ```tsx
155
155
  // routes/user/profile/page.loader.ts
@@ -178,14 +178,14 @@ export default ErrorBoundary;
178
178
 
179
179
  ### 获取上层组件的数据
180
180
 
181
- 很多场景下,子组件需要获取到祖先组件 loader 中的数据,你可以通过 `useRouteLoaderData` 方便地获取到祖先组件的数据:
181
+ 很多场景下,子组件需要获取到祖先组件 `loader` 中的数据,你可以通过 `useRouteLoaderData` 方便地获取到祖先组件的数据:
182
182
 
183
183
  ```tsx
184
184
  // routes/user/profile/page.tsx
185
185
  import { useRouteLoaderData } from '@modern-js/runtime/router';
186
186
 
187
187
  export default function UserLayout() {
188
- // 获取 routes/user/layout.loader.ts 中 loader 返回的数据
188
+ // 获取 routes/user/layout.loader.ts 中 `loader` 返回的数据
189
189
  const data = useRouteLoaderData('user/layout');
190
190
  return (
191
191
  <div>
@@ -198,7 +198,7 @@ export default function UserLayout() {
198
198
 
199
199
  `userRouteLoaderData` 接受一个参数 `routeId`,在使用约定式路由时,Modern.js 会为你自动生成`routeId`,`routeId` 的值是对应组件相对于 `src/routes` 的路径,如上面的例子中,子组件想要获取 `routes/user/layout.tsx` 中 loader 返回的数据,`routeId` 的值就是 `user/layout`。
200
200
 
201
- 在多 entry(MPA) 场景下,`routeId` 的值需要加上对应 entry 的 name,entry name 非指定情况下一般是 entry 目录名,如以下目录结构:
201
+ 在多入口(MPA) 场景下,`routeId` 的值需要加上对应入口的名称,入口名称非指定情况下一般是入口的目录名,如以下目录结构:
202
202
 
203
203
  ```bash
204
204
  .
@@ -211,7 +211,7 @@ export default function UserLayout() {
211
211
  └── layout.tsx
212
212
  ```
213
213
 
214
- 如果想获取 `entry1/routes/layout.tsx` 中 loader 返回的数据,`routeId` 的值就是 `entry1_layout`。
214
+ 如果想获取 `entry1/routes/layout.tsx` 中 `loader` 返回的数据,`routeId` 的值就是 `entry1_layout`。
215
215
 
216
216
  ### (WIP)Loading UI
217
217
 
@@ -341,11 +341,11 @@ export default async (): Promise<ProfileData> => {
341
341
 
342
342
  ### 常见问题
343
343
 
344
- 1. loader 和 BFF 函数的关系
344
+ 1. `loader` 和 BFF 函数的关系
345
345
 
346
- 在 CSR 项目中,loader 在客户端执行,在 loader 可以直接调用 BFF 函数进行接口请求。
346
+ 在 CSR 项目中,`loader` 在客户端执行,在 `loader` 可以直接调用 BFF 函数进行接口请求。
347
347
 
348
- 在 SSR 项目中,每个 loader 也是一个服务端接口,我们推荐使用 loader 替代 http method 为 `get` 的 BFF 函数,作为接口层,避免多一层转发和执行。
348
+ 在 SSR 项目中,每个 `loader` 也是一个服务端接口,我们推荐使用 `loader` 替代 http method 为 `get` 的 BFF 函数,作为接口层,避免多一层转发和执行。
349
349
 
350
350
 
351
351
  ## useLoader(旧版)
@@ -18,7 +18,7 @@ Modern.js 的路由基于 [React Router 6](https://reactrouter.com/en/main),
18
18
 
19
19
  Modern.js 支持了业界流行的约定式路由模式:**嵌套路由**,使用嵌套路由时,页面的路由 与 UI 结构是相呼应的,我们将会详细介绍这种路由模式。
20
20
 
21
- ```
21
+ ```bash
22
22
  /user/johnny/profile /user/johnny/posts
23
23
  +------------------+ +-----------------+
24
24
  | User | | User |
@@ -154,7 +154,7 @@ export default () => {
154
154
 
155
155
  通过 `[]` 命名的文件目录,生成的路由会作为动态路由。例如以下文件目录:
156
156
 
157
- ```
157
+ ```bash
158
158
  └── routes
159
159
  ├── [id]
160
160
  │ └── page.tsx
@@ -173,7 +173,7 @@ export default () => {
173
173
 
174
174
  通过 `[$]` 命名的文件目录,生成的路由会作为动态路由。例如以下文件目录:
175
175
 
176
- ```
176
+ ```bash
177
177
  └── routes
178
178
  ├── user
179
179
  │ └── [id$]
@@ -199,7 +199,7 @@ export default () => {
199
199
 
200
200
  例如以下目录结构:
201
201
 
202
- ```
202
+ ```bash
203
203
  └── routes
204
204
  ├── $.tsx
205
205
  ├── blog
@@ -222,7 +222,7 @@ params['*']; // => 'aaa/bbb'
222
222
 
223
223
  当目录名以 \_\_ 开头时,对应的目录名不会转换为实际的路由路径,例如以下文件目录:
224
224
 
225
- ```
225
+ ```bash
226
226
  .
227
227
  └── routes
228
228
  ├── __auth
@@ -245,7 +245,7 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
245
245
 
246
246
  因此 Modern.js 支持了通过 `.` 来分割路由片段,代替文件目录。例如,当需要 `/user/profile/2022/edit` 时,可以直接创建如下文件:
247
247
 
248
- ```
248
+ ```bash
249
249
  └── routes
250
250
  ├── user.profile.[id].edit
251
251
  │ └── page.tsx
@@ -281,7 +281,7 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
281
281
 
282
282
  当定义 `loading.tsx` 时,就相当于以下布局:
283
283
 
284
- ```tsx title="当路由为 / "
284
+ ```tsx title=当路由为"/"
285
285
  <Layout>
286
286
  <Suspense fallback={<Loading />}>
287
287
  <Page />
@@ -289,7 +289,7 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
289
289
  </Layout>
290
290
  ```
291
291
 
292
- ```tsx title="当路由为 /blog "
292
+ ```tsx title=当路由为"/blog"
293
293
  <Layout>
294
294
  <Suspense fallback={<Loading />}>
295
295
  <BlogPage />
@@ -297,7 +297,7 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
297
297
  </Layout>
298
298
  ```
299
299
 
300
- ```tsx title="当路由为 /blog/123 "
300
+ ```tsx title=当路由为"/blog/123"
301
301
  <Layout>
302
302
  <Suspense fallback={<Loading />}>
303
303
  <BlogIdPage />
@@ -306,8 +306,8 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
306
306
  ```
307
307
 
308
308
  :::info
309
- 当目录的 layout 组件不存在时,该目录下的 loading 组件也不会生效。
310
- Modern.js 建议必须有根 layout 和根 loading
309
+ 当目录的 Layout 组件不存在时,该目录下的 Loading 组件也不会生效。
310
+ Modern.js 建议必须有根 Layout 和根 Loading
311
311
 
312
312
  :::
313
313
 
@@ -317,7 +317,7 @@ Modern.js 建议必须有根 layout 和根 loading。
317
317
 
318
318
  ### 路由重定向
319
319
 
320
- 可以通过创建 [`data loader`](/guides/basic-features/data-fetch) 文件做路由的重定向,如有文件 `routes/user/page.tsx`,想对这个文件对应的路由做重定向,可以创建 `routes/user/page.loader.ts` 文件:
320
+ 可以通过创建 [`Data Loader`](/guides/basic-features/data-fetch) 文件做路由的重定向,如有文件 `routes/user/page.tsx`,想对这个文件对应的路由做重定向,可以创建 `routes/user/page.loader.ts` 文件:
321
321
 
322
322
  ```ts title="routes/user/page.loader.ts"
323
323
  import { redirect } from '@modern-js/runtime/router';
@@ -335,13 +335,13 @@ export default () => {
335
335
 
336
336
  `routes/` 下每一层目录中,开发者同样可以定义一个 `error.tsx` 文件,默认导出一个 `<ErrorBoundary>` 组件。
337
337
 
338
- 当有路由目录下存在该组件时,组件渲染出错会被 ErrorBoundary 组件捕获。当目录未定义 `layout.tsx` 文件时,`<ErrorBoundary>` 组件不会生效。
338
+ 当有路由目录下存在该组件时,组件渲染出错会被 `ErrorBoundary` 组件捕获。当目录未定义 `layout.tsx` 文件时,`<ErrorBoundary>` 组件不会生效。
339
339
 
340
340
  `<ErrorBoundary>` 可以返回出错时的 UI 视图,当前层级未声明 `<ErrorBoundary>` 组件时,错误会向上冒泡到更上层的组件,直到被捕获或抛出错误。同时,当组件出错时,只会影响捕获到该错误的路由组件及子组件,其他组件的状态和视图不受影响,可以继续交互。
341
341
 
342
342
  {/* Todo API 路由 */}
343
343
 
344
- 在 `<ErrorBoundary>` 组件内,可以使用 [useRouteError](/apis/app/runtime/router/router#useparams) 获取的错误的具体信息:
344
+ 在 `<ErrorBoundary>` 组件内,可以使用 [useRouteError](/apis/app/runtime/router/router#userouteerror) 获取的错误的具体信息:
345
345
 
346
346
  ```tsx
347
347
  import { useRouteError } from '@modern-js/runtime/router';
@@ -359,7 +359,7 @@ export default ErrorBoundary;
359
359
 
360
360
  ### 运行时配置
361
361
 
362
- 在每个根 `Layout` 组件中(`routes/layout.ts`),可以动态地定义应用运行时配置:
362
+ 在每个根 `Layout` 组件中(`routes/layout.ts`),可以动态地定义运行时配置:
363
363
 
364
364
  ```tsx title="src/routes/layout.tsx"
365
365
  // 定义运行时配置
@@ -447,29 +447,29 @@ export const init = (context: RuntimeContext) => {
447
447
  ### 预加载
448
448
 
449
449
  在约定式路由下, Modern.js 会根据路由,自动地对路由进行分片,当用户访问具体的路由时,会自动加载对应的分片,这样可以有效地减少首屏加载的时间。但这也带来了一个问题,当用户访问一个路由时,如果该路由对应的分片还未加载完成,就会出现白屏的情况。
450
- 这种情况下你可以通过定义 `loading` 组件,在静态资源加载完成前,展示一个自定义的 `loading` 组件。
450
+ 这种情况下你可以通过定义 `Loading` 组件,在静态资源加载完成前,展示一个自定义的 `Loading` 组件。
451
451
 
452
452
  为了进一步提升用户体验,减少 loading 的时间,Modern.js 支持在 Link 组件上定义 `prefetch` 属性,可以提前对静态资源和数据进行加载, `prefetch` 属性有三个可选值:
453
453
 
454
- ```
454
+ ```tsx
455
455
  <Link prefetch="intent" to="page">
456
456
  ```
457
457
 
458
458
  :::info
459
459
  - 该功能目前仅在 Webpack 项目中支持,Rspack 项目暂不支持。
460
- - 对数据的预加载目前只会预加载 SSR 项目中 [data loader](/guides/basic-features/data-fetch) 中返回的数据。
460
+ - 对数据的预加载目前只会预加载 SSR 项目中 [Data Loader](/guides/basic-features/data-fetch) 中返回的数据。
461
461
 
462
462
  :::
463
463
 
464
464
  - `none`, 默认值,不会做 prefetch,没有任何额外的行为。
465
- - `intent`,这是我们推荐大多数场景下使用的值,当你把鼠标放在 Link 上时,会自动开始加载对应的分片和 data loader 中定义的数据,当鼠标移开时,会自动取消加载。在我们的测试中,即使是快速点击,也能减少大约 200ms 的加载时间。
466
- - `render`,当 Link 组件渲染时,就会加载对应的分片和 data loader 中定义的数据。
465
+ - `intent`,这是我们推荐大多数场景下使用的值,当你把鼠标放在 Link 上时,会自动开始加载对应的分片和 Data Loader 中定义的数据,当鼠标移开时,会自动取消加载。在我们的测试中,即使是快速点击,也能减少大约 200ms 的加载时间。
466
+ - `render`,当 Link 组件渲染时,就会加载对应的分片和 Data Loader 中定义的数据。
467
467
 
468
468
  #### 常见问题
469
469
 
470
470
  1. 使用 `render` 和不根据路由做静态资源分片的区别?
471
471
 
472
- - 使用 `render` 可以指定哪些路由在首屏时,进行加载,同时你可以通过对渲染的控制,仅当 Link 组件进入到可视区域时,才对 Link 组件进行渲染。
472
+ - 使用 `render` 可以指定哪些路由在首屏时,进行加载,同时你可以通过对渲染的控制,仅当 `Link` 组件进入到可视区域时,才对 `Link` 组件进行渲染。
473
473
  - 使用 `render`,仅在空闲时对静态资源进行加载,不会与首屏静态资源抢占网络。
474
474
  - 在 SSR 场景下,也会对数据进行预取。
475
475
 
@@ -484,7 +484,7 @@ import Practice from '@site-docs/components/routes-practice'
484
484
 
485
485
  ## 自控式路由
486
486
 
487
- 以 `src/App.tsx` 为约定的入口,Modern.js 不会多路由做额外的操作,开发者可以自行使用 React Router 6 的 API 进行开发,例如:
487
+ 以 `src/App.tsx` 为约定的入口,Modern.js 不会对路由做额外的操作,开发者可以自行使用 [React Router 6](https://reactrouter.com/en/main) 的 API 进行开发,例如:
488
488
 
489
489
  ```ts title="src/App.tsx"
490
490
  import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
@@ -2,6 +2,7 @@
2
2
  title: Hook 列表
3
3
  sidebar_position: 8
4
4
  ---
5
+
5
6
  # Hook 列表
6
7
 
7
8
  在 Modern.js 中暴露了三类插件:CLI、Runtime、Server。下面列举下各类中的 Hook:
@@ -166,7 +167,6 @@ export default (): CliPlugin => ({
166
167
  });
167
168
  ```
168
169
 
169
-
170
170
  ### `commands`
171
171
 
172
172
  - 功能:为 command 添加新的命令
@@ -260,9 +260,9 @@ export default (): CliPlugin => ({
260
260
  ### `afterDev`
261
261
 
262
262
  - 功能:运行 dev 主流程的之后的任务
263
- - 执行阶段:`dev` 命令运行时,项目启动完成之后执行
263
+ - 执行阶段:运行 `dev` 命令时,每一次编译完成后执行
264
264
  - Hook 模型:AsyncWorkflow
265
- - 类型:`AsyncWorkflow<void, unknown>`
265
+ - 类型:`AsyncWorkflow<{ isFirstCompile: boolean }, unknown>`
266
266
  - 使用示例:
267
267
 
268
268
  ```ts
@@ -279,6 +279,24 @@ export default (): CliPlugin => ({
279
279
  });
280
280
  ```
281
281
 
282
+ `afterDev` 会在每一次编译完成后执行,你可以通过 `isFirstCompile` 参数来判断是否为首次编译:
283
+
284
+ ```ts
285
+ import type { CliPlugin } from '@modern-js/core';
286
+
287
+ export default (): CliPlugin => ({
288
+ setup(api) {
289
+ return {
290
+ afterDev: ({ isFirstCompile }) => {
291
+ if (isFirstCompile) {
292
+ // do something
293
+ }
294
+ },
295
+ };
296
+ },
297
+ });
298
+ ```
299
+
282
300
  ### `beforeCreateCompiler`
283
301
 
284
302
  - 功能:在中间件函数中可以拿到创建 Webpack Compiler 的 Webpack 配置
@@ -438,7 +456,7 @@ import type { CliPlugin } from '@modern-js/core';
438
456
  export default (): CliPlugin => ({
439
457
  setup(api) {
440
458
  return {
441
- modifyEntryImports({ entrypoint, exportStatement }) {
459
+ modifyEntryExport({ entrypoint, exportStatement }) {
442
460
  return {
443
461
  entrypoint,
444
462
  exportStatement: [`export const foo = 'test'`, exportStatement].join(
@@ -778,7 +796,7 @@ export default (): Plugin => ({
778
796
  );
779
797
  };
780
798
  return next({
781
- App: hoistNonReactStatics(AppWrapper, App)
799
+ App: hoistNonReactStatics(AppWrapper, App),
782
800
  });
783
801
  },
784
802
  };
package/package.json CHANGED
@@ -15,27 +15,27 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.20.0",
18
+ "version": "2.21.0",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public"
22
22
  },
23
23
  "peerDependencies": {
24
- "@modern-js/builder-doc": "^2.20.0"
24
+ "@modern-js/builder-doc": "^2.21.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "classnames": "^2",
28
28
  "clsx": "^1.2.1",
29
29
  "react": "^18",
30
30
  "react-dom": "^18",
31
- "ts-node": "^10",
32
- "typescript": "^4",
31
+ "ts-node": "^10.9.1",
32
+ "typescript": "^5",
33
33
  "fs-extra": "^10",
34
34
  "@types/node": "^16",
35
35
  "@types/fs-extra": "^9",
36
- "@modern-js/builder-doc": "2.20.0",
37
- "@modern-js/doc-tools": "2.20.0",
38
- "@modern-js/doc-plugin-auto-sidebar": "2.20.0"
36
+ "@modern-js/builder-doc": "2.21.0",
37
+ "@modern-js/doc-tools": "2.21.0",
38
+ "@modern-js/doc-plugin-auto-sidebar": "2.21.0"
39
39
  },
40
40
  "scripts": {
41
41
  "dev": "modern dev",