@modern-js/main-doc 2.0.0-beta.6 → 2.0.0-canary.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/index_.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/pages.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/routes.md +86 -0
- package/en/docusaurus-plugin-content-docs/current/components/global-proxy-config.md +74 -0
- package/en/docusaurus-plugin-content-docs/current/components/global-proxy.md +28 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/proxy.md +2 -72
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/entries.md +0 -2
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/tailwindcss.md +16 -22
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/_category_.json +8 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/bff-proxy.md +27 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/frameworks.md +148 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/function.md +218 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/index.md +20 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/type.md +43 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/code-split.md +77 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/compatibility.md +76 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/eslint.md +145 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/index.md +12 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/low-level.md +46 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssg.md +128 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssr.md +306 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/testing.md +46 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/web-server.md +57 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/alias.md +67 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +30 -35
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/data-fetch.md +400 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/env-vars.md +166 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/html.md +235 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/mock.md +78 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/proxy.md +60 -0
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +2 -4
- package/package.json +3 -3
- package/zh/apis/app/hooks/src/index_.md +1 -1
- package/zh/apis/app/hooks/src/pages.md +1 -1
- package/zh/apis/app/hooks/src/routes.md +89 -0
- package/zh/components/debug-app.md +1 -2
- package/zh/components/global-proxy-config.md +70 -0
- package/zh/configure/app/dev/proxy.md +2 -70
- package/zh/configure/app/source/entries.md +1 -3
- package/zh/configure/app/tools/tailwindcss.md +16 -23
- package/zh/guides/advanced-features/bff/function.md +37 -19
- package/zh/guides/advanced-features/code-split.md +28 -20
- package/zh/guides/advanced-features/compatibility.md +24 -14
- package/zh/guides/advanced-features/ssg.md +1 -47
- package/zh/guides/advanced-features/ssr.md +1 -1
- package/zh/guides/advanced-features/testing.md +2 -2
- package/zh/guides/basic-features/alias.md +5 -5
- package/zh/guides/basic-features/css/tailwindcss.md +31 -35
- package/zh/guides/basic-features/data-fetch.md +7 -6
- package/zh/guides/basic-features/env-vars.md +2 -2
- package/zh/guides/basic-features/html.md +62 -137
- package/zh/guides/basic-features/mock.md +8 -9
- package/zh/guides/basic-features/proxy.md +2 -2
- package/zh/guides/basic-features/routes.md +37 -3
- package/zh/guides/get-started/quick-start.md +1 -2
- package/zh/guides/topic-detail/framework-plugin/implement.md +54 -6
- package/zh/guides/topic-detail/micro-frontend/c02-development.md +1 -1
@@ -61,7 +61,6 @@ export default defineConfig({
|
|
61
61
|
|
62
62
|
* `entry`:`string`,入口文件路径。
|
63
63
|
* `disableMount`:`boolean = false`,关闭 Modern.js 生成入口代码的行为。
|
64
|
-
* `enableFileSystemRoutes`:`boolean = false`,是否 [使用约定式路由](/docs/apis/app/hooks/src/pages)。
|
65
64
|
|
66
65
|
```ts title="modern.config.ts"
|
67
66
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -76,8 +75,7 @@ export default defineConfig({
|
|
76
75
|
// 启用约定式路由
|
77
76
|
entry_spa: {
|
78
77
|
// 约定式路由的入口路径必须设置为目录
|
79
|
-
entry: './src/about'
|
80
|
-
enableFileSystemRoutes: true,
|
78
|
+
entry: './src/about'
|
81
79
|
},
|
82
80
|
},
|
83
81
|
},
|
@@ -4,39 +4,32 @@ title: tools.tailwindcss
|
|
4
4
|
sidebar_label: tailwindcss
|
5
5
|
---
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
* 默认值:见下方配置详情。
|
7
|
+
- 类型: `Object | Function`
|
8
|
+
- 默认值:见下方配置详情。
|
10
9
|
|
11
10
|
<details>
|
12
11
|
<summary>TailwindCSS 配置详情</summary>
|
13
12
|
|
14
13
|
```js
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
removeDeprecatedGapUtilities: false,
|
29
|
-
purgeLayersByDefault: true,
|
30
|
-
defaultLineHeights: false,
|
31
|
-
standardFontWeights: false,
|
32
|
-
},
|
33
|
-
theme: source.designSystem // 使用source.designSystem配置作为Tailwind CSS Theme配置
|
34
|
-
}
|
14
|
+
const tailwind = {
|
15
|
+
content: [
|
16
|
+
'./config/html/**/*.html',
|
17
|
+
'./config/html/**/*.ejs',
|
18
|
+
'./config/html/**/*.hbs',
|
19
|
+
'./src/**/*.js',
|
20
|
+
'./src/**/*.jsx',
|
21
|
+
'./src/**/*.ts',
|
22
|
+
'./src/**/*.tsx',
|
23
|
+
'./storybook/**/*',
|
24
|
+
],
|
25
|
+
theme: source.designSystem, // 使用source.designSystem配置作为Tailwind CSS Theme配置
|
26
|
+
};
|
35
27
|
```
|
36
28
|
|
37
29
|
:::tip 提示
|
38
30
|
更多关于:<a href="https://tailwindcss.com/docs/configuration" target="_blank">TailwindCSS 配置</a>。
|
39
31
|
:::
|
32
|
+
|
40
33
|
</details>
|
41
34
|
|
42
35
|
对应 [TailwindCSS](https://tailwindcss.com/docs/configuration) 的配置,值为 `Object` 类型时,与默认配置通过 `Object.assign` 合并。
|
@@ -13,6 +13,10 @@ Modern.js 允许在 React 组件中直接调用 `api/` 目录下满足一定条
|
|
13
13
|
|
14
14
|
允许通过一体化调用的函数,称为 **BFF 函数**。这里写一个最简单的 BFF 函数,创建 `api/hello.ts` 文件:
|
15
15
|
|
16
|
+
:::caution
|
17
|
+
如果是框架模式(有 `api/lambda` 目录),需要创建 `api/lambda/hello.ts`
|
18
|
+
:::
|
19
|
+
|
16
20
|
```ts title="api/hello.ts"
|
17
21
|
export const get = async () => 'Hello Modern.js';
|
18
22
|
```
|
@@ -41,7 +45,7 @@ Modern.js 生成器已经在 `tsconfig.json` 中配置 `@api` 别名,因此可
|
|
41
45
|
|
42
46
|
执行 `pnpm run dev` 打开 `http://localhost:8080/` 可以看到页面已经展示了 BFF 函数返回的内容,在 Network 中可以看到页面向 `http://localhost:8080/api/hello` 发送了请求:
|
43
47
|
|
44
|
-
![Network](https://
|
48
|
+
![Network](https://p6-piu.byteimg.com/tos-cn-i-8jisjyls3a/fd41750f8d414179a9b4ecb519919b36~tplv-8jisjyls3a-3:0:0:q75.png)
|
45
49
|
|
46
50
|
## 函数路由
|
47
51
|
|
@@ -53,32 +57,30 @@ Modern.js 中,BFF 函数对应的路由系统是基于文件系统实现的,
|
|
53
57
|
函数写法和框架写法会在下一节详细介绍。
|
54
58
|
:::
|
55
59
|
|
56
|
-
|
60
|
+
所有 BFF 函数生成的路由都带有统一的前缀,默认值为 `/api`。可以通过 [bff.prefix](/docs/configure/app/bff/prefix) 设置公共路由的前缀。
|
57
61
|
|
58
|
-
|
59
|
-
可以通过 [bff.prefix](/docs/configure/app/bff/prefix) 设置公共路由的前缀。
|
60
|
-
:::
|
62
|
+
下面介绍几种路由的约定。
|
61
63
|
|
62
64
|
### 默认路由
|
63
65
|
|
64
66
|
以 `index.[jt]s` 命名的文件会被映射到上一层目录。
|
65
67
|
|
66
|
-
* `api/index.ts` ->
|
67
|
-
* `api/user/index.ts` ->
|
68
|
+
* `api/index.ts` -> `{prefix}/`
|
69
|
+
* `api/user/index.ts` -> `{prefix}/user`
|
68
70
|
|
69
|
-
###
|
71
|
+
### 多层路由
|
70
72
|
|
71
73
|
支持解析嵌套的文件,如果创建嵌套文件夹结构,文件仍会以相同方式自动解析路由。
|
72
74
|
|
73
|
-
* `api/hello.ts` ->
|
74
|
-
* `api/user/list.ts` ->
|
75
|
+
* `api/hello.ts` -> `{prefix}/hello`
|
76
|
+
* `api/user/list.ts` -> `{prefix}/user/list`
|
75
77
|
|
76
78
|
### 动态路由
|
77
79
|
|
78
|
-
同样的,创建命名带有 `[xxx]`
|
80
|
+
同样的,创建命名带有 `[xxx]` 的文件夹或者文件,支持动态的命名路由参数。动态路由的函数参数规则可以看 [dynamac-path](/docs/guides/advanced-features/bff/function#dynamic-path)
|
79
81
|
|
80
|
-
* `api/user/[username]/info.ts` ->
|
81
|
-
* `api/user/username/[action].ts` ->
|
82
|
+
* `api/user/[username]/info.ts` -> `{prefix}/user/:username/info`
|
83
|
+
* `api/user/username/[action].ts` -> `{prefix}/user/username/:action`
|
82
84
|
|
83
85
|
### 白名单
|
84
86
|
|
@@ -102,7 +104,7 @@ Modern.js 的 BFF 函数需要遵循 RESTful API 标准来定义, 遵循 HTTP Me
|
|
102
104
|
|
103
105
|
### 函数具名导出
|
104
106
|
|
105
|
-
Modern.js BFF 函数的导出名决定了函数对应接口的 Method
|
107
|
+
Modern.js BFF 函数的导出名决定了函数对应接口的 Method,如 `get`,`post` 等。
|
106
108
|
|
107
109
|
例如,按照以下例子,可导出一个 GET 接口。
|
108
110
|
|
@@ -126,9 +128,9 @@ export const post = async () => {
|
|
126
128
|
};
|
127
129
|
```
|
128
130
|
|
129
|
-
*
|
131
|
+
* 对应 HTTP Method,Modern.js 也支持了 9 种定义,即:`GET`、`POST`、`PUT`、`DELETE`、`CONNECT`、`TRACE`、`PATCH`、`OPTION`、`HEAD`,即可以用这些 Method 作为函数导出的名字。
|
130
132
|
|
131
|
-
*
|
133
|
+
* 名字是大小不敏感的,如果是 `GET`,写成 `get`、`Get`、`GEt`、`GET`,都可以准确识别。而默认导出,即 `export default xxx` 则会被映射为 `Get`。
|
132
134
|
|
133
135
|
* 可以在一个文件中定义多个不同 Method 的函数,但如果定义多个相同 Method 的函数,则只有第一个会生效。
|
134
136
|
|
@@ -140,9 +142,7 @@ export const post = async () => {
|
|
140
142
|
|
141
143
|
如上所述,为了满足 RESTful API 的设计标准,因此 Modern.js 中 BFF 函数需要遵循一定的入参规则。
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
-
普通函数参数分为两块,分别是请求路径中的动态部分和请求选项 `RequestOption`。
|
145
|
+
函数参数分为两块,分别是请求路径中的动态部分和请求选项 `RequestOption`。
|
146
146
|
|
147
147
|
#### Dynamic Path
|
148
148
|
|
@@ -190,6 +190,24 @@ export async function post(
|
|
190
190
|
}
|
191
191
|
```
|
192
192
|
|
193
|
+
这里你也可以使用自定义类型:
|
194
|
+
```ts title="api/lambda/hello.ts"
|
195
|
+
import type { RequestOption } from '@modern-js/runtime/server'
|
196
|
+
|
197
|
+
type IQuery = {
|
198
|
+
// some types
|
199
|
+
}
|
200
|
+
type IData = {
|
201
|
+
// some types
|
202
|
+
}
|
203
|
+
|
204
|
+
export async function post(
|
205
|
+
{ query, data }: { query:IQuery, data:IData }
|
206
|
+
) {
|
207
|
+
// do somethings
|
208
|
+
}
|
209
|
+
```
|
210
|
+
|
193
211
|
当函数文件使用动态路由规则时,动态路由会在 `RequestOption` 对象参数前。
|
194
212
|
|
195
213
|
```ts title="api/[sku]/[id]/item.ts"
|
@@ -5,6 +5,10 @@ sidebar_position: 6
|
|
5
5
|
|
6
6
|
代码分割是优化前端资源加载的一种常用手段,本文将介绍 Modern.js 支持的三种代码分割方式:
|
7
7
|
|
8
|
+
:::info
|
9
|
+
使用 Modern.js [约定式路由](/docs/guides/basic-features/routes#约定式路由)时,默认会根据路由组件做代码分割,包裹 `Suspense` 组件,无需自行进行代码分割。
|
10
|
+
:::
|
11
|
+
|
8
12
|
- `import`
|
9
13
|
- `React.lazy`
|
10
14
|
- `loadable`
|
@@ -21,30 +25,14 @@ import("./math").then(math => {
|
|
21
25
|
|
22
26
|
`./math` 路径对应的 JS 模块会被打包到单独的 JS 文件中。
|
23
27
|
|
24
|
-
##
|
25
|
-
|
26
|
-
使用 `loadable` API,示例如下:
|
27
|
-
|
28
|
-
```ts
|
29
|
-
import loadable from '@modern-js/runtime/loadable'
|
30
|
-
|
31
|
-
const OtherComponent = loadable(() => import('./OtherComponent'));
|
32
|
-
|
33
|
-
function MyComponent() {
|
34
|
-
return <OtherComponent />
|
35
|
-
}
|
36
|
-
```
|
28
|
+
## React.lazy
|
37
29
|
|
38
|
-
|
30
|
+
React 官方提供的组件代码分割的方式。
|
39
31
|
|
40
|
-
:::
|
41
|
-
|
32
|
+
:::caution
|
33
|
+
React 17 及以下版本不支持 SSR,建议 React17 的 SSR 应用使用 loadable。
|
42
34
|
:::
|
43
35
|
|
44
|
-
## React.lazy
|
45
|
-
|
46
|
-
React 官方提供的组件代码分割的方式,**缺点是不支持 SSR**。
|
47
|
-
|
48
36
|
```ts
|
49
37
|
import React, { Suspense } from 'react';
|
50
38
|
|
@@ -66,3 +54,23 @@ function MyComponent() {
|
|
66
54
|
```
|
67
55
|
|
68
56
|
`React.lazy` 更多用法请见 [React lazy](https://zh-hans.reactjs.org/docs/code-splitting.html#reactlazy)。
|
57
|
+
|
58
|
+
## loadable
|
59
|
+
|
60
|
+
使用 `loadable` API,示例如下:
|
61
|
+
|
62
|
+
```ts
|
63
|
+
import loadable from '@modern-js/runtime/loadable'
|
64
|
+
|
65
|
+
const OtherComponent = loadable(() => import('./OtherComponent'));
|
66
|
+
|
67
|
+
function MyComponent() {
|
68
|
+
return <OtherComponent />
|
69
|
+
}
|
70
|
+
```
|
71
|
+
|
72
|
+
`loadable` 更多用法请见 [loadable API](/docs/apis/app/runtime/utility/loadable)。
|
73
|
+
|
74
|
+
:::info 注
|
75
|
+
`loadable` 开箱即用的支持 SSR,但不支持和 Suspense 一起使用,如果是 CSR 项目可以使用 [loadable.lazy](https://loadable-components.com/docs/suspense/)
|
76
|
+
:::
|
@@ -3,13 +3,32 @@ title: 客户端兼容性
|
|
3
3
|
sidebar_position: 5
|
4
4
|
---
|
5
5
|
|
6
|
-
##
|
6
|
+
## Browserslist 配置
|
7
|
+
|
8
|
+
Modern.js 支持在项目根目录 `package.json` 文件中的 `browserslist` 字段(或单独的 `.browserslistrc` 文件)指定项目覆盖的目标浏览器范围。该值会被 [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env) 和 [`autoprefixer`](https://github.com/postcss/autoprefixer) 用来确定需要转换的 JavaScript 语法特性和需要添加的 CSS 浏览器前缀。
|
9
|
+
|
10
|
+
Modern.js 中默认值如下:
|
11
|
+
|
12
|
+
```js
|
13
|
+
['> 0.01%', 'not dead', 'not op_mini all']
|
14
|
+
```
|
15
|
+
|
16
|
+
可以在[这里](https://github.com/browserslist/browserslist)了解如何自定义浏览器范围。
|
17
|
+
|
18
|
+
查看 Modern.js Builder 文档了解更多 [Browserlist](https://modernjs.dev/builder/zh/guide/advanced/browserslist.html) 相关内容。
|
19
|
+
|
20
|
+
:::note
|
21
|
+
Modern.js 支持配置 [output.overrideBrowserlist](/docs/configure/app/output/override-browserslist) 覆盖默认 browserlist 值。
|
22
|
+
:::
|
23
|
+
|
24
|
+
|
25
|
+
## Polyfill
|
7
26
|
|
8
27
|
### 编译时 Polyfill
|
9
28
|
|
10
29
|
Modern.js 在编译时默认通过 [core-js](https://github.com/zloirock/core-js) 引入对应的 Polyfill 代码。
|
11
30
|
|
12
|
-
默认情况下会根据项目
|
31
|
+
默认情况下会根据项目 Browserslist 的设置情况引入所需的 Polyfill 代码, 这样基本不用再担心项目源码和第三方依赖的 Polyfill 问题了,但是因为包含了一些没有用到的 Polyfill 代码,所以最终的包大小可能会有所增加。
|
13
32
|
|
14
33
|
:::info 注
|
15
34
|
对于明确第三方依赖不需要 Polyfill 的场景,可以设置 [`output.polyfill`](/docs/configure/app/output/polyfill) 为 `usage`, 这样 Babel 编译时只会根据代码中使用到的语法引入 Polyfill 代码。
|
@@ -48,17 +67,8 @@ export default defineConfig({
|
|
48
67
|
|
49
68
|
在 Chrome 51 下访问页面可以看到 `http://localhost:8080/__polyfill__` 返回内容如下:
|
50
69
|
|
51
|
-
|
52
70
|
![ua-polyfill](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/docs/ua-polyfill.png)
|
53
71
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
Modern.js 中默认值如下:
|
59
|
-
|
60
|
-
```js
|
61
|
-
['> 0.01%', 'not dead', 'not op_mini all']
|
62
|
-
```
|
63
|
-
|
64
|
-
可以在[这里](https://github.com/browserslist/browserslist)了解如何自定义浏览器范围。
|
72
|
+
:::caution 注意
|
73
|
+
该功能只有在使用 Modern.js 内置的 Web Server 时才会生效。
|
74
|
+
:::
|
@@ -5,10 +5,6 @@ sidebar_position: 4
|
|
5
5
|
|
6
6
|
SSG(Static Site Generation)是一种基于数据与模板,在构建时渲染完整静态网页的技术解决方案。
|
7
7
|
|
8
|
-
:::info 注
|
9
|
-
SSG 是构建阶段的解决方案,因此仅对生产环境有效。通过 `dev` 命令运行时,表现效果与 SSR 相同。
|
10
|
-
:::
|
11
|
-
|
12
8
|
我们首先需要执行 `pnpm run new` 启用 SSG 功能:
|
13
9
|
|
14
10
|
```bash
|
@@ -16,7 +12,7 @@ SSG 是构建阶段的解决方案,因此仅对生产环境有效。通过 `de
|
|
16
12
|
? 启用可选功能 启用「SSG」功能
|
17
13
|
```
|
18
14
|
|
19
|
-
执行命令后,在 `modern.config.ts` 中注册 SSG
|
15
|
+
执行命令后,在 `modern.config.ts` 中注册 SSG 插件:
|
20
16
|
|
21
17
|
```ts title="modern.config.ts"
|
22
18
|
import SSGPlugin from '@modern-js/plugin-ssg';
|
@@ -129,45 +125,3 @@ export default defineConfig({
|
|
129
125
|
:::info
|
130
126
|
以上仅介绍了单入口的情况,更多相关内容可以查看 [API 文档](/docs/configure/app/output/ssg)。
|
131
127
|
:::
|
132
|
-
|
133
|
-
### 获取数据
|
134
|
-
|
135
|
-
在 SSR 中,组件可以通过 `useLoader` 同构的获取数据。在 SSG 中,Modern.js 也提供了相同的能力。
|
136
|
-
|
137
|
-
调用 `useLoader` 时,在第二个参数中设置 `{ static: true }`,可以在 SSG 阶段执行数据的请求。
|
138
|
-
|
139
|
-
:::info 注
|
140
|
-
- Modern.js 目前还不支持 SSG 与 SSR 混合渲染,敬请期待。
|
141
|
-
- 在开发阶段,不管 `useLoader` 是否配置 `{ static: true }`,函数都会在 SSR 时获取数据。
|
142
|
-
:::
|
143
|
-
|
144
|
-
修改上述 `src/App.ts` 的代码为:
|
145
|
-
|
146
|
-
```tsx title="App.ts"
|
147
|
-
import { useRuntimeContext, useLoader } from '@modern-js/runtime';
|
148
|
-
import { Routes, Route, BrowserRouter } from '@modern-js/runtime/router';
|
149
|
-
import { StaticRouter } from '@modern-js/runtime/router/server';
|
150
|
-
|
151
|
-
const Router = typeof window === 'undefined' ? StaticRouter : BrowserRouter;
|
152
|
-
|
153
|
-
export default () => {
|
154
|
-
const { context } = useRuntimeContext();
|
155
|
-
|
156
|
-
const { data } = useLoader(async () => ({
|
157
|
-
message: Math.random(),
|
158
|
-
}), { static: true });
|
159
|
-
|
160
|
-
return (
|
161
|
-
<Router location={context.request.pathname}>
|
162
|
-
<Routes>
|
163
|
-
<Route index element={<div>index</div>} />
|
164
|
-
<Route path="about" element={<div>about, {data?.message}</div>} />
|
165
|
-
</Routes>
|
166
|
-
</Router>
|
167
|
-
);
|
168
|
-
};
|
169
|
-
```
|
170
|
-
|
171
|
-
执行 `pnpm run dev`,重复刷新页面,可以看到 `/foo` 页面的渲染结果不断发生变化,说明数据是在请求时获取的。
|
172
|
-
|
173
|
-
重新执行 `pnpm run build` 后,执行 `pnpm run serve`,重复刷新页面,发现页面渲染结果始终保持同样的内容,数据在请求时不会再次获取,说明页面在编译时已经完成渲染。
|
@@ -125,7 +125,7 @@ CSR 中这类问题不易被发觉,因此从 CSR 切换到 SSR 时,如果不
|
|
125
125
|
|
126
126
|
## 收敛服务端数据
|
127
127
|
|
128
|
-
为了保持 SSR 阶段请求的数据,可以在浏览器端直接使用,
|
128
|
+
为了保持 SSR 阶段请求的数据,可以在浏览器端直接使用,Modern.js 会将渲染过程中收集的数据与状态注入到 HTML 内。但是,CSR 应用常常存在接口数据量大、组件状态未收敛的情况,这时如果直接使用 SSR,渲染得到的 HTML 体积可能会存在过大的问题。此时,SSR 不仅无法为应用带来用户体验上的提升,反而可能起到相反的作用。
|
129
129
|
|
130
130
|
因此,使用 SSR 时,**开发者需要为应用做合理的瘦身**:
|
131
131
|
|
@@ -15,7 +15,7 @@ Modern.js 默认继承了 [Jest](https://jestjs.io/) 的测试能力。
|
|
15
15
|
|
16
16
|
执行上述命令后,`package.json` 中将会自动生成 `"test": "modern test"` 命令。
|
17
17
|
|
18
|
-
在 `modern.config.ts` 中注册 Test
|
18
|
+
在 `modern.config.ts` 中注册 Test 插件:
|
19
19
|
|
20
20
|
```ts title="modern.config.ts"
|
21
21
|
import TestPlugin from '@modern-js/plugin-testing';
|
@@ -28,7 +28,7 @@ export default defineConfig({
|
|
28
28
|
|
29
29
|
## 测试文件
|
30
30
|
|
31
|
-
Modern.js
|
31
|
+
Modern.js 默认识别的测试文件路径为:`<rootDir>/src/**/*.test.[jt]s?(x)` 和 `<rootDir>/tests/**/*.test.[jt]s?(x)`。
|
32
32
|
|
33
33
|
如果你需要自定义 test 目录,可通过 [tools.jest](/docs/configure/app/tools/jest) 进行配置。
|
34
34
|
|
@@ -13,10 +13,10 @@ Modern.js 允许在 JS 和 CSS 中使用别名导入自定义目录下的模块
|
|
13
13
|
```
|
14
14
|
|
15
15
|
:::info 注
|
16
|
-
在开启可选功能时,生成器也会动态的添加内置别名,例如启用 BFF 时默认会添加 `@api`
|
16
|
+
在开启可选功能时,生成器也会动态的添加内置别名,例如启用 BFF 时默认会添加 `@api` 别名。
|
17
17
|
:::
|
18
18
|
|
19
|
-
|
19
|
+
例如从 `src/App.tsx` 文件中导入 `src/common` 目录下的模块:
|
20
20
|
|
21
21
|
```bash
|
22
22
|
.
|
@@ -28,14 +28,14 @@ Modern.js 允许在 JS 和 CSS 中使用别名导入自定义目录下的模块
|
|
28
28
|
├── App.tsx
|
29
29
|
```
|
30
30
|
|
31
|
-
`src/App.tsx`
|
31
|
+
`src/App.tsx` 中写法如下:
|
32
32
|
|
33
33
|
```ts
|
34
34
|
import utils from '@/src/common/utils';
|
35
35
|
import '@/src/common/styles/base.css';
|
36
36
|
```
|
37
37
|
|
38
|
-
Modern.js 也提供了自定义别名的方式,以添加 `@common` 别名为例,对于 TypeScript 项目,只需要在项目根目录 `tsconfig.json` 下配置 `compilerOptions.paths`
|
38
|
+
Modern.js 也提供了自定义别名的方式,以添加 `@common` 别名为例,对于 TypeScript 项目,只需要在项目根目录 `tsconfig.json` 下配置 `compilerOptions.paths` 如下:
|
39
39
|
|
40
40
|
```json
|
41
41
|
{
|
@@ -52,7 +52,7 @@ Modern.js 也提供了自定义别名的方式,以添加 `@common` 别名为
|
|
52
52
|
}
|
53
53
|
```
|
54
54
|
|
55
|
-
JavaScript 项目可以在 `modern.config.js` 中配置 [`source.alias`](/docs/configure/app/source/alias)
|
55
|
+
JavaScript 项目可以在 `modern.config.js` 中配置 [`source.alias`](/docs/configure/app/source/alias):
|
56
56
|
|
57
57
|
```typescript title="modern.config.ts"
|
58
58
|
export default defineConfig({
|
@@ -32,12 +32,40 @@ import 'tailwindcss/components.css';
|
|
32
32
|
import 'tailwindcss/utilities.css';
|
33
33
|
```
|
34
34
|
|
35
|
-
然后即可在各个组件中使用 Tailwind CSS 提供的 Utility Class
|
35
|
+
然后即可在各个组件中使用 Tailwind CSS 提供的 Utility Class 了:
|
36
|
+
|
37
|
+
```tsx
|
38
|
+
const App = () => (
|
39
|
+
<div className="h-12 w-48">
|
40
|
+
<p className="text-xl font-medium text-black">hello world</p>
|
41
|
+
</div>
|
42
|
+
);
|
43
|
+
```
|
36
44
|
|
37
45
|
:::info 补充信息
|
38
|
-
|
46
|
+
根据需求不同,你可以选择性的导入 Tailwind CSS 提供的 CSS 文件。由于使用 `@tailwind` 与直接导入 CSS 文件的作用等价,因此关于 Tailwind CSS 提供的 CSS 文件的用途,可以参考 [`@tailwind` 的使用](https://tailwindcss.com/docs/functions-and-directives#tailwind) 文档中注释里的内容。
|
39
47
|
:::
|
40
48
|
|
49
|
+
## Tailwind CSS 版本
|
50
|
+
|
51
|
+
Modern.js 同时支持 Tailwind CSS v2 和 v3 版本,框架会识别项目 `package.json` 中的 `tailwindcss` 依赖版本,并启用相应的配置。默认情况下,我们会为你安装 Tailwind CSS v3 版本。
|
52
|
+
|
53
|
+
如果你的项目仍在使用 Tailwind CSS v2,我们推荐你升级到 v3 以支持 JIT 等能力。关于 Tailwind CSS v2 与 v3 版本之间的差异,请参考以下文章:
|
54
|
+
|
55
|
+
- [Tailwind CSS v3.0](https://tailwindcss.com/blog/tailwindcss-v3)
|
56
|
+
- [Upgrade Guide](https://tailwindcss.com/docs/upgrade-guide)
|
57
|
+
|
58
|
+
### 浏览器兼容性
|
59
|
+
|
60
|
+
Tailwind CSS v2 和 v3 均不支持 IE 11 浏览器,相关背景请参考:
|
61
|
+
|
62
|
+
- [Tailwind CSS v3 - Browser Support](https://tailwindcss.com/docs/browser-support)。
|
63
|
+
- [Tailwind CSS v2 - Browser Support](https://v2.tailwindcss.com/docs/browser-support)
|
64
|
+
|
65
|
+
如果你在 IE 11 浏览器上使用 Tailwind CSS,可能会出现部分样式不可用的现象,请谨慎使用。
|
66
|
+
|
67
|
+
## Theme 配置
|
68
|
+
|
41
69
|
当需要自定义 Tailwind CSS 的 [theme](https://tailwindcss.com/docs/theme) 配置的时候,可以在配置 [`source.designSystem`](/docs/configure/app/source/design-system) 中修改,例如,颜色主题中增加一个 `primary`:
|
42
70
|
|
43
71
|
```typescript title="modern.config.ts"
|
@@ -70,36 +98,4 @@ export default defineConfig({
|
|
70
98
|
});
|
71
99
|
```
|
72
100
|
|
73
|
-
|
74
|
-
|
75
|
-
在上一章中介绍了什么是 CSS-in-JS 以及社区常用的 CSS-in-JS 库 [styled-components](https://styled-components.com/)。这一部分将要介绍如何通过 [`Twin`](https://github.com/ben-rogerson/twin.macro) 在 CSS-in-JS 中使用 [Tailwind CSS](https://tailwindcss.com/)。使用 [`Twin`](https://github.com/ben-rogerson/twin.macro) 可以更容易在 CSS-in-JS 的代码中使用 Tailwind CSS。[`Twin`](https://github.com/ben-rogerson/twin.macro) 对于自己的描述是:
|
76
|
-
|
77
|
-
> *Twin blends the magic of Tailwind with the flexibility of css-in-js*
|
78
|
-
|
79
|
-
在开启「Tailwind CSS 支持」的功能后,首先需要安装 [`Twin`](https://github.com/ben-rogerson/twin.macro) 依赖:
|
80
|
-
|
81
|
-
``` bash
|
82
|
-
pnpm add twin.macro -D
|
83
|
-
```
|
84
|
-
|
85
|
-
当项目安装 `twin.macro` 依赖后,Modern.js 会检测到该依赖并对内置的 `babel-plugin-macro` 增加 `twin.macro` 相关的配置。因此在安装完依赖后,无需手动配置。下面是一个简单使用 `twin.macro` 的示例:
|
86
|
-
|
87
|
-
``` js
|
88
|
-
import tw from 'twin.macro'
|
89
|
-
|
90
|
-
const Input = tw.input`border hover:border-black`
|
91
|
-
```
|
92
|
-
|
93
|
-
:::tip 提示
|
94
|
-
如果在运行过程中出现了 `MacroError: /project/App.tsx` 错误的时候,有可能是缺少 `twin.macro` 依赖导致的。
|
95
|
-
:::
|
96
|
-
|
97
|
-
更多的使用方式可以参考 `twin.macro` 的 [文档](https://github.com/ben-rogerson/twin.macro/blob/master/docs/index.md)。
|
98
|
-
|
99
|
-
`twin.macro` 默认会读取项目目录下的 `tailwindcss.config.js` 文件,或者通过 `babel-plugin-macro` 上的 [`twin.config`](https://github.com/ben-rogerson/twin.macro/blob/master/docs/options.md#options) 指定的文件路径读取 Tailwind CSS 配置。不过在 Modern.js 中不需要进行这些额外配置。
|
100
|
-
|
101
|
-
当在 `modern.config.ts` 文件中通过 [`source.designSystem`](/docs/configure/app/source/design-system) 和 [`tools.tailwindcss`](/docs/configure/app/tools/tailwindcss) 对 Tailwind CSS 进行配置的时候,这些配置也会对 `twin.macro` 生效。
|
102
|
-
> 当为项目配置 Tailwind CSS 的时候,[`source.designSystem`](/docs/configure/app/source/design-system) 和 [`tools.tailwindcss`](/docs/configure/app/tools/tailwindcss) 这两个配置的组合等价于单独配置了一个 `tailwindcss.config.js` 文件。
|
103
|
-
> 其中[`source.designSystem`](/docs/configure/app/source/design-system)等效于 Tailwind CSS 的 [`theme`](https://v2.tailwindcss.com/docs/configuration#theme) 配置。
|
104
|
-
|
105
|
-
|
101
|
+
> 当你为项目配置 Tailwind CSS 的时候,[source.designSystem](/docs/configure/app/source/design-system) 和 [tools.tailwindcss](/docs/configure/app/tools/tailwindcss) 这两个配置的组合等价于单独配置了一个 `tailwindcss.config.js` 文件。其中 [source.designSystem](/docs/configure/app/source/design-system) 等效于 Tailwind CSS 的 [theme](https://v2.tailwindcss.com/docs/configuration#theme) 配置。
|
@@ -9,10 +9,10 @@ Modern.js 中提供了开箱即用的数据获取能力,开发者可以通过
|
|
9
9
|
|
10
10
|
## Data Loader(推荐)
|
11
11
|
|
12
|
-
Modern.js 推荐使用约定式路由做路由的管理,通过 Modern.js 的[约定式(嵌套)路由](/docs/guides/basic-features/routes#约定式路由),每个路由组件(`layout.ts` 或 `page.ts`)可以导出一个函数`loader
|
12
|
+
Modern.js 推荐使用约定式路由做路由的管理,通过 Modern.js 的[约定式(嵌套)路由](/docs/guides/basic-features/routes#约定式路由),每个路由组件(`layout.ts` 或 `page.ts`)可以导出一个函数`loader`,该函数可以在组件渲染之前执行,为路由组件提供数据。
|
13
13
|
|
14
14
|
:::info
|
15
|
-
Modern.js
|
15
|
+
Modern.js v1 支持通过 [useLoader](#useloader旧版) 获取数据,这已经不是我们推荐的用法,除迁移过程外,不推荐两者混用。
|
16
16
|
:::
|
17
17
|
|
18
18
|
### 基础示例
|
@@ -85,7 +85,7 @@ export default function UserPage() {
|
|
85
85
|
|
86
86
|
|
87
87
|
`loader` 函数有两个入参:
|
88
|
-
|
88
|
+
#### `Params`
|
89
89
|
|
90
90
|
当路由文件通过 `[]` 时,会作为[动态路由](/docs/guides/basic-features/routes#动态路由),动态路由片段会作为参数传入 loader 函数:
|
91
91
|
|
@@ -102,9 +102,9 @@ export const loader = async({ params }: LoaderArgs) => {
|
|
102
102
|
|
103
103
|
当访问 `/user/123` 时,`loader` 函数的参数为 `{ params: { id: '123' } }`。
|
104
104
|
|
105
|
-
|
105
|
+
#### `request`
|
106
106
|
|
107
|
-
request 是一个 [Fetch Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) 实例。
|
107
|
+
`request` 是一个 [Fetch Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) 实例。
|
108
108
|
|
109
109
|
一个常见的使用场景是通过 `request` 获取查询参数:
|
110
110
|
```tsx
|
@@ -181,7 +181,7 @@ const ErrorBoundary = () => {
|
|
181
181
|
export default ErrorBoundary;
|
182
182
|
```
|
183
183
|
|
184
|
-
###
|
184
|
+
### 获取上层组件的数据
|
185
185
|
|
186
186
|
很多场景下,子组件需要获取到祖先组件 loader 中的数据,你可以通过 `useRouteLoaderData` 方便地获取到祖先组件的数据:
|
187
187
|
```tsx
|
@@ -239,6 +239,7 @@ export default function UserLayout() {
|
|
239
239
|
.
|
240
240
|
└── routes
|
241
241
|
├── layout.tsx
|
242
|
+
├── loading.tsx
|
242
243
|
└── user
|
243
244
|
├── layout.tsx
|
244
245
|
└── page.ts
|
@@ -103,7 +103,7 @@ if (process.env.NODE_ENV === 'development') {
|
|
103
103
|
}
|
104
104
|
```
|
105
105
|
|
106
|
-
执行 `pnpm run dev`
|
106
|
+
执行 `pnpm run dev` 命令之后可以看到如下构建产物:
|
107
107
|
|
108
108
|
```js
|
109
109
|
if (true) {
|
@@ -119,7 +119,7 @@ if (true) {
|
|
119
119
|
|
120
120
|
### 任意命名
|
121
121
|
|
122
|
-
如果需要在代码中使用任意名称的环境变量,可以在 [`source.globalVars`](/docs/configure/app/source/global-vars) 配置指定,
|
122
|
+
如果需要在代码中使用任意名称的环境变量,可以在 [`source.globalVars`](/docs/configure/app/source/global-vars) 配置指定, 例如:
|
123
123
|
|
124
124
|
```typescript title="modern.config.ts"
|
125
125
|
export default defineConfig({
|