@modern-js/main-doc 2.0.0-beta.6 → 2.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/apis/app/runtime/router/router.md +176 -373
- package/en/docusaurus-plugin-content-docs/current/components/enable-bff.md +36 -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/components/router-legacy-tip.md +1 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/auto-load-plugin.md +62 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/proxy.md +2 -72
- package/en/docusaurus-plugin-content-docs/current/configure/app/runtime/router.md +17 -2
- 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 +150 -0
- package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/function.md +222 -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 +132 -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/basic-features/routes.md +0 -2
- 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/apis/app/runtime/router/router.md +170 -368
- package/zh/components/debug-app.md +1 -2
- package/zh/components/enable-bff.md +36 -0
- package/zh/components/global-proxy-config.md +70 -0
- package/zh/components/micro-master-manifest-config.md +15 -0
- package/zh/components/router-legacy-tip.md +1 -0
- package/zh/configure/app/auto-load-plugin.md +62 -0
- package/zh/configure/app/deploy/microFrontend.md +0 -10
- package/zh/configure/app/dev/proxy.md +2 -70
- package/zh/configure/app/runtime/master-app.md +2 -16
- package/zh/configure/app/runtime/router.md +17 -3
- package/zh/configure/app/source/entries.md +1 -3
- package/zh/configure/app/tools/_category_.json +1 -1
- package/zh/configure/app/tools/tailwindcss.md +16 -23
- package/zh/guides/advanced-features/bff/frameworks.md +2 -0
- package/zh/guides/advanced-features/bff/function.md +44 -24
- 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 +5 -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 -6
- 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
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/with-master-app.md +0 -31
- package/zh/configure/app/dev/with-master-app.md +0 -32
|
@@ -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,13 +12,17 @@ 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';
|
|
23
19
|
// https://modernjs.dev/docs/apis/app/config
|
|
24
20
|
export default defineConfig({
|
|
25
21
|
...,
|
|
22
|
+
output: {
|
|
23
|
+
...,
|
|
24
|
+
ssg: true,
|
|
25
|
+
},
|
|
26
26
|
plugins: [..., SSGPlugin()],
|
|
27
27
|
});
|
|
28
28
|
```
|
|
@@ -129,45 +129,3 @@ export default defineConfig({
|
|
|
129
129
|
:::info
|
|
130
130
|
以上仅介绍了单入口的情况,更多相关内容可以查看 [API 文档](/docs/configure/app/output/ssg)。
|
|
131
131
|
:::
|
|
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({
|
|
@@ -3,86 +3,60 @@ title: HTML 模板
|
|
|
3
3
|
sidebar_position: 9
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Modern.js 提供了
|
|
6
|
+
Modern.js 提供了 **JSX 语法**和**HTML(Ejs) 语法**两种方式用于自定义 HTML 模板。
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## JSX 语法
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Modern.js 约定,在 `src/` 目录下,或在入口目录下,可以创建 `Document.[jt]sx` 并默认导出组件。该组件的渲染结果可以作为入口的 HTML 模板。
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
例如以下目录结构:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
.
|
|
16
|
+
├── src
|
|
17
|
+
│ ├── Document.tsx
|
|
18
|
+
│ ├── entry-a
|
|
19
|
+
│ │ ├── Document.tsx
|
|
20
|
+
│ │ └── routes
|
|
21
|
+
│ ├── entry-b
|
|
22
|
+
│ │ └── routes
|
|
23
|
+
│ └── modern-app-env.d.ts
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
```tsx
|
|
25
|
-
export default Document() {}
|
|
26
|
+
`entry-a` 会优先使用当前入口下的 `Docoument.[jt]sx` 文件。如果当前入口没有 `Document.[jt]sx` 文件,例如 `entry-b`,则会查找根目录下的 `Document.[jt]sx` 文件。
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
如果还没有,则会兜底到传统模板的逻辑。
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
### HTML 组件
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
Modern.js 提供了一些列渲染页面的组件,用来帮助开发者生成模板,可以从 `@modern-js/runtime/document` 中导出这些组件:
|
|
32
33
|
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
├── src
|
|
36
|
-
│ ├── modern-app-env.d.ts
|
|
37
|
-
│ ├── myapp
|
|
38
|
-
│ │ └── routes
|
|
39
|
-
│ │ ├── index.css
|
|
40
|
-
│ │ ├── layout.tsx
|
|
41
|
-
│ │ ├── Document.tsx
|
|
42
|
-
│ │ └── page.tsx
|
|
43
|
-
│ ├── new-entry
|
|
44
|
-
│ │ └── routes
|
|
45
|
-
│ │ ├── index.css
|
|
46
|
-
│ │ ├── layout.tsx
|
|
47
|
-
│ │ ├── Document.tsx
|
|
48
|
-
│ │ └── page.tsx
|
|
49
|
-
│ └── Document.tsx
|
|
50
|
-
├── modern.config.ts
|
|
51
|
-
├── package.json
|
|
52
|
-
├── pnpm-lock.yaml
|
|
53
|
-
├── README.md
|
|
54
|
-
└── tsconfig.json
|
|
34
|
+
```tsx
|
|
35
|
+
import { Html, Body, Root, Head, Scripts } from '@modern-js/runtime/document';
|
|
55
36
|
```
|
|
56
37
|
|
|
57
|
-
|
|
58
|
-
如果还没有,则会 fallback 到 `html 模板` 的逻辑。
|
|
59
|
-
|
|
60
|
-
#### 子组件
|
|
38
|
+
这些组件分别渲染:
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
分别渲染:
|
|
64
|
-
- `Html`: 提供 html 原生 dom。并计算出 `DocumentStructrueContext` 的值,将 `Html` 的结构传递给子组件,判断其它子组件是否默认渲染。
|
|
40
|
+
- `Html`:提供原生 HTML Element 的能力,并能默认渲染开发者未添加的必须的组件。`<Head>` 和 `<Body>` 是必须要存在的,其它组件可以按需选择合适的组件进行组装。
|
|
65
41
|
|
|
66
|
-
- `Body
|
|
42
|
+
- `Body`:提供原生 Body Element 的能力,内部需要包含 `<Root>` 组件,也支持其它元素同时作为子元素,例如添加页脚。
|
|
67
43
|
|
|
68
|
-
- `Root
|
|
44
|
+
- `Root`:渲染的根节点 `<div id='root'></div>`。默认根节点的 `id = 'root'`。可以设置 `props.rootId` 来更改 id 属性。可以添加子组件,也会被渲染到 HTML 模板中,当 React 渲染完成后会被覆盖,一般用来实现全局 Loading。
|
|
69
45
|
|
|
70
|
-
- `Head
|
|
46
|
+
- `Head`:提供原生 Head Element 的能力,并会自动填充 `<meta>`,以及 `<Scripts>` 组件。
|
|
71
47
|
|
|
72
|
-
- `Scripts
|
|
48
|
+
- `Scripts`:构建产生的 script 内容,可用于调整构建产物的位置,默认放在 `<Head>` 组件中。
|
|
73
49
|
|
|
74
|
-
|
|
50
|
+
### 模板参数
|
|
75
51
|
|
|
76
|
-
|
|
52
|
+
因为是 JSX 形式,`Document.[jt]sx` 里,可以比较自由的在组件内使用各种变量去赋值给各种自定义组件。
|
|
77
53
|
|
|
78
|
-
|
|
79
|
-
但同时 Document 自身也提供了 `DocumentContext` context 来提供一些配置、环境参数,方便直接获取。主要以下参数:
|
|
54
|
+
Modern.js 也提供了 `DocumentContext` 来提供一些配置、环境参数,方便直接获取。主要以下参数:
|
|
80
55
|
|
|
81
56
|
- `processEnv`:提供构建时的 `process.env`
|
|
82
|
-
- `config
|
|
83
|
-
- `entryName
|
|
84
|
-
- `templateParams
|
|
85
|
-
|
|
57
|
+
- `config`:Modern.js 项目的配置。目前只暴露出 output 相关的配置
|
|
58
|
+
- `entryName`:当前的入口名
|
|
59
|
+
- `templateParams`:HTML 模板的参数(为了兼容传统模板,不推荐使用)
|
|
86
60
|
|
|
87
61
|
### 示例
|
|
88
62
|
|
|
@@ -92,12 +66,11 @@ import {
|
|
|
92
66
|
Html,
|
|
93
67
|
Root,
|
|
94
68
|
Head,
|
|
95
|
-
DocumentContext,
|
|
96
69
|
Body,
|
|
70
|
+
Scripts,
|
|
71
|
+
DocumentContext
|
|
97
72
|
} from '@modern-js/runtime/document';
|
|
98
|
-
import Script from '@/components/Script';
|
|
99
73
|
|
|
100
|
-
// 默认导出
|
|
101
74
|
export default function Document(): React.ReactElement {
|
|
102
75
|
// DocumentContext 提供一些构建时的参数
|
|
103
76
|
const {
|
|
@@ -109,34 +82,23 @@ export default function Document(): React.ReactElement {
|
|
|
109
82
|
return (
|
|
110
83
|
<Html>
|
|
111
84
|
<Head>
|
|
112
|
-
// Head 组件支持自定义子元素。包括 link, script
|
|
113
85
|
<link href="https://modernjs.dev">Modern.js</link>
|
|
114
|
-
<script
|
|
115
|
-
// inline script 的脚本需要如下处理
|
|
116
|
-
dangerouslySetInnerHTML={{
|
|
117
|
-
__html: `window.b = 22`,
|
|
118
|
-
}}
|
|
119
|
-
></script>
|
|
120
86
|
</Head>
|
|
121
87
|
<Body>
|
|
122
|
-
// rootId 可以更改根元素的 id
|
|
123
88
|
<Root rootId="root">
|
|
124
|
-
// Root 支持子元素
|
|
125
89
|
<h1 style={{ color: 'red' }}>以下为构建时传过来的参数:</h1>
|
|
126
90
|
<h2> entryName:{entryName}</h2>
|
|
127
91
|
<h2> title:{htmlConfig.title}</h2>
|
|
128
92
|
<h2> rootId: {templateParams.mountId}</h2>
|
|
129
93
|
</Root>
|
|
130
|
-
// Body 组件支持 Root 以外增加不同的组件,共同组成页面
|
|
131
94
|
<h1>bottom</h1>
|
|
132
95
|
</Body>
|
|
133
96
|
</Html>
|
|
134
97
|
);
|
|
135
98
|
}
|
|
136
|
-
|
|
137
99
|
```
|
|
138
100
|
|
|
139
|
-
|
|
101
|
+
以上 JSX 组件,将会生成以下 HTML 模板:
|
|
140
102
|
|
|
141
103
|
```html
|
|
142
104
|
<!DOCTYPE html>
|
|
@@ -162,7 +124,6 @@ export default function Document(): React.ReactElement {
|
|
|
162
124
|
src="/static/js/packages_runtime_plugin-router-legacy_dist_js_treeshaking_runtime_index_js-packages_runtime_p-28f4c9.js"></script>
|
|
163
125
|
<script defer src="/static/js/sub.js"></script>
|
|
164
126
|
<link href="https://www.baidu.com" />
|
|
165
|
-
<script>window.b = 22</script>
|
|
166
127
|
</head>
|
|
167
128
|
|
|
168
129
|
<body>
|
|
@@ -177,26 +138,23 @@ export default function Document(): React.ReactElement {
|
|
|
177
138
|
<!--<?- chunksMap.js ?>-->
|
|
178
139
|
<!--<?- SSRDataScript ?>-->
|
|
179
140
|
</body>
|
|
180
|
-
|
|
181
141
|
</html>
|
|
182
142
|
```
|
|
183
143
|
|
|
184
|
-
##
|
|
144
|
+
## Html 语法
|
|
185
145
|
|
|
186
|
-
Modern.js
|
|
146
|
+
Modern.js 也支持 HTML 语法。默认情况下,Modern.js 的应用工程中会内置一份 HTML 模板,用于生成 HTML 代码。
|
|
187
147
|
|
|
188
|
-
|
|
148
|
+
基于 HTML 语法的模板,Modern.js 提供了 **自定义 HTML 片段**和**完全自定义 HTML 模板**两种方式来自定义模板。
|
|
189
149
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
## 自定义 HTML 片段
|
|
150
|
+
### 自定义 HTML 片段
|
|
193
151
|
|
|
194
152
|
在应用根目录下,创建 `config/html/` 目录,该目录下支持创建四种 HTML 片段。
|
|
195
153
|
|
|
196
|
-
- `top.
|
|
197
|
-
- `head.
|
|
198
|
-
- `body.
|
|
199
|
-
- `bottom.
|
|
154
|
+
- `top.html`
|
|
155
|
+
- `head.html`
|
|
156
|
+
- `body.html`
|
|
157
|
+
- `bottom.html`
|
|
200
158
|
|
|
201
159
|
**这些片段将按位置注入到默认的 HTML 模板中。**
|
|
202
160
|
|
|
@@ -226,54 +184,19 @@ Modern.js 提供了**「自定义 HTML 片段」**和**「完全自定义 HTML
|
|
|
226
184
|
</html>
|
|
227
185
|
```
|
|
228
186
|
|
|
229
|
-
|
|
187
|
+
代码片段支持使用 [Lodash template](https://lodash.com/docs/4.17.15#template) 语法。
|
|
230
188
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```html title="config/html/head.ejs"
|
|
234
|
-
<% if (process.env.NODE_ENV === 'production') { %>
|
|
235
|
-
<meta name='env' content="production">
|
|
236
|
-
<% } else { %>
|
|
237
|
-
<meta name='env' content="development">
|
|
238
|
-
<% } %>
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
或在 `body.html` 里插入一个外链脚本:
|
|
189
|
+
例如在 `body.html` 里插入一个外链脚本:
|
|
242
190
|
|
|
243
191
|
```html title="config/html/body.html"
|
|
244
192
|
<script src="//example.com/assets/a.js"></script>
|
|
245
193
|
```
|
|
246
194
|
|
|
247
|
-
:::info
|
|
248
|
-
自定义 HTML 片段的实现方式是将片段与框架内置的模板进行合并,由于框架的默认模板中已经存在 title
|
|
195
|
+
:::info
|
|
196
|
+
自定义 HTML 片段的实现方式是将片段与框架内置的模板进行合并,由于框架的默认模板中已经存在 `<title>`,因此自定义 HTML 模板中的 title 标签无法生效,请通过 [html.title](/docs/configure/app/html/title) 来修改页面标题。
|
|
249
197
|
:::
|
|
250
198
|
|
|
251
|
-
###
|
|
252
|
-
|
|
253
|
-
模板中使用的参数可以通过 [html.templateParameters](/docs/configure/app/html/template-parameters) 配置项来定义。
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
### 按入口设置
|
|
257
|
-
|
|
258
|
-
`config/html/` 目录中的 HTML 片段对应用中的所有入口都生效。如果希望按入口自定义 HTML 片段,可以在 `config/html/` 目录下新建一个以**入口名**命名的目录,然后在这个目录中自定义 HTML 片段。
|
|
259
|
-
|
|
260
|
-
例如,如下设置的 HTML 片段仅对入口 `entry1` 生效:
|
|
261
|
-
|
|
262
|
-
```html
|
|
263
|
-
.
|
|
264
|
-
├── config/
|
|
265
|
-
│ └── html/
|
|
266
|
-
│ └── entry1
|
|
267
|
-
│ ├── head.html
|
|
268
|
-
│ └── body.html
|
|
269
|
-
└── src/
|
|
270
|
-
├── entry1/
|
|
271
|
-
│ └── App.jsx
|
|
272
|
-
└── entry2/
|
|
273
|
-
└── App.jsx
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## 完全自定义 HTML 模板
|
|
199
|
+
### 完全自定义 HTML 模板
|
|
277
200
|
|
|
278
201
|
某些情况下,HTML 片段无法满足自定义需求,Modern.js 提供了完全自定义方式。
|
|
279
202
|
|
|
@@ -281,30 +204,32 @@ Modern.js 提供了**「自定义 HTML 片段」**和**「完全自定义 HTML
|
|
|
281
204
|
通常不建议直接覆盖默认的 HTML 模板,可能会失去一部分功能选项。即使需要替换,建议以内置模板为基础,按需修改。
|
|
282
205
|
:::
|
|
283
206
|
|
|
284
|
-
|
|
285
|
-
### 配置方式
|
|
286
|
-
|
|
287
|
-
在 `config/html/` 目录下,创建 `index.(html|ejs)` 文件。
|
|
288
|
-
|
|
289
|
-
该文件将替代默认的 HTML 模板。
|
|
207
|
+
在 `config/html/` 目录下,创建 `index.html` 文件,该文件将替代默认的 HTML 模板。
|
|
290
208
|
|
|
291
209
|
:::info 注
|
|
292
210
|
内部默认 HTML 模板可以在 `node_modules/.modern-js/${entryName}/index.html` 中查看。
|
|
293
211
|
:::
|
|
294
212
|
|
|
295
|
-
|
|
213
|
+
### 模板参数
|
|
296
214
|
|
|
297
|
-
|
|
215
|
+
模板中使用的参数可以通过 [html.templateParameters](/docs/configure/app/html/template-parameters) 配置项来定义。
|
|
216
|
+
|
|
217
|
+
### 按入口设置
|
|
218
|
+
|
|
219
|
+
`config/html/` 目录中的 HTML 片段对应用中的所有入口都生效。如果希望按入口自定义 HTML 片段,可以在 `config/html/` 目录下新建一个以**入口名**命名的目录,然后在这个目录中自定义 HTML 片段。
|
|
220
|
+
|
|
221
|
+
例如,如下设置的 HTML 片段仅对入口 `entry1` 生效:
|
|
298
222
|
|
|
299
223
|
```html
|
|
300
224
|
.
|
|
301
225
|
├── config/
|
|
302
226
|
│ └── html/
|
|
303
227
|
│ └── entry1
|
|
304
|
-
│
|
|
228
|
+
│ ├── head.html
|
|
229
|
+
│ └── body.html
|
|
305
230
|
└── src/
|
|
306
231
|
├── entry1/
|
|
307
|
-
│ └──
|
|
232
|
+
│ └── routes
|
|
308
233
|
└── entry2/
|
|
309
|
-
└──
|
|
234
|
+
└── routes
|
|
310
235
|
```
|
|
@@ -7,26 +7,25 @@ Modern.js 提供了快速生成 Mock 数据的功能,能够让前端独立自
|
|
|
7
7
|
|
|
8
8
|
## Mock 文件
|
|
9
9
|
|
|
10
|
-
约定当 `config/mock` 目录下存在 `index.[jt]s` 时,会自动开启 Mock
|
|
10
|
+
约定当 `config/mock` 目录下存在 `index.[jt]s` 时,会自动开启 Mock 功能,如下:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
.
|
|
14
14
|
├── config
|
|
15
15
|
│ └── mock
|
|
16
|
-
│
|
|
17
|
-
│ └── index.js
|
|
16
|
+
│ └── index.ts
|
|
18
17
|
├── src
|
|
19
|
-
│ └── App.
|
|
20
|
-
└── modern.config.
|
|
18
|
+
│ └── App.tsx
|
|
19
|
+
└── modern.config.ts
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
## Mock
|
|
22
|
+
## 编写 Mock 文件
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
`config/mock/index.ts` 文件只需要导出一个包含所有 Mock API 的对象,对象的属性由请求配置 `method` 和 `url` 组成,对应的属性值可以为 `Object`、`Array`、`Function`:
|
|
26
25
|
|
|
27
26
|
```js
|
|
28
27
|
module.exports = {
|
|
29
|
-
/* 属性为具体的 method 和 请求 url,值为 object 或 array作为请求的结果 */
|
|
28
|
+
/* 属性为具体的 method 和 请求 url,值为 object 或 array 作为请求的结果 */
|
|
30
29
|
'GET /api/getInfo': { data: [1, 2, 3, 4] },
|
|
31
30
|
|
|
32
31
|
/* method 默认为 GET */
|
|
@@ -44,7 +43,7 @@ module.exports = {
|
|
|
44
43
|
|
|
45
44
|
## 返回随机数据
|
|
46
45
|
|
|
47
|
-
可以在
|
|
46
|
+
可以在 `config/mock/index.js` 中自主引入 [Mock.js](https://github.com/nuysoft/Mock/wiki/Getting-Started) 等库生成随机数据,例如:
|
|
48
47
|
|
|
49
48
|
```js
|
|
50
49
|
const Mock = require('mockjs');
|