@modern-js/main-doc 2.60.5 → 2.60.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ BFF combined with runtime framework provides file upload capabilities, supporting integrated calls and pure function manual calls.
2
+
3
+ ### BFF Function
4
+
5
+ First, create the `api/lambda/upload.ts` file:
6
+
7
+ ```ts title="api/lambda/upload.ts"
8
+ export const post = async ({ formData }: {formData: Record<string, any>}) => {
9
+ console.info('formData:', formData);
10
+ // do somethings
11
+ return {
12
+ data: {
13
+ code: 0,
14
+ },
15
+ };
16
+ };
17
+ ```
18
+ :::tip
19
+ The `formData` parameter in the interface processing function can access files uploaded from the client side. It is an `Object` where the keys correspond to the field names used during the upload.
20
+ :::
21
+
22
+
23
+ ### Integrated Calling
24
+
25
+ Next, directly import and call the function in `src/routes/upload/page.tsx`:
26
+ ```tsx title="routes/upload/page.tsx"
27
+ import { upload } from '@api/upload';
28
+ import React from 'react';
29
+
30
+ export default (): JSX.Element => {
31
+ const [file, setFile] = React.useState<FileList | null>();
32
+
33
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
34
+ setFile(e.target.files);
35
+ };
36
+
37
+ const handleUpload = () => {
38
+ if (!file) {
39
+ return;
40
+ }
41
+ upload({
42
+ files: {
43
+ images: file,
44
+ },
45
+ });
46
+ };
47
+
48
+ return (
49
+ <div>
50
+ <input multiple type="file" onChange={handleChange} />
51
+ <button onClick={handleUpload}>upload</button>
52
+ </div>
53
+ );
54
+ };
55
+ ```
56
+ :::tip
57
+ Note: The input type must be `{ formData: FormData }` for the upload to succeed.
58
+ :::
59
+
60
+
61
+ ### Manual Calling
62
+ You can manually upload files using the `fetch API`, when calling `fetch`, set the `body` as `FormData` type and submit a post request.
63
+
64
+ ```tsx title="routes/upload/page.tsx"
65
+ import React from 'react';
66
+
67
+ export default (): JSX.Element => {
68
+ const [file, setFile] = React.useState<FileList | null>();
69
+
70
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
71
+ setFile(e.target.files);
72
+ };
73
+
74
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
75
+ e.preventDefault();
76
+ const formData = new FormData();
77
+ if (file) {
78
+ for (let i = 0; i < file.length; i++) {
79
+ formData.append('images', file[i]);
80
+ }
81
+ await fetch('/api/upload', {
82
+ method: 'POST',
83
+ body: formData,
84
+ });
85
+ }
86
+ };
87
+
88
+ return (
89
+ <form onSubmit={handleSubmit}>
90
+ <input multiple type="file" onChange={handleChange} />
91
+ <button type="submit">upload</button>
92
+ </form>
93
+ );
94
+ };
95
+ ```
@@ -76,3 +76,6 @@ export default {
76
76
  };
77
77
  ```
78
78
 
79
+ #### Clean up cert cache
80
+
81
+ The certificate created by devcert is saved in `~/Library/Application\ Support/devcert`. You may do some cleanup if needed.
@@ -18,6 +18,19 @@ const defaultOptions = {
18
18
  filename, // 基于 `output.distPath` 和 `entryName` 生成
19
19
  templateParameters, // 对应 `html.templateParameters` 配置
20
20
  chunks: [entryName],
21
+ minify: { // // generated based on `output.disableMinimize` and `output.minify`
22
+ removeComments: false,
23
+ useShortDoctype: true,
24
+ keepClosingSlash: true,
25
+ collapseWhitespace: true,
26
+ removeRedundantAttributes: true,
27
+ removeScriptTypeAttributes: true,
28
+ removeStyleLinkTypeAttributes: true,
29
+ removeEmptyAttributes: true,
30
+ minifyJS, // generated based on `output.charset`, `output.legalComments` and `performance.removeConsole`
31
+ minifyCSS: true,
32
+ minifyURLs: true,
33
+ },
21
34
  };
22
35
  ```
23
36
 
@@ -52,5 +52,5 @@ export default {
52
52
  ```
53
53
 
54
54
  :::tip Disable code minification
55
- If you need to disable code minification, you can use the [output.disableMinimize](https://modernjs.dev/builder/en/api/config-output.html#outputdisableminimize) configuration.
55
+ If you need to disable code minification, you can use the [output.minify](/configure/app/output/minify) configuration.
56
56
  :::
@@ -8,10 +8,13 @@ title: tsLoader
8
8
  - **Default:** `undefined`
9
9
  - **Bundler:** `only support webpack`
10
10
 
11
- :::warning Alternatives for ts-loader
12
- Using [babel-loader](https://modernjs.dev/builder/en/guide/basic/typescript.html#why-babel-is-the-default-option) or [Rspack](https://modernjs.dev/en/guide/advanced/rspack-start.html) instead of ts-loader can significantly improve compilation speed and provide better extendability.
11
+ :::warning Deprecated
12
+
13
+ ts-loader is not recommended for use in the project, because:
14
+
15
+ - ts-loader cannot be used with certain features such as [source.transformImport](/configure/app/source/transform-import) and [tools.styledComponents](/configure/app/tools/styled-components) provided by Babel & SWC.
16
+ - Rspack does not support ts-loader.
13
17
 
14
- ts-loader cannot be used with certain features such as [source.transformImport](https://modernjs.dev/en/configure/app/source/transform-import.html) and [tools.styledComponents](https://modernjs.dev/en/configure/app/tools/styled-components.html) provided by Babel & SWC.
15
18
  :::
16
19
 
17
20
  `ts-loader` is not enabled by default in the project. When `tools.tsLoader` is not undefined, builder will use ts-loader instead of babel-loader to compile TypeScript code.
@@ -227,8 +227,8 @@ For example, the `RULE.STYLUS` rule exists only when the Stylus plugin is regist
227
227
  | `PLUGIN.REACT_FAST_REFRESH` | correspond to `ReactFastRefreshPlugin` |
228
228
  | `PLUGIN.NODE_POLYFILL_PROVIDE` | correspond to `ProvidePlugin` for node polyfills |
229
229
  | `PLUGIN.SUBRESOURCE_INTEGRITY` | correspond to `webpack-subresource-integrity` |
230
- | `PLUGIN.ASSETS_RETRY` | correspond to webpack static asset retry plugin |
231
- | `PLUGIN.AUTO_SET_ROOT_SIZE` | correspond to automatically set root font size plugin |
230
+ | `PLUGIN.ASSETS_RETRY` | correspond to webpack static asset retry plugin |
231
+ | `PLUGIN.AUTO_SET_ROOT_SIZE` | correspond to automatically set root font size plugin |
232
232
 
233
233
  #### CHAIN_ID.MINIMIZER
234
234
 
@@ -243,4 +243,4 @@ For example, the `RULE.STYLUS` rule exists only when the Stylus plugin is regist
243
243
 
244
244
  ### Examples
245
245
 
246
- For usage examples, please refer to: [WebpackChain usage examples](https://modernjs.dev/builder/en/guide/advanced/custom-webpack-config.html#webpack-chain-basics).
246
+ For usage examples, please refer to: [Rsbuild - bundlerChain examples](https://rsbuild.dev/guide/basic/configure-rspack#examples).
@@ -1 +1 @@
1
- ["function", "frameworks", "extend-server", "sdk"]
1
+ ["function", "frameworks", "extend-server", "sdk", "upload"]
@@ -0,0 +1,5 @@
1
+ # File Upload
2
+
3
+ import BffUpload from "@site-docs-en/components/bff-upload";
4
+
5
+ <BffUpload />
@@ -0,0 +1,97 @@
1
+ BFF 搭配运行时框架提供了文件上传能力,支持一体化调用及纯函数手动调用。
2
+
3
+ ### BFF 函数
4
+
5
+ 首先创建 `api/lambda/upload.ts` 文件:
6
+
7
+ ```ts title="api/lambda/upload.ts"
8
+ export const post = async ({ formData }: {formData: Record<string, any>}) => {
9
+ console.info('formData:', formData);
10
+ // do somethings
11
+ return {
12
+ data: {
13
+ code: 0,
14
+ },
15
+ };
16
+ };
17
+ ```
18
+ :::tip
19
+ 通过接口处理函数入参中的 `formData` 可以获取客户端上传的文件。值为 `Object`,key 为上传时的字段名。
20
+ :::
21
+
22
+ ### 一体化调用
23
+
24
+ 接着在 `src/routes/upload/page.tsx` 中直接引入函数并调用:
25
+ ```tsx title="routes/upload/page.tsx"
26
+ import { post } from '@api/upload';
27
+ import React from 'react';
28
+
29
+ export default (): JSX.Element => {
30
+ const [file, setFile] = React.useState<FileList | null>();
31
+
32
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
33
+ setFile(e.target.files);
34
+ };
35
+
36
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
37
+ e.preventDefault();
38
+ const formData = new FormData();
39
+ if (file) {
40
+ for (let i = 0; i < file.length; i++) {
41
+ formData.append('images', file[i]);
42
+ }
43
+ post({
44
+ formData,
45
+ });
46
+ }
47
+ };
48
+
49
+ return (
50
+ <div>
51
+ <input multiple type="file" onChange={handleChange} />
52
+ <button onClick={handleUpload}>upload</button>
53
+ </div>
54
+ );
55
+ };
56
+ ```
57
+ :::tip
58
+ 注意:入参类型必须为:`{ formData: FormData }` 才会正确上传。
59
+
60
+ :::
61
+
62
+ ### 手动上传
63
+ 可以基于 `fetch API` 手动上传文件,需要在调用 `fetch` 时,将 `body` 设置为 `FormData` 类型并提交 `post` 请求。
64
+
65
+ ```tsx title="routes/upload/page.tsx"
66
+ import React from 'react';
67
+
68
+ export default (): JSX.Element => {
69
+ const [file, setFile] = React.useState<FileList | null>();
70
+
71
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
72
+ setFile(e.target.files);
73
+ };
74
+
75
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
76
+ e.preventDefault();
77
+ const formData = new FormData();
78
+ if (file) {
79
+ for (let i = 0; i < file.length; i++) {
80
+ formData.append('images', file[i]);
81
+ }
82
+ await fetch('/api/upload', {
83
+ method: 'POST',
84
+ body: formData,
85
+ });
86
+ }
87
+ };
88
+
89
+ return (
90
+ <form onSubmit={handleSubmit}>
91
+ <input multiple type="file" onChange={handleChange} />
92
+ <button type="submit">upload</button>
93
+ </form>
94
+ );
95
+ };
96
+
97
+ ```
@@ -77,3 +77,6 @@ export default {
77
77
  };
78
78
  ```
79
79
 
80
+ #### 清理证书缓存
81
+
82
+ devcert 默认会将生成的证书缓存在 `~/Library/Application\ Support/devcert` ,你可以按需清理。
@@ -18,6 +18,19 @@ const defaultOptions = {
18
18
  filename, // 基于 `output.distPath` 和 `entryName` 生成
19
19
  templateParameters, // 对应 `html.templateParameters` 配置
20
20
  chunks: [entryName],
21
+ minify: { // 基于 `output.minify` 和 `output.disableMinimize` 生成
22
+ removeComments: false,
23
+ useShortDoctype: true,
24
+ keepClosingSlash: true,
25
+ collapseWhitespace: true,
26
+ removeRedundantAttributes: true,
27
+ removeScriptTypeAttributes: true,
28
+ removeStyleLinkTypeAttributes: true,
29
+ removeEmptyAttributes: true,
30
+ minifyJS, // 基于 `output.charset`、`output.legalComments` 和 `performance.removeConsole` 生成
31
+ minifyCSS: true,
32
+ minifyURLs: true,
33
+ },
21
34
  };
22
35
  ```
23
36
 
@@ -52,5 +52,5 @@ export default {
52
52
  ```
53
53
 
54
54
  :::tip 禁用代码压缩
55
- 如果你需要禁用代码压缩,可以使用 [output.disableMinimize](https://modernjs.dev/builder/api/config-output.html#outputdisableminimize) 配置项。
55
+ 如果你需要禁用代码压缩,可以使用 [output.minify](/configure/app/output/minify) 配置项。
56
56
  :::
@@ -8,10 +8,13 @@ title: tsLoader
8
8
  - **默认值:** `undefined`
9
9
  - **打包工具:** `仅支持 webpack`
10
10
 
11
- :::warning 不再推荐使用 ts-loader
12
- 使用 [babel-loader](https://modernjs.dev/builder/guide/basic/typescript.html#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%BB%98%E8%AE%A4%E4%BD%BF%E7%94%A8-babel) 或 [Rspack](https://modernjs.dev/guide/advanced/rspack-start.html) 转译 TypeScript 代码的性能明显优于 ts-loader 且能够使用更多拓展能力。
11
+ :::warning 废弃提示
12
+
13
+ 不推荐在项目中使用 ts-loader,原因如下:
14
+
15
+ - 启用 ts-loader 时将无法使用 [source.transformImport](/configure/app/source/transform-import) 和 [tools.styledComponents](/configure/app/tools/styled-components) 等由 Babel 和 SWC 提供支持的能力。
16
+ - Rspack 不支持使用 ts-loader。
13
17
 
14
- 启用 ts-loader 时将无法使用 [source.transformImport](https://modernjs.dev/configure/app/source/transform-import.html) 和 [tools.styledComponents](https://modernjs.dev/configure/app/tools/styled-components.html) 等由 Babel 和 SWC 提供支持的能力。
15
18
  :::
16
19
 
17
20
  项目中默认不开启 ts-loader,当 `tools.tsLoader` 不为 undefined 则表示开启 ts-loader,同时禁用 babel-loader 对 TypeScript 的编译。
@@ -231,8 +231,8 @@ Modern.js 中预先定义了一些常用的 Chain ID,你可以通过这些 ID
231
231
  | `PLUGIN.REACT_FAST_REFRESH` | 对应 `ReactFastRefreshPlugin` |
232
232
  | `PLUGIN.NODE_POLYFILL_PROVIDE` | 对应处理 node polyfill 的 `ProvidePlugin` |
233
233
  | `PLUGIN.SUBRESOURCE_INTEGRITY` | 对应 `webpack-subresource-integrity` |
234
- | `PLUGIN.ASSETS_RETRY` | 对应 webpack 静态资源重试插件 `WebpackAssetsRetryPlugin` |
235
- | `PLUGIN.AUTO_SET_ROOT_SIZE` | 对应自动设置根字体大小插件 `AutoSetRootSizePlugin` |
234
+ | `PLUGIN.ASSETS_RETRY` | 对应 webpack 静态资源重试插件 `WebpackAssetsRetryPlugin` |
235
+ | `PLUGIN.AUTO_SET_ROOT_SIZE` | 对应自动设置根字体大小插件 `AutoSetRootSizePlugin` |
236
236
 
237
237
  #### CHAIN_ID.MINIMIZER
238
238
 
@@ -247,4 +247,4 @@ Modern.js 中预先定义了一些常用的 Chain ID,你可以通过这些 ID
247
247
 
248
248
  ### 使用示例
249
249
 
250
- 使用示例可参考:[WebpackChain 使用示例](https://modernjs.dev/builder/guide/advanced/custom-webpack-config.html#%E4%BD%BF%E7%94%A8-webpack-chain)。
250
+ 使用示例可参考:[Rsbuild - bundlerChain 使用示例](https://rsbuild.dev/zh/guide/basic/configure-rspack#%E7%A4%BA%E4%BE%8B)。
@@ -1 +1 @@
1
- ["function", "frameworks", "extend-server", "sdk"]
1
+ ["function", "frameworks", "extend-server", "sdk", "upload"]
@@ -0,0 +1,5 @@
1
+ # 文件上传
2
+
3
+ import BffUpload from "@site-docs/components/bff-upload";
4
+
5
+ <BffUpload />
package/package.json CHANGED
@@ -15,17 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.60.5",
18
+ "version": "2.60.6",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
24
  "dependencies": {
25
- "@modern-js/sandpack-react": "2.60.5"
25
+ "@modern-js/sandpack-react": "2.60.6"
26
26
  },
27
27
  "devDependencies": {
28
- "@rspress/shared": "1.31.1",
28
+ "@rspress/shared": "1.35.2",
29
29
  "@types/fs-extra": "9.0.13",
30
30
  "@types/node": "^16",
31
31
  "classnames": "^2",
@@ -33,7 +33,7 @@
33
33
  "fs-extra": "^10",
34
34
  "react": "^18.3.1",
35
35
  "react-dom": "^18.3.1",
36
- "rspress": "1.31.1",
36
+ "rspress": "1.35.2",
37
37
  "ts-node": "^10.9.1",
38
38
  "typescript": "^5"
39
39
  },