@modern-js/main-doc 2.9.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +27 -0
- package/docs/en/apis/app/hooks/src/server.mdx +1 -28
- package/docs/en/apis/app/runtime/web-server/hook.mdx +1 -3
- package/docs/en/apis/app/runtime/web-server/middleware.mdx +1 -4
- package/docs/en/blog/index.md +8 -0
- package/docs/en/configure/app/output/splitRouteChunks.mdx +20 -0
- package/docs/en/configure/app/source/config-dir.mdx +2 -2
- package/docs/en/configure/app/source/design-system.mdx +2 -2
- package/docs/en/configure/app/source/disable-default-entries.mdx +12 -12
- package/docs/en/configure/app/source/disable-entry-dirs.mdx +3 -4
- package/docs/en/configure/app/source/enable-async-entry.mdx +2 -2
- package/docs/en/configure/app/source/entries-dir.mdx +10 -10
- package/docs/en/configure/app/source/entries.mdx +83 -26
- package/docs/en/configure/app/source/plugin-import.mdx +13 -0
- package/docs/en/configure/app/source/transform-import.mdx +13 -0
- package/docs/en/configure/app/tools/esbuild.mdx +9 -4
- package/docs/en/configure/app/tools/jest.mdx +2 -3
- package/docs/en/configure/app/tools/swc.mdx +6 -2
- package/docs/en/guides/advanced-features/compatibility.mdx +1 -0
- package/docs/en/guides/advanced-features/rspack-start.mdx +1 -1
- package/docs/en/guides/advanced-features/ssr.mdx +4 -3
- package/docs/en/guides/advanced-features/web-server.mdx +1 -1
- package/docs/en/guides/concept/entries.mdx +130 -39
- package/docs/en/guides/get-started/introduction.mdx +1 -1
- package/docs/en/guides/get-started/quick-start.mdx +2 -0
- package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +7 -3
- package/docs/en/guides/topic-detail/framework-plugin/plugin-api.mdx +29 -28
- package/docs/en/guides/topic-detail/generator/codesmith/api/fs.mdx +2 -2
- package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +4 -4
- package/docs/en/tutorials/first-app/c06-model.mdx +15 -12
- package/docs/en/tutorials/first-app/c07-container.mdx +22 -19
- package/docs/zh/apis/app/hooks/src/server.mdx +1 -28
- package/docs/zh/apis/app/runtime/web-server/hook.mdx +1 -3
- package/docs/zh/apis/app/runtime/web-server/middleware.mdx +1 -4
- package/docs/zh/blog/index.md +71 -3
- package/docs/zh/blog/updates/2022-0708-updates.md +96 -0
- package/docs/zh/blog/updates/2022-0910-updates.md +80 -0
- package/docs/zh/blog/updates/_category_.json +5 -0
- package/docs/zh/blog/updates/v2-release-note.mdx +250 -0
- package/docs/zh/configure/app/output/splitRouteChunks.mdx +20 -0
- package/docs/zh/configure/app/source/config-dir.mdx +2 -2
- package/docs/zh/configure/app/source/design-system.mdx +3 -3
- package/docs/zh/configure/app/source/disable-default-entries.mdx +11 -10
- package/docs/zh/configure/app/source/disable-entry-dirs.mdx +2 -3
- package/docs/zh/configure/app/source/enable-async-entry.mdx +3 -3
- package/docs/zh/configure/app/source/entries-dir.mdx +10 -11
- package/docs/zh/configure/app/source/entries.mdx +84 -23
- package/docs/zh/configure/app/source/plugin-import.mdx +13 -0
- package/docs/zh/configure/app/source/transform-import.mdx +13 -0
- package/docs/zh/configure/app/tools/esbuild.mdx +9 -5
- package/docs/zh/configure/app/tools/jest.mdx +2 -3
- package/docs/zh/configure/app/tools/swc.mdx +6 -2
- package/docs/zh/guides/advanced-features/compatibility.mdx +1 -0
- package/docs/zh/guides/advanced-features/eslint.mdx +1 -1
- package/docs/zh/guides/advanced-features/rspack-start.mdx +1 -1
- package/docs/zh/guides/advanced-features/ssr.mdx +6 -3
- package/docs/zh/guides/advanced-features/web-server.mdx +10 -5
- package/docs/zh/guides/concept/entries.mdx +36 -35
- package/docs/zh/guides/get-started/quick-start.mdx +2 -0
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +6 -2
- package/docs/zh/guides/topic-detail/framework-plugin/plugin-api.mdx +30 -29
- package/docs/zh/guides/topic-detail/generator/codesmith/api/fs.mdx +2 -2
- package/docs/zh/tutorials/first-app/c06-model.mdx +14 -12
- package/docs/zh/tutorials/first-app/c07-container.mdx +22 -19
- package/modern.config.ts +6 -7
- package/package.json +5 -5
- package/src/pages/index.tsx +10 -5
- package/en/configure/app/dev/asset-prefix.mdx +0 -13
- package/en/configure/app/dev/before-start-url.mdx +0 -13
- package/en/configure/app/dev/hmr.mdx +0 -13
- package/en/configure/app/dev/host.mdx +0 -13
- package/en/configure/app/dev/https.mdx +0 -13
- package/en/configure/app/dev/port.mdx +0 -13
- package/en/configure/app/dev/progress-bar.mdx +0 -13
- package/en/configure/app/dev/start-url.mdx +0 -13
- package/en/configure/app/experiments/lazy-compilation.mdx +0 -13
- package/en/configure/app/html/app-icon.mdx +0 -13
- package/en/configure/app/html/crossorigin.mdx +0 -13
- package/en/configure/app/html/disable-html-folder.mdx +0 -13
- package/en/configure/app/html/favicon-by-entries.mdx +0 -13
- package/en/configure/app/html/favicon.mdx +0 -13
- package/en/configure/app/html/inject-by-entries.mdx +0 -13
- package/en/configure/app/html/inject.mdx +0 -13
- package/en/configure/app/html/meta-by-entries.mdx +0 -13
- package/en/configure/app/html/meta.mdx +0 -13
- package/en/configure/app/html/mount-id.mdx +0 -13
- package/en/configure/app/html/tags-by-entries.mdx +0 -13
- package/en/configure/app/html/tags.mdx +0 -13
- package/en/configure/app/html/template-by-entries.mdx +0 -13
- package/en/configure/app/html/template-parameters-by-entries.mdx +0 -13
- package/en/configure/app/html/template-parameters.mdx +0 -13
- package/en/configure/app/html/template.mdx +0 -13
- package/en/configure/app/html/title-by-entries.mdx +0 -13
- package/en/configure/app/html/title.mdx +0 -13
- package/en/configure/app/output/asset-prefix.mdx +0 -13
- package/en/configure/app/output/assets-retry.mdx +0 -13
- package/en/configure/app/output/charset.mdx +0 -13
- package/en/configure/app/output/clean-dist-path.mdx +0 -13
- package/en/configure/app/output/convert-to-rem.mdx +0 -13
- package/en/configure/app/output/copy.mdx +0 -13
- package/en/configure/app/output/css-module-local-ident-name.mdx +0 -13
- package/en/configure/app/output/data-uri-limit.mdx +0 -13
- package/en/configure/app/output/disable-css-extract.mdx +0 -13
- package/en/configure/app/output/disable-css-module-extension.mdx +0 -13
- package/en/configure/app/output/disable-filename-hash.mdx +0 -13
- package/en/configure/app/output/disable-inline-runtime-chunk.mdx +0 -13
- package/en/configure/app/output/disable-minimize.mdx +0 -13
- package/en/configure/app/output/disable-source-map.mdx +0 -13
- package/en/configure/app/output/disable-ts-checker.mdx +0 -13
- package/en/configure/app/output/dist-path.mdx +0 -13
- package/en/configure/app/output/enable-asset-fallback.mdx +0 -13
- package/en/configure/app/output/enable-asset-manifest.mdx +0 -13
- package/en/configure/app/output/enable-css-module-tsdeclaration.mdx +0 -13
- package/en/configure/app/output/enable-inline-scripts.mdx +0 -13
- package/en/configure/app/output/enable-inline-styles.mdx +0 -13
- package/en/configure/app/output/enable-latest-decorators.mdx +0 -13
- package/en/configure/app/output/externals.mdx +0 -13
- package/en/configure/app/output/filename.mdx +0 -13
- package/en/configure/app/output/legal-comments.mdx +0 -13
- package/en/configure/app/output/override-browserslist.mdx +0 -13
- package/en/configure/app/output/polyfill.mdx +0 -13
- package/en/configure/app/output/svg-default-export.mdx +0 -13
- package/en/configure/app/performance/build-cache.mdx +0 -13
- package/en/configure/app/performance/bundle-analyze.mdx +0 -13
- package/en/configure/app/performance/chunk-split.mdx +0 -13
- package/en/configure/app/performance/print-file-size.mdx +0 -13
- package/en/configure/app/performance/profile.mdx +0 -13
- package/en/configure/app/performance/remove-console.mdx +0 -13
- package/en/configure/app/performance/remove-moment-locale.mdx +0 -13
- package/en/configure/app/security/check-syntax.mdx +0 -13
- package/en/configure/app/security/sri.mdx +0 -13
- package/en/configure/app/source/alias.mdx +0 -13
- package/en/configure/app/source/compile-js-data-uri.mdx +0 -13
- package/en/configure/app/source/define.mdx +0 -13
- package/en/configure/app/source/exclude.mdx +0 -13
- package/en/configure/app/source/global-vars.mdx +0 -13
- package/en/configure/app/source/include.mdx +0 -13
- package/en/configure/app/source/module-scopes.mdx +0 -13
- package/en/configure/app/source/pre-entry.mdx +0 -13
- package/en/configure/app/source/resolve-extension-prefix.mdx +0 -13
- package/en/configure/app/source/resolve-main-fields.mdx +0 -13
- package/en/configure/app/tools/autoprefixer.mdx +0 -13
- package/en/configure/app/tools/babel.mdx +0 -13
- package/en/configure/app/tools/css-extract.mdx +0 -13
- package/en/configure/app/tools/css-loader.mdx +0 -13
- package/en/configure/app/tools/dev-server.mdx +0 -13
- package/en/configure/app/tools/html-plugin.mdx +0 -13
- package/en/configure/app/tools/inspector.mdx +0 -13
- package/en/configure/app/tools/less.mdx +0 -13
- package/en/configure/app/tools/minify-css.mdx +0 -13
- package/en/configure/app/tools/postcss.mdx +0 -13
- package/en/configure/app/tools/pug.mdx +0 -13
- package/en/configure/app/tools/rspack.mdx +0 -13
- package/en/configure/app/tools/sass.mdx +0 -13
- package/en/configure/app/tools/style-loader.mdx +0 -13
- package/en/configure/app/tools/styled-components.mdx +0 -13
- package/en/configure/app/tools/terser.mdx +0 -13
- package/en/configure/app/tools/ts-checker.mdx +0 -13
- package/en/configure/app/tools/ts-loader.mdx +0 -13
- package/en/configure/app/tools/webpack-chain.mdx +0 -13
- package/en/configure/app/tools/webpack.mdx +0 -13
- package/zh/configure/app/dev/asset-prefix.mdx +0 -13
- package/zh/configure/app/dev/before-start-url.mdx +0 -13
- package/zh/configure/app/dev/hmr.mdx +0 -13
- package/zh/configure/app/dev/host.mdx +0 -13
- package/zh/configure/app/dev/https.mdx +0 -13
- package/zh/configure/app/dev/port.mdx +0 -13
- package/zh/configure/app/dev/progress-bar.mdx +0 -13
- package/zh/configure/app/dev/start-url.mdx +0 -13
- package/zh/configure/app/experiments/lazy-compilation.mdx +0 -13
- package/zh/configure/app/html/app-icon.mdx +0 -13
- package/zh/configure/app/html/crossorigin.mdx +0 -13
- package/zh/configure/app/html/disable-html-folder.mdx +0 -13
- package/zh/configure/app/html/favicon-by-entries.mdx +0 -13
- package/zh/configure/app/html/favicon.mdx +0 -13
- package/zh/configure/app/html/inject-by-entries.mdx +0 -13
- package/zh/configure/app/html/inject.mdx +0 -13
- package/zh/configure/app/html/meta-by-entries.mdx +0 -13
- package/zh/configure/app/html/meta.mdx +0 -13
- package/zh/configure/app/html/mount-id.mdx +0 -13
- package/zh/configure/app/html/tags-by-entries.mdx +0 -13
- package/zh/configure/app/html/tags.mdx +0 -13
- package/zh/configure/app/html/template-by-entries.mdx +0 -13
- package/zh/configure/app/html/template-parameters-by-entries.mdx +0 -13
- package/zh/configure/app/html/template-parameters.mdx +0 -13
- package/zh/configure/app/html/template.mdx +0 -13
- package/zh/configure/app/html/title-by-entries.mdx +0 -13
- package/zh/configure/app/html/title.mdx +0 -13
- package/zh/configure/app/output/asset-prefix.mdx +0 -13
- package/zh/configure/app/output/assets-retry.mdx +0 -13
- package/zh/configure/app/output/charset.mdx +0 -13
- package/zh/configure/app/output/clean-dist-path.mdx +0 -13
- package/zh/configure/app/output/convert-to-rem.mdx +0 -13
- package/zh/configure/app/output/copy.mdx +0 -13
- package/zh/configure/app/output/css-module-local-ident-name.mdx +0 -13
- package/zh/configure/app/output/data-uri-limit.mdx +0 -13
- package/zh/configure/app/output/disable-css-extract.mdx +0 -13
- package/zh/configure/app/output/disable-css-module-extension.mdx +0 -13
- package/zh/configure/app/output/disable-filename-hash.mdx +0 -13
- package/zh/configure/app/output/disable-inline-runtime-chunk.mdx +0 -13
- package/zh/configure/app/output/disable-minimize.mdx +0 -13
- package/zh/configure/app/output/disable-source-map.mdx +0 -13
- package/zh/configure/app/output/disable-ts-checker.mdx +0 -13
- package/zh/configure/app/output/dist-path.mdx +0 -13
- package/zh/configure/app/output/enable-asset-fallback.mdx +0 -13
- package/zh/configure/app/output/enable-asset-manifest.mdx +0 -13
- package/zh/configure/app/output/enable-css-module-tsdeclaration.mdx +0 -13
- package/zh/configure/app/output/enable-inline-scripts.mdx +0 -13
- package/zh/configure/app/output/enable-inline-styles.mdx +0 -13
- package/zh/configure/app/output/enable-latest-decorators.mdx +0 -13
- package/zh/configure/app/output/externals.mdx +0 -13
- package/zh/configure/app/output/filename.mdx +0 -13
- package/zh/configure/app/output/legal-comments.mdx +0 -13
- package/zh/configure/app/output/override-browserslist.mdx +0 -13
- package/zh/configure/app/output/polyfill.mdx +0 -13
- package/zh/configure/app/output/svg-default-export.mdx +0 -13
- package/zh/configure/app/performance/build-cache.mdx +0 -13
- package/zh/configure/app/performance/bundle-analyze.mdx +0 -13
- package/zh/configure/app/performance/chunk-split.mdx +0 -13
- package/zh/configure/app/performance/print-file-size.mdx +0 -13
- package/zh/configure/app/performance/profile.mdx +0 -13
- package/zh/configure/app/performance/remove-console.mdx +0 -13
- package/zh/configure/app/performance/remove-moment-locale.mdx +0 -13
- package/zh/configure/app/security/check-syntax.mdx +0 -13
- package/zh/configure/app/security/sri.mdx +0 -13
- package/zh/configure/app/source/alias.mdx +0 -13
- package/zh/configure/app/source/compile-js-data-uri.mdx +0 -13
- package/zh/configure/app/source/define.mdx +0 -13
- package/zh/configure/app/source/exclude.mdx +0 -13
- package/zh/configure/app/source/global-vars.mdx +0 -13
- package/zh/configure/app/source/include.mdx +0 -13
- package/zh/configure/app/source/module-scopes.mdx +0 -13
- package/zh/configure/app/source/pre-entry.mdx +0 -13
- package/zh/configure/app/source/resolve-extension-prefix.mdx +0 -13
- package/zh/configure/app/source/resolve-main-fields.mdx +0 -13
- package/zh/configure/app/tools/autoprefixer.mdx +0 -13
- package/zh/configure/app/tools/babel.mdx +0 -13
- package/zh/configure/app/tools/css-extract.mdx +0 -13
- package/zh/configure/app/tools/css-loader.mdx +0 -13
- package/zh/configure/app/tools/dev-server.mdx +0 -13
- package/zh/configure/app/tools/html-plugin.mdx +0 -13
- package/zh/configure/app/tools/inspector.mdx +0 -13
- package/zh/configure/app/tools/less.mdx +0 -13
- package/zh/configure/app/tools/minify-css.mdx +0 -13
- package/zh/configure/app/tools/postcss.mdx +0 -13
- package/zh/configure/app/tools/pug.mdx +0 -13
- package/zh/configure/app/tools/rspack.mdx +0 -13
- package/zh/configure/app/tools/sass.mdx +0 -13
- package/zh/configure/app/tools/style-loader.mdx +0 -13
- package/zh/configure/app/tools/styled-components.mdx +0 -13
- package/zh/configure/app/tools/terser.mdx +0 -13
- package/zh/configure/app/tools/ts-checker.mdx +0 -13
- package/zh/configure/app/tools/ts-loader.mdx +0 -13
- package/zh/configure/app/tools/webpack-chain.mdx +0 -13
- package/zh/configure/app/tools/webpack.mdx +0 -13
@@ -4,26 +4,29 @@ sidebar_position: 1
|
|
4
4
|
|
5
5
|
# Entries
|
6
6
|
|
7
|
-
|
7
|
+
Through this chapter, you can learn about the entry convention in Modern.js and how to customize the entry.
|
8
8
|
|
9
|
-
|
9
|
+
## What is an Entry
|
10
|
+
|
11
|
+
**Entry is the starting module of a page.**
|
12
|
+
|
13
|
+
In the Modern.js project, each entry corresponds to an independent page, and also corresponds to a server route. By default, Modern.js will automatically determine the entry of the page based on the directory convention, and also supports customizing the entry through configuration items.
|
14
|
+
|
15
|
+
Many configuration items provided by Modern.js are divided by entry, such as page title, HTML template, page Meta information, whether to enable SSR/SSG, server-side routing rules, etc.
|
10
16
|
|
11
17
|
## Single Entry and Multiple Entries
|
12
18
|
|
13
|
-
Modern.js
|
19
|
+
The project initialized by Modern.js is single-entry (SPA), and the project structure is as follows:
|
14
20
|
|
15
21
|
```
|
16
22
|
.
|
17
23
|
├── src
|
18
|
-
│ ├── modern-app-env.d.ts
|
19
24
|
│ └── routes
|
20
25
|
│ ├── index.css
|
21
26
|
│ ├── layout.tsx
|
22
27
|
│ └── page.tsx
|
23
28
|
├── package.json
|
24
29
|
├── modern.config.ts
|
25
|
-
├── pnpm-lock.yaml
|
26
|
-
├── README.md
|
27
30
|
└── tsconfig.json
|
28
31
|
```
|
29
32
|
|
@@ -35,17 +38,16 @@ Modern.js can easily switch from single entry to multiple entry. You can execute
|
|
35
38
|
? Entry name: new-entry
|
36
39
|
```
|
37
40
|
|
38
|
-
After execution, the `src/` directory
|
41
|
+
After execution, Modern.js will automatically generate a new entry directory, and you can see that the `src/` directory has the following structure:
|
39
42
|
|
40
|
-
```
|
43
|
+
```bash
|
41
44
|
.
|
42
|
-
├──
|
43
|
-
├── myapp
|
45
|
+
├── myapp # Original entry
|
44
46
|
│ └── routes
|
45
47
|
│ ├── index.css
|
46
48
|
│ ├── layout.tsx
|
47
49
|
│ └── page.tsx
|
48
|
-
└── new-entry
|
50
|
+
└── new-entry # New entry
|
49
51
|
└── routes
|
50
52
|
├── index.css
|
51
53
|
├── layout.tsx
|
@@ -56,65 +58,154 @@ The original code was moved to the directory with the same name as the `name` in
|
|
56
58
|
|
57
59
|
After executing `pnpm run dev`, you can see that a `/new-entry` route has been added, and the migrated code route has not changed.
|
58
60
|
|
59
|
-
:::
|
60
|
-
Modern.js will use the
|
61
|
+
:::tip
|
62
|
+
Modern.js will use the entry with the same name as the `name` field in the package.json file as the main entry, the route of the main entry is `/`, and the route of other entries is `/{entryName}`.
|
63
|
+
|
64
|
+
For example, when `name` in package.json is `myapp`, `src/myapp` will be used as the main entry of the project.
|
61
65
|
|
62
66
|
:::
|
63
67
|
|
64
|
-
## Entry
|
68
|
+
## Entry Type
|
65
69
|
|
66
|
-
|
70
|
+
Different entry types have different compile and run-time behaviors. When creating a project in Modern.js, developers can manually choose to create a project in **framework mode** or **build mode**. After the creation is complete, you can see that the project template files for different modes are different.
|
71
|
+
|
72
|
+
By default, Modern.js will scan the files under `src/` before starting the project, identify the entry, and generate the corresponding server-side route.
|
67
73
|
|
68
74
|
:::tip
|
69
|
-
You can change the entry directory to another directory
|
75
|
+
You can change the entry directory to another directory through [source.entriesDir](/configure/app/source/entries-dir).
|
70
76
|
|
71
77
|
:::
|
72
78
|
|
73
|
-
Not all first-level directories under `src/` will become project
|
79
|
+
Not all first-level directories under `src/` will become project entries, and the directory where the entry is located must meet one of the following four conditions:
|
74
80
|
|
75
|
-
1.
|
76
|
-
2. Has
|
77
|
-
3.
|
78
|
-
4.
|
81
|
+
1. Have a `routes/` directory
|
82
|
+
2. Has `App.[jt]sx?` file
|
83
|
+
3. Has `index.[jt]sx?` file
|
84
|
+
4. Has a `pages/` directory (Modern.js 1.0 compatible)
|
79
85
|
|
80
|
-
When the `src/` directory
|
86
|
+
When the `src/` directory meets the entry characteristics, Modern.js will consider the current project as a single-entry application.
|
81
87
|
|
82
88
|
:::tip
|
83
|
-
|
89
|
+
In single-entry applications, the default entry is named `main`.
|
84
90
|
|
85
91
|
:::
|
86
92
|
|
87
|
-
When the project is not a single-entry application, Modern.js further
|
93
|
+
When the project is not a single-entry application, Modern.js will further check the first-level directory under `src/`.
|
94
|
+
|
95
|
+
### Framework Mode Entry
|
88
96
|
|
89
|
-
|
97
|
+
Framework mode refers to the need to use the capabilities of the Modern.js framework, such as Router, SSR, integrated calls, etc. Under this kind of entry agreement, the entry defined by the developer is not the real Webpack compilation entry. Modern.js will generate an encapsulated entry when it starts, and the real entry can be found in `node_modules/.modern/{entryName}/index.js`.
|
90
98
|
|
91
|
-
|
99
|
+
#### Conventional Routing
|
92
100
|
|
93
|
-
|
101
|
+
If there is a `routes/` directory in the entry, Modern.js will scan the files under `routes/` at startup, and automatically generate client-side routes (react-router) based on file conventions.
|
94
102
|
|
95
|
-
|
103
|
+
For details, please refer to [routing](/guides/basic-features/routes).
|
96
104
|
|
97
|
-
|
105
|
+
#### Custom Routing
|
98
106
|
|
99
|
-
|
107
|
+
If there is an `App.[jt]sx?` file in the entry, the developer can freely set the client route in this file, or not set the client route.
|
100
108
|
|
101
|
-
|
109
|
+
For details, please refer to [routing](/guides/basic-features/routes).
|
102
110
|
|
103
|
-
|
111
|
+
#### Custom App
|
104
112
|
|
105
|
-
|
113
|
+
If there is an `index.[jt]sx` file in the entry, and when the file exports functions by default, Modern.js will still generate the code wrapped by createApp according to the runtime settings. In the rendering process, the component wrapped by createApp is passed as a parameter to the function exported by the index file, so that developers can customize the component to be mounted on the DOM node, or add custom behavior before mounting. For example:
|
106
114
|
|
107
|
-
|
115
|
+
```tsx
|
116
|
+
import ReactDOM from 'react-dom/client';
|
117
|
+
import { bootstrap } from '@modern-js/runtime';
|
108
118
|
|
109
|
-
|
119
|
+
export default (App: React.ComponentType) => {
|
120
|
+
// do something before bootstrap...
|
121
|
+
bootstrap(App, 'root', undefined, ReactDOM);
|
122
|
+
};
|
123
|
+
```
|
124
|
+
|
125
|
+
:::warning
|
126
|
+
Since the bootstrap function needs to be compatible with React17 and React18, you need to manually pass in ReactDOM parameters when calling the bootstrap function.
|
127
|
+
|
128
|
+
:::
|
129
|
+
|
130
|
+
The content of the file generated by Modern.js is as follows:
|
110
131
|
|
111
|
-
|
132
|
+
```js
|
133
|
+
import React from 'react';
|
134
|
+
import ReactDOM from 'react-dom/client';
|
135
|
+
import customBootstrap from '@_edenx_src/index.tsx';
|
136
|
+
import App from '@_edenx_src/App';
|
137
|
+
import { router, state } from '@edenx/runtime/plugins';
|
112
138
|
|
113
|
-
|
139
|
+
const IS_BROWSER = typeof window !== 'undefined' && window.name !== 'nodejs';
|
140
|
+
const MOUNT_ID = 'root';
|
114
141
|
|
115
|
-
|
142
|
+
let AppWrapper = null;
|
143
|
+
|
144
|
+
function render() {
|
145
|
+
AppWrapper = createApp({
|
146
|
+
// plugin parameters for runtime...
|
147
|
+
})(App);
|
148
|
+
if (IS_BROWSER) {
|
149
|
+
customBootstrap(AppWrapper);
|
150
|
+
}
|
151
|
+
return AppWrapper;
|
152
|
+
}
|
153
|
+
|
154
|
+
AppWrapper = render();
|
155
|
+
|
156
|
+
export default AppWrapper;
|
157
|
+
```
|
158
|
+
|
159
|
+
### Build Mode Entry
|
160
|
+
|
161
|
+
Build mode refers to the ability not to use any Modern.js runtime, and the developer defines the entry of the project Webpack completely by himself.
|
162
|
+
|
163
|
+
If `index.[jt]sx` exists in the entry and there is no default export function, then this file is the real Webpack entry file. This is similar to [Create React App](https://github.com/facebook/create-react-app), you need to mount components to DOM nodes, add hot update code, etc. For example:
|
164
|
+
|
165
|
+
```js title=src/index.jsx
|
166
|
+
import React from 'react';
|
167
|
+
import ReactDOM from 'react-dom';
|
168
|
+
import App from './App';
|
169
|
+
|
170
|
+
ReactDOM.render(<App />, document.getElementById('root'));
|
171
|
+
```
|
172
|
+
|
173
|
+
Modern.js **not recommended** to use this method, this method loses some capabilities of the framework, such as the `runtime` configuration in the **`modern.config.js` file will no longer take effect**. But this method will be very useful when the project is migrated from other frameworks to Modern.js, such as CRA, or webpack that is manually built by yourself.
|
174
|
+
|
175
|
+
## Custom Entry
|
176
|
+
|
177
|
+
Most existing projects are not built according to the directory convention of Modern.js. If you want to change to the directory structure agreed by Modern.js, there will be a certain migration cost.
|
178
|
+
|
179
|
+
In this case, instead of generating the entry using file conventions, you can manually configure the entry in `modern.config.[jt]s`.
|
180
|
+
|
181
|
+
```ts title="modern.config.ts"
|
182
|
+
export default defineConfig({
|
183
|
+
source: {
|
184
|
+
entries: {
|
185
|
+
// Specify a new entry named entry_customize
|
186
|
+
entry_customize: './src/home/test/index.ts',
|
187
|
+
},
|
188
|
+
// Disable default ingress scanning
|
189
|
+
disableDefaultEntries: true,
|
190
|
+
},
|
191
|
+
});
|
192
|
+
```
|
193
|
+
|
194
|
+
### Disable Default Entries
|
195
|
+
|
196
|
+
When using a custom entry, part of the project structure may happen to hit the directory convention of Modern.js, but in fact this part of the directory is not the real entry.
|
197
|
+
|
198
|
+
Modern.js provides `disableDefaultEntries` config to disable default entry scanning rules. When you need to customize the entry, you generally need to use `disableDefaultEntries` with `entries`. In this way, some existing projects can be quickly migrated without modifying the directory structure.
|
199
|
+
|
200
|
+
```ts title="modern.config.ts"
|
201
|
+
export default defineConfig({
|
202
|
+
source: {
|
203
|
+
disableDefaultEntries: true,
|
204
|
+
},
|
205
|
+
});
|
206
|
+
```
|
116
207
|
|
117
208
|
:::tip
|
118
|
-
|
209
|
+
For detailed usage, please refer to [source.entries](/configure/app/source/entries) and [source.disableDefaultEntries](/configure/app/source/disable-default-entries).
|
119
210
|
|
120
211
|
:::
|
@@ -9,7 +9,7 @@ sidebar_position: 1
|
|
9
9
|
|
10
10
|
Currently, Modern.js includes three solutions, each targeting at different development scenarios: web application development, npm package development, and document site development:
|
11
11
|
|
12
|
-

|
13
13
|
|
14
14
|
As a part of the Modern.js engineering system, each of these solutions can be used separately and has its own independent documentation site. Developers can choose one or more solutions as needed.
|
15
15
|
|
@@ -139,6 +139,8 @@ The bundle is generated to `dist/` by default, and the directory structure is as
|
|
139
139
|
└── js
|
140
140
|
```
|
141
141
|
|
142
|
+
> If you want to customize the output directory, please refer to [Output Files](https://modernjs.dev/builder/en/guide/basic/output-files.html).
|
143
|
+
|
142
144
|
## Verify
|
143
145
|
|
144
146
|
Execute `pnpm run serve` in the project to verify locally that the bundle is running correctly:
|
@@ -191,8 +191,8 @@ foo
|
|
191
191
|
|
192
192
|
- Functionality: Reset some file states before exiting the process.
|
193
193
|
- Execution phase: Before the process exits.
|
194
|
-
- Hook model:
|
195
|
-
- Type: `
|
194
|
+
- Hook model: Workflow
|
195
|
+
- Type: `Workflow<void, void>`
|
196
196
|
- Example usage:
|
197
197
|
|
198
198
|
```ts
|
@@ -209,6 +209,10 @@ export default (): CliPlugin => ({
|
|
209
209
|
});
|
210
210
|
```
|
211
211
|
|
212
|
+
:::tip
|
213
|
+
Since the callback function when exiting the process in Node.js is synchronous, the type of `beforeExit` Hook is `Workflow` and cannot perform asynchronous operations.
|
214
|
+
:::
|
215
|
+
|
212
216
|
### `beforeDev`
|
213
217
|
|
214
218
|
- Functionality: Tasks before running the main dev process.
|
@@ -442,7 +446,7 @@ export default (): CliPlugin => ({
|
|
442
446
|
modifyEntryRuntimePlugins({ entrypoint, plugins }) {
|
443
447
|
const name = 'customPlugin';
|
444
448
|
const options = {
|
445
|
-
/**
|
449
|
+
/** serializable content */
|
446
450
|
};
|
447
451
|
|
448
452
|
return {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
title: Plugin API
|
3
3
|
sidebar_position: 6
|
4
4
|
---
|
5
|
+
|
5
6
|
# Plugin API
|
6
7
|
|
7
8
|
The `setup` function of the plugin will receive an `api` imported parameter, and you can call some methods provided on the api to obtain information such as configuration and application context.
|
@@ -36,17 +37,40 @@ interface UserConfig {
|
|
36
37
|
source?: SourceConfig;
|
37
38
|
output?: OutputConfig;
|
38
39
|
server?: ServerConfig;
|
39
|
-
dev?: DevConfig;
|
40
40
|
deploy?: DeployConfig;
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
// ...other fields
|
42
|
+
}
|
43
|
+
```
|
44
|
+
|
45
|
+
Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
|
46
|
+
|
47
|
+
:::tip
|
48
|
+
This method returns a read-only configuration and cannot be modified. If you need to modify the configuration, please use [config hook](/guides/topic-detail/framework-plugin/hook-list.html#config).
|
49
|
+
:::
|
50
|
+
|
51
|
+
### useResolvedConfigContext
|
52
|
+
|
53
|
+
Used to retrieve the final configuration after parsing.
|
54
|
+
|
55
|
+
```ts
|
56
|
+
const useResolvedConfigContext: () => NormalizedConfig;
|
57
|
+
|
58
|
+
interface NormalizedConfig {
|
59
|
+
source: NormalizedSourceConfig;
|
60
|
+
output: NormalizedOutputConfig;
|
61
|
+
server: NormalizedServerConfig;
|
62
|
+
deploy: NormalizedDeployConfig;
|
63
|
+
_raw: UserConfig; // the original user config
|
64
|
+
// ...other fields
|
45
65
|
}
|
46
66
|
```
|
47
67
|
|
48
68
|
Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
|
49
69
|
|
70
|
+
:::tip
|
71
|
+
This method returns a read-only configuration and cannot be modified. If you need to modify the configuration, please use [config hook](/guides/topic-detail/framework-plugin/hook-list.html#config).
|
72
|
+
:::
|
73
|
+
|
50
74
|
### useAppContext
|
51
75
|
|
52
76
|
Used to retrieve the runtime context of the application.
|
@@ -75,29 +99,6 @@ interface IAppContext {
|
|
75
99
|
}
|
76
100
|
```
|
77
101
|
|
78
|
-
### useResolvedConfigContext
|
79
|
-
|
80
|
-
Used to retrieve the final configuration after parsing.
|
81
|
-
|
82
|
-
```ts
|
83
|
-
const useResolvedConfigContext: () => NormalizedConfig;
|
84
|
-
|
85
|
-
interface NormalizedConfig {
|
86
|
-
source: NormalizedSourceConfig;
|
87
|
-
output: OutputConfig;
|
88
|
-
server: ServerConfig;
|
89
|
-
dev: DevConfig;
|
90
|
-
deploy: DeployConfig;
|
91
|
-
tools: NormalizedToolsConfig;
|
92
|
-
plugins: PluginConfig;
|
93
|
-
runtime: RuntimeConfig;
|
94
|
-
runtimeByEntries?: RuntimeByEntriesConfig;
|
95
|
-
_raw: UserConfig;
|
96
|
-
}
|
97
|
-
```
|
98
|
-
|
99
|
-
Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
|
100
|
-
|
101
102
|
### useHookRunners
|
102
103
|
|
103
104
|
Used to retrieve the executor of Hooks and trigger the execution of specific Hooks.
|
@@ -12,8 +12,8 @@ API wrapper for file operations in microgenerators, providing methods to render
|
|
12
12
|
import { FsAPI } from '@modern-js/codesmith-api-fs';
|
13
13
|
|
14
14
|
export default async (context: GeneratorContext, generator: GeneratorCore) => {
|
15
|
-
const
|
16
|
-
await
|
15
|
+
const fsApi = new FsAPI(generator);
|
16
|
+
await fsApi.renderFile(
|
17
17
|
material.get('templates/a.js'),
|
18
18
|
target: 'b.js'
|
19
19
|
);
|
@@ -47,7 +47,7 @@ export const bar = model<State>('bar').define({
|
|
47
47
|
data: '',
|
48
48
|
},
|
49
49
|
computed: {
|
50
|
-
//
|
50
|
+
// specify the type for fooState
|
51
51
|
withFoo: [foo, (state, fooState: FooState) => state.data + fooState.data],
|
52
52
|
},
|
53
53
|
});
|
@@ -62,11 +62,11 @@ Reduck provides a set of utility types for getting Model type information:
|
|
62
62
|
|
63
63
|
```ts
|
64
64
|
export const foo = model<State2>('foo').define({
|
65
|
-
//
|
65
|
+
// skip some codes
|
66
66
|
});
|
67
67
|
|
68
|
-
//
|
68
|
+
// get the State type of foo
|
69
69
|
let fooActions: GetModelActions<typeof foo>;
|
70
|
-
//
|
70
|
+
// get the Actions type of foo
|
71
71
|
let fooState: GetModelState<typeof foo>;
|
72
72
|
```
|
@@ -195,18 +195,10 @@ const Item = ({
|
|
195
195
|
export default Item;
|
196
196
|
```
|
197
197
|
|
198
|
-
Next, we modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
|
198
|
+
Next, we add `src/routes.page.loader` and modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
|
199
199
|
|
200
|
-
```tsx
|
201
|
-
|
202
|
-
import { useModel } from '@modern-js/runtime/model';
|
203
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
204
|
-
import { List } from 'antd';
|
205
|
-
import { name, internet } from 'faker';
|
206
|
-
import Item from '../components/Item';
|
207
|
-
import contacts from '../models/contacts';
|
208
|
-
|
209
|
-
type LoaderData = {
|
200
|
+
```tsx title="src/routes/page.loader.ts"
|
201
|
+
export type LoaderData = {
|
210
202
|
code: number;
|
211
203
|
data: {
|
212
204
|
name: string;
|
@@ -215,7 +207,7 @@ type LoaderData = {
|
|
215
207
|
}[];
|
216
208
|
};
|
217
209
|
|
218
|
-
export
|
210
|
+
export default async (): Promise<LoaderData> => {
|
219
211
|
const data = new Array(20).fill(0).map(() => {
|
220
212
|
const firstName = name.firstName();
|
221
213
|
return {
|
@@ -231,6 +223,17 @@ export const loader = async (): Promise<LoaderData> => {
|
|
231
223
|
data,
|
232
224
|
};
|
233
225
|
};
|
226
|
+
```
|
227
|
+
|
228
|
+
```tsx title="src/routes/page.tsx"
|
229
|
+
import { Helmet } from '@modern-js/runtime/head';
|
230
|
+
import { useModel } from '@modern-js/runtime/model';
|
231
|
+
import { useLoaderData } from '@modern-js/runtime/router';
|
232
|
+
import { List } from 'antd';
|
233
|
+
import { name, internet } from 'faker';
|
234
|
+
import Item from '../components/Item';
|
235
|
+
import contacts from '../models/contacts';
|
236
|
+
import type { LoaderData } from './page.loader';
|
234
237
|
|
235
238
|
function Index() {
|
236
239
|
const { data } = useLoaderData() as LoaderData;
|
@@ -15,24 +15,8 @@ Because the two pages need to share the same set of state (point of contact tabu
|
|
15
15
|
|
16
16
|
Modern.js support obtaining data through Data Loader in `layout.tsx`, we first move the data acquisition part of the code to `src/routes/layout.tsx`:
|
17
17
|
|
18
|
-
```
|
19
|
-
|
20
|
-
import {
|
21
|
-
Outlet,
|
22
|
-
useLoaderData,
|
23
|
-
useLocation,
|
24
|
-
useNavigate,
|
25
|
-
} from '@modern-js/runtime/router';
|
26
|
-
import { useState } from 'react';
|
27
|
-
import { Radio, RadioChangeEvent } from 'antd';
|
28
|
-
import { useModel } from '@modern-js/runtime/model';
|
29
|
-
import contacts from '../models/contacts';
|
30
|
-
import 'tailwindcss/base.css';
|
31
|
-
import 'tailwindcss/components.css';
|
32
|
-
import 'tailwindcss/utilities.css';
|
33
|
-
import '../styles/utils.css';
|
34
|
-
|
35
|
-
type LoaderData = {
|
18
|
+
```ts title="src/routes/layout.loader.ts"
|
19
|
+
export type LoaderData = {
|
36
20
|
code: number;
|
37
21
|
data: {
|
38
22
|
name: string;
|
@@ -41,7 +25,7 @@ type LoaderData = {
|
|
41
25
|
}[];
|
42
26
|
};
|
43
27
|
|
44
|
-
export
|
28
|
+
export default async (): Promise<LoaderData> => {
|
45
29
|
const data = new Array(20).fill(0).map(() => {
|
46
30
|
const firstName = name.firstName();
|
47
31
|
return {
|
@@ -56,6 +40,25 @@ export const loader = async (): Promise<LoaderData> => {
|
|
56
40
|
data,
|
57
41
|
};
|
58
42
|
};
|
43
|
+
```
|
44
|
+
|
45
|
+
```tsx title="src/routes/layout.tsx"
|
46
|
+
import { name, internet } from 'faker';
|
47
|
+
import {
|
48
|
+
Outlet,
|
49
|
+
useLoaderData,
|
50
|
+
useLocation,
|
51
|
+
useNavigate,
|
52
|
+
} from '@modern-js/runtime/router';
|
53
|
+
import { useState } from 'react';
|
54
|
+
import { Radio, RadioChangeEvent } from 'antd';
|
55
|
+
import { useModel } from '@modern-js/runtime/model';
|
56
|
+
import contacts from '../models/contacts';
|
57
|
+
import 'tailwindcss/base.css';
|
58
|
+
import 'tailwindcss/components.css';
|
59
|
+
import 'tailwindcss/utilities.css';
|
60
|
+
import '../styles/utils.css';
|
61
|
+
import type { LoaderData } from './layout.loader';
|
59
62
|
|
60
63
|
export default function Layout() {
|
61
64
|
const { data } = useLoaderData() as LoaderData;
|
@@ -4,31 +4,4 @@ sidebar_position: 8
|
|
4
4
|
---
|
5
5
|
# *.[server|node].[tj]sx
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
1. 当 `*.tsx` 和 `*.[server|node].tsx` 共存时,SSR 在服务端执行渲染时,会优先使用 `*.[server|node].tsx` 文件,而不是 `*.tsx` 文件。
|
10
|
-
|
11
|
-
2. 在使用 [data loader](/guides/basic-features/data-fetch) 时,需要将服务端的依赖从该文件中做重导出
|
12
|
-
|
13
|
-
```tsx
|
14
|
-
// routes/user/avatar.tsx
|
15
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
16
|
-
import { readFile } from './utils.server';
|
17
|
-
|
18
|
-
type ProfileData = {
|
19
|
-
/* some type declarations */
|
20
|
-
};
|
21
|
-
|
22
|
-
export const loader = async (): ProfileData => {
|
23
|
-
const profile = await readFile('profile.json');
|
24
|
-
return profile;
|
25
|
-
};
|
26
|
-
|
27
|
-
export default function UserPage() {
|
28
|
-
const profileData = useLoaderData() as ProfileData;
|
29
|
-
return <div>{profileData}</div>;
|
30
|
-
}
|
31
|
-
|
32
|
-
// routes/user/utils.server.ts
|
33
|
-
export * from 'fs-extra';
|
34
|
-
```
|
7
|
+
应用项目中使用,用于放置服务端代码,当 `*.tsx` 和 `*.[server|node].tsx` 共存时,SSR 在服务端执行渲染时,会优先使用 `*.[server|node].tsx` 文件,而不是 `*.tsx` 文件。
|
@@ -36,9 +36,7 @@ type HookContext = {
|
|
36
36
|
set: (key: string, value: string) => void;
|
37
37
|
status: (code: number) => void;
|
38
38
|
cookies: {
|
39
|
-
|
40
|
-
set: (key: string, value: string) => void;
|
41
|
-
delete: () => void;
|
39
|
+
set: (key: string, value: string, options?: any) => void;
|
42
40
|
clear: () => void;
|
43
41
|
};
|
44
42
|
raw: (
|
@@ -45,11 +45,8 @@ type MiddlewareContext = {
|
|
45
45
|
set: (key: string, value: string) => void;
|
46
46
|
status: (code: number) => void;
|
47
47
|
cookies: {
|
48
|
-
|
49
|
-
set: (key: string, value: string) => void;
|
50
|
-
delete: () => void;
|
48
|
+
set: (key: string, value: string, options?: any) => void;
|
51
49
|
clear: () => void;
|
52
|
-
apply: () => void;
|
53
50
|
};
|
54
51
|
raw: (
|
55
52
|
body: string,
|
package/docs/zh/blog/index.md
CHANGED
@@ -1,6 +1,74 @@
|
|
1
1
|
---
|
2
|
-
|
2
|
+
sidebar_position: 1
|
3
3
|
---
|
4
|
-
# Modern.js 2.0
|
5
4
|
|
6
|
-
|
5
|
+
# 博客
|
6
|
+
|
7
|
+
在这里,你可以了解到 Modern.js 的最新进展和技术分享。
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
## Modern.js v2 发布:支持 Rspack 构建
|
12
|
+
|
13
|
+
> 发表于 2023.03.16
|
14
|
+
|
15
|
+
大家好,很高兴地向大家宣布,Modern.js v2 版本已经正式发布了!
|
16
|
+
|
17
|
+
Modern.js 是字节跳动 Web Infra 团队开源的一套 Web 工程体系。在开源以来的一年多时间里,Modern.js 保持稳定的迭代节奏,数十位贡献者参与了开发,累计提交 2000+ 个 Pull Request,并支持了 Rspack 构建、嵌套路由、流式渲染等新特性。
|
18
|
+
|
19
|
+
在这篇文章里,我们会和大家一起聊一聊 Modern.js 在过去一年多时间里的变化。
|
20
|
+
|
21
|
+
[了解更多 →](/blog/updates/v2-release-note)
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
## React Streaming SSR 原理解析
|
26
|
+
|
27
|
+
> 发表于 2022.12.16
|
28
|
+
|
29
|
+
React 18 提供了一种新的 SSR 渲染模式: Streaming SSR。通过 Streaming SSR,我们可以实现以下两个功能:
|
30
|
+
|
31
|
+
- Streaming HTML:服务端可以分段传输 HTML 到浏览器,而不是像 React 18 以前一样,需要等待服务端渲染完成整个页面后才返回给浏览器。这样,浏览器可以更快的启动 HTML 的渲染,提高 FP、FCP 等性能指标。
|
32
|
+
- Selective Hydration:在浏览器端 hydration 阶段,可以只对已经完成渲染的区域做 hydration,而不需要等待整个页面渲染完成、所有组件的 JS bundle 加载完成,才能开始 hydration。这样可以更早的对已经完成渲染的区域做事件绑定,从而让页面获得更好的可交互性。
|
33
|
+
|
34
|
+
[了解更多 →](https://mp.weixin.qq.com/s/w4FS5sBcHqRl-Saqi19Y6g)
|
35
|
+
|
36
|
+
---
|
37
|
+
|
38
|
+
## React Server Component 介绍
|
39
|
+
|
40
|
+
> 发表于 2022.12.01
|
41
|
+
|
42
|
+
React 官方对 Server Component 是这样介绍的: **zero-bundle-size React Server Components**。
|
43
|
+
|
44
|
+
这是一种实验性探索,但相信该探索是个未来 React 发展的方向,与 React Server Component 相关的周边生态正在积极的建设当中。
|
45
|
+
|
46
|
+
[了解更多 →](https://mp.weixin.qq.com/s/B-XLvW00vl5RE1Ur3EW4ow)
|
47
|
+
|
48
|
+
---
|
49
|
+
|
50
|
+
## 2022 年 9 ~ 10 月更新内容
|
51
|
+
|
52
|
+
> 发表于 2022.11.01
|
53
|
+
|
54
|
+
Modern.js 9 ~ 10 月的最新版本为 v1.21.0,本双月的主要更新有:
|
55
|
+
|
56
|
+
- **支持 pnpm v7**:完成框架对 pnpm v7 的支持。
|
57
|
+
- **服务端增加 Typescript 作为 ts 文件编译器**。
|
58
|
+
|
59
|
+
[了解更多 →](/blog/updates/2022-0910-updates)
|
60
|
+
|
61
|
+
---
|
62
|
+
|
63
|
+
## 2022 年 7 ~ 8 月更新内容
|
64
|
+
|
65
|
+
> 发表于 2022.09.05
|
66
|
+
|
67
|
+
Modern.js 7 ~ 8 月的最新版本为 v1.17.0,本双月的主要更新有:
|
68
|
+
|
69
|
+
- **支持 React 18**:完成框架和插件对 React 18 的适配。
|
70
|
+
- **包版本统一**:Modern.js 所有组成包的版本号进行统一,提供升级命令。
|
71
|
+
- **模块工程支持 bundle 构建**:模块工程类型的项目,支持对产物做 bundle 构建。
|
72
|
+
- **Reduck v1.1**:发布 Reduck v1.1,使用文档全面更新。
|
73
|
+
|
74
|
+
[了解更多 →](/blog/updates/2022-0708-updates)
|