@modern-js/main-doc 2.0.0-beta.4 → 2.0.0-beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/en/docusaurus-plugin-content-docs/current/apis/app/commands/dev.md +8 -3
  3. package/en/docusaurus-plugin-content-docs/current/apis/app/commands/inspect.md +33 -8
  4. package/en/docusaurus-plugin-content-docs/current/apis/app/commands/serve.md +32 -0
  5. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/server.md +31 -0
  6. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/bootstrap.md +4 -3
  7. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/create-app.md +2 -3
  8. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/use-module-apps.md +1 -1
  9. package/en/docusaurus-plugin-content-docs/current/components/init-app.md +1 -1
  10. package/en/docusaurus-plugin-content-docs/current/configure/app/builder-plugins.md +70 -0
  11. package/en/docusaurus-plugin-content-docs/current/configure/app/dev/with-master-app.md +0 -1
  12. package/en/docusaurus-plugin-content-docs/current/configure/app/plugins.md +11 -5
  13. package/en/docusaurus-plugin-content-docs/current/configure/app/source/disable-entry-dirs.md +38 -0
  14. package/en/docusaurus-plugin-content-docs/current/configure/app/source/entries.md +66 -2
  15. package/en/docusaurus-plugin-content-docs/current/configure/app/tools/esbuild.md +1 -1
  16. package/en/docusaurus-plugin-content-docs/current/guides/concept/entries.md +1 -1
  17. package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +3 -3
  18. package/en/docusaurus-plugin-content-docs/current/guides/topic-detail/framework-plugin/_category_.json +4 -0
  19. package/en/docusaurus-plugin-content-docs/current/guides/{concept → topic-detail/framework-plugin}/lifecycle.md +0 -0
  20. package/package.json +3 -3
  21. package/zh/apis/app/commands/dev.md +9 -4
  22. package/zh/apis/app/commands/inspect.md +34 -9
  23. package/zh/apis/app/commands/{start.md → serve.md} +3 -3
  24. package/zh/apis/app/hooks/src/index_.md +1 -1
  25. package/zh/apis/app/hooks/src/server.md +31 -0
  26. package/zh/apis/app/runtime/core/bootstrap.md +3 -4
  27. package/zh/apis/app/runtime/core/create-app.md +1 -18
  28. package/zh/apis/app/runtime/core/use-module-apps.md +64 -33
  29. package/zh/apis/app/runtime/web-server/hook.md +1 -1
  30. package/zh/apis/app/runtime/web-server/middleware.md +1 -0
  31. package/zh/components/default-mwa-generate.md +5 -0
  32. package/zh/components/deploy.md +1 -0
  33. package/zh/components/enable-micro-frontend.md +13 -0
  34. package/zh/components/init-app.md +2 -2
  35. package/zh/components/micro-runtime-config.md +18 -0
  36. package/zh/components/prerequisites.md +2 -2
  37. package/zh/components/release-note.md +1 -0
  38. package/zh/configure/app/builder-plugins.md +72 -0
  39. package/zh/configure/app/deploy/_category_.json +4 -0
  40. package/zh/configure/app/deploy/microFrontend.md +64 -0
  41. package/zh/configure/app/dev/with-master-app.md +0 -2
  42. package/zh/configure/app/plugins.md +10 -4
  43. package/zh/configure/app/runtime/master-app.md +33 -36
  44. package/zh/configure/app/source/disable-entry-dirs.md +37 -0
  45. package/zh/configure/app/source/entries-dir.md +0 -3
  46. package/zh/configure/app/source/entries.md +66 -3
  47. package/zh/guides/advanced-features/compatibility.md +12 -1
  48. package/zh/guides/advanced-features/eslint.md +21 -21
  49. package/zh/guides/advanced-features/ssg.md +14 -3
  50. package/zh/guides/advanced-features/ssr.md +1 -1
  51. package/zh/guides/advanced-features/testing.md +11 -0
  52. package/zh/guides/advanced-features/web-server.md +12 -1
  53. package/zh/guides/basic-features/css/tailwindcss.md +11 -0
  54. package/zh/guides/basic-features/data-fetch.md +398 -5
  55. package/zh/guides/basic-features/routes.md +35 -3
  56. package/zh/guides/concept/entries.md +104 -14
  57. package/zh/guides/get-started/quick-start.md +8 -5
  58. package/zh/guides/get-started/upgrade.md +3 -1
  59. package/zh/guides/{concept → topic-detail/framework-plugin}/lifecycle.md +0 -0
  60. package/zh/guides/topic-detail/micro-frontend/c01-introduction.md +29 -0
  61. package/zh/guides/topic-detail/micro-frontend/c02-development.md +191 -0
  62. package/zh/guides/topic-detail/micro-frontend/c03-main-app.md +246 -0
  63. package/zh/guides/topic-detail/micro-frontend/c04-communicate.md +54 -0
  64. package/zh/guides/topic-detail/micro-frontend/{mixed-stack.md → c05-mixed-stack.md} +3 -3
  65. package/zh/guides/topic-detail/monorepo/create-sub-project.md +2 -2
  66. package/zh/tutorials/first-app/c01-start.md +9 -4
  67. package/zh/tutorials/first-app/c03-css.md +19 -0
  68. package/zh/tutorials/first-app/c04-routes.md +4 -4
  69. package/zh/tutorials/first-app/c05-loader.md +3 -3
  70. package/zh/tutorials/first-app/c06-model.md +19 -19
  71. package/zh/tutorials/first-app/c07-container.md +38 -23
  72. package/zh/tutorials/first-app/c08-entries.md +4 -1
  73. package/en/docusaurus-plugin-content-docs/current/apis/app/commands/start.md +0 -32
  74. package/zh/guides/advanced-features/custom-app.md +0 -70
  75. package/zh/guides/topic-detail/micro-frontend/communicate.md +0 -39
  76. package/zh/guides/topic-detail/micro-frontend/debugging.md +0 -168
  77. package/zh/guides/topic-detail/micro-frontend/introduction.md +0 -13
  78. package/zh/guides/topic-detail/micro-frontend/route-mode.md +0 -110
@@ -0,0 +1,29 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: 微前端介绍
4
+ ---
5
+
6
+ 微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。
7
+
8
+ 它主要解决了两个问题:
9
+
10
+ * 随着项目迭代应用越来越庞大,难以维护。
11
+ * 跨团队或跨部门协作开发项目导致效率低下的问题。
12
+
13
+ ## 微前端关键词
14
+
15
+ 在微前端研发模式中,应用会被分成 **主应用**、和 **子应用**。
16
+
17
+ - 主应用:微前端项目的基座工程,所有子应用都会由它来加载。
18
+ - 子应用:独立开发、独立部署的应用,最终会被主应用加载。
19
+
20
+ ## 功能简介
21
+
22
+ * 基于 [Garfish](https://www.garfishjs.org/guide)
23
+ * 生成器支持微前端应用
24
+ * 支持 React 组件式引用微前端子应用
25
+ * 支持 loading
26
+ * 支持主应用线上、子应用线下调试模式
27
+
28
+ 可以在 [体验微前端](/docs/guides/topic-detail/micro-frontend/c02-development) 一节学习如何开发微前端主子应用。
29
+
@@ -0,0 +1,191 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: 体验微前端
4
+ ---
5
+
6
+ 通过本章你可以了解到:
7
+
8
+ - 如何创建微前端项目的主应用、子应用。
9
+ - 微前端项目开发的基本流程。
10
+
11
+ ## 创建应用
12
+
13
+ 在这次的实践中,我们需要创建三个应用,分别为1个主应用,2个子应用:
14
+
15
+ - main 主应用
16
+ - dashboard 子应用
17
+ - table 子应用
18
+
19
+ ### 创建 main 主应用
20
+
21
+ 通过命令行工具初始化项目:
22
+
23
+ ```bash
24
+ mkdir main && cd main
25
+ npx @modern-js/create
26
+ ```
27
+
28
+ import DefaultMWAGenerate from '@site-docs/components/default-mwa-generate.md';
29
+
30
+ <DefaultMWAGenerate />
31
+
32
+ 完成项目创建后我们可以通过 `pnpm run new` 来开启 `微前端` 功能:
33
+
34
+ ```bash
35
+ ? 请选择你想要的操作 启用可选功能
36
+ ? 启用可选功能 启用「微前端」模式
37
+ ```
38
+
39
+ 接下来,让我们注册微前端插件并添加开启微前端主应用,并增加子应用列表:
40
+
41
+ import EnableMicroFrontend from '@site-docs/components/enable-micro-frontend.md';
42
+
43
+ <EnableMicroFrontend />
44
+
45
+ import MicroRuntimeConfig from '@site-docs/components/micro-runtime-config.md';
46
+
47
+ <MicroRuntimeConfig />
48
+
49
+
50
+ ### 创建 dashboard 子应用
51
+
52
+ 通过命令行工具初始化项目:
53
+
54
+ ```bash
55
+ mkdir dashboard && cd dashboard
56
+ npx @modern-js/create
57
+ ```
58
+
59
+ 按照如下选择,生成项目:
60
+
61
+ <DefaultMWAGenerate/>
62
+
63
+ 我们执行 `pnpm run new` 来开启 `微前端` 功能:
64
+
65
+ ```bash
66
+ ? 请选择你想要的操作 启用可选功能
67
+ ? 启用可选功能 启用「微前端」模式
68
+ ```
69
+ 接下来,让我们注册微前端插件并修改 `modern.config.ts`,添加微前端子应用的配置 `deploy.microFrontend`:
70
+
71
+ ```javascript title="modern.config.ts"
72
+ import AppToolPlugin, { defineConfig } from '@modern-js/app-tools';
73
+ import GarfishPlugin from '@modern-js/plugin-garfish';
74
+
75
+ export default defineConfig({
76
+ runtime: {
77
+ router: true,
78
+ state: true
79
+ },
80
+ deploy: {
81
+ microFrontend: true
82
+ },
83
+ plugins: [AppToolPlugin(), GarfishPlugin()],
84
+ });
85
+ ```
86
+
87
+ ### 创建 table 子应用
88
+
89
+ 通过命令行工具初始化项目:
90
+
91
+ ```bash
92
+ mkdir table && cd table
93
+ npx @modern-js/create
94
+ ```
95
+
96
+ 按照如下选择,生成项目:
97
+
98
+ <DefaultMWAGenerate/>
99
+
100
+ 我们执行 `pnpm run new` 来开启 `微前端`:
101
+
102
+ ```bash
103
+ ? 请选择你想要的操作 启用可选功能
104
+ ? 启用可选功能 启用「微前端」模式
105
+ ```
106
+
107
+ 接下来,让我们注册微前端插件并修改 `modern.config.ts`,添加微前端子应用的配置 `deploy.microFrontend`:
108
+
109
+ ```javascript title="modern.config.ts"
110
+ import AppToolPlugin, { defineConfig } from '@modern-js/app-tools';
111
+ import GarfishPlugin from '@modern-js/plugin-garfish';
112
+
113
+ export default defineConfig({
114
+ runtime: {
115
+ router: true,
116
+ state: true
117
+ },
118
+ deploy: {
119
+ microFrontend: true
120
+ },
121
+ plugins: [AppToolPlugin(), GarfishPlugin()],
122
+ });
123
+ ```
124
+
125
+ ## 添加代码
126
+
127
+ ### main 主应用
128
+
129
+ 删除 `src/routers` 目录, 创建 `src/App.tsx`,并添加如下内容:
130
+
131
+ ```tsx
132
+ import { Link } from '@modern-js/runtime/router';
133
+ import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
134
+
135
+ const App = () => {
136
+ const { DashBoard, TableList } = useModuleApps();
137
+ return (
138
+ <div>
139
+ <div>
140
+ <Link to='/dashboard'>Dashboard</Link> &nbsp;
141
+ <Link to='/table'>Table</Link>
142
+ </div>
143
+ <Route path='/dashboard'>
144
+ <DashBoard />
145
+ </Route>
146
+ <Route path='/table'>
147
+ <TableList />
148
+ </Route>
149
+ </div>
150
+ );
151
+ };
152
+
153
+ export default App;
154
+ ```
155
+
156
+ ### dashboard 子应用
157
+
158
+ 删除 `src/routers` 目录, 创建 `src/App.tsx`,并添加如下内容:
159
+
160
+ ```tsx
161
+ export default () => <div>Dashboard Page</div>;
162
+ ```
163
+
164
+ ### table 子应用
165
+
166
+ 删除 `src/routers` 目录, 创建 `src/App.tsx`,并添加如下内容:
167
+
168
+ ```tsx
169
+ export default () => <div>Table Page</div>;
170
+ ```
171
+
172
+ ## 调试
173
+
174
+ 按顺序在 `main`、 `dashboard`、 `table` 目录执行 `pnpm run dev` 命令启动应用:
175
+
176
+ - main - `http://localhost:8080`
177
+ - dashboard - `http://localhost:8081`
178
+ - table - `http://localhost:8082`
179
+
180
+ 访问主应用地址 `http://localhost:8080`,效果如下:
181
+
182
+ ![demo](https://tosv.byted.org/obj/eden-internal/ozpmyhn_lm_hymuPild/ljhwZthlaukjlkulzlp/modernjs/micro-demo.gif)
183
+
184
+ 在完成了微前端整体开发流程的体验后,你可以进一步了解如何 [开发主应用](./c03-main-app.md)
185
+
186
+
187
+ ## 常见问题
188
+
189
+ 自查手册: https://www.garfishjs.org/issues/
190
+
191
+
@@ -0,0 +1,246 @@
1
+ ---
2
+ sidebar_position: 3
3
+ title: 开发主应用
4
+ ---
5
+
6
+ 在上一章 [体验微前端](./c02-development.md) 通过一个示例演示了如何创建和配置微前端子应用,通过本章你可以进一步了解如何开发主应用,以及它的常见配置。
7
+
8
+ 在通过 `@modern-js/create` 命令创建应用工程后,可以在项目中执行 `pnpm run new`(实际执行了 `modern new` 命令),在选择了「微前端」模式后,会安装微前端依赖依赖,只需手动注册插件即可。
9
+
10
+ import EnableMicroFrontend from '@site-docs/components/enable-micro-frontend.md';
11
+
12
+ <EnableMicroFrontend />
13
+
14
+ ## 注册子应用信息
15
+
16
+ 当在 `masterApp` 配置上提供了信息后,将会认为该应用为主应用,目前存在两种子应用信息的配置方式,这两种方式分别应用于不同的场景。
17
+
18
+
19
+ ### 直接注册子应用信息
20
+
21
+ 可以直接通过配置注册子应用信息:
22
+
23
+ :::tip 提示
24
+ 可以通过 API [defineConfig](/docs/apis/app/runtime/app/define-config) 在运行时进行配置。
25
+ 当参数为函数时无法被序列化到产物代码,所以在涉及到函数之类的配置时请通过 defineConfig 来进行配置
26
+ :::
27
+
28
+ import MicroRuntimeConfig from '@site-docs/components/micro-runtime-config.md';
29
+
30
+ <MicroRuntimeConfig />
31
+
32
+
33
+ ### 自定义远程应用列表
34
+
35
+ 通过该函数可以拉取远程的子应用列表,并将其注册至运行时框架:
36
+
37
+ ```ts title="App.tsx"
38
+ defineConfig(App, {
39
+ masterApp: {
40
+ manifest: {
41
+ getAppList: async ()=> {
42
+ // 可以从其他远程接口获取
43
+ return [
44
+ {
45
+ name: 'DashBoard',
46
+ entry: 'http://127.0.0.1:8081/'
47
+ },
48
+ {
49
+ name: 'TableList',
50
+ entry: 'http://localhost:8082'
51
+ }
52
+ ];
53
+ },
54
+ }
55
+ }
56
+ })
57
+ ```
58
+
59
+ ## 渲染子应用
60
+
61
+ 在微前端中分为两种加载子应用的方式:
62
+
63
+ 1. **子应用组件** 获取到每个子应用的组件,之后就可以像使用普通的 `React` 组件一样渲染微前端的子应用。
64
+ 2. **集中式路由** 通过集中式的路由配置,自动根据当前页面 `pathname` 激活渲染对应的子应用。
65
+
66
+ ### 子应用组件
67
+
68
+ 开发者使用 `useModuleApps` 方法可以获取到各个子应用的组件。
69
+
70
+ 再通过 `router` 组件的结合运用,开发者可以自控式的根据不同的路由渲染不同的子应用。
71
+
72
+ 假设我们的子应用列表配置如下:
73
+
74
+ <EnableMicroFrontend />
75
+
76
+ 编辑主应用 `App.tsx` 文件如下:
77
+
78
+ ```tsx title=主应用:App.tsx
79
+ import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
80
+ import { Route, Switch } from '@modern-js/runtime/router';
81
+
82
+ function App() {
83
+ const { DashBoard, TableList} = useModuleApps();
84
+
85
+ return <div>
86
+ <Route path="/dashboard">
87
+ <DashBoard
88
+ loadable={{
89
+ loading: ({ pastDelay, error }: any) => {
90
+ if (error) {
91
+ return <div>error: {error?.message}</div>;
92
+ } else if (pastDelay) {
93
+ return <div>loading</div>;
94
+ } else {
95
+ return null;
96
+ }
97
+ },
98
+ }}
99
+ />
100
+ </Route>
101
+ <Route path="/table">
102
+ <TableList />
103
+ </Route>
104
+ </div>
105
+ }
106
+ ```
107
+
108
+ 这里通过 `Route` 组件自定义了 **DashBoard** 的激活路由为 **/dashboard**, **TableList** 的激活路由为 **/table**。
109
+
110
+ ### 集中式路由
111
+
112
+ **集中式路由** 是将子应用的激活路由集中配置的方式。我们给子应用列表信息添加 `activeWhen` 字段来启用 **集中式路由**。
113
+
114
+
115
+ <MicroRuntimeConfig />
116
+
117
+ 然后在主应用中使用 `useModuleApp` 方法获取 `MApp` 组件, 并在主应用渲染 `MApp`。
118
+
119
+ ```tsx title=主应用:App.tsx
120
+ import { useModuleApp } from '@modern-js/plugin-runtime';
121
+
122
+ function App() {
123
+ const { MApp } = useModuleApps();
124
+
125
+ return <div>
126
+ <MApp />
127
+ </div>
128
+ }
129
+ ```
130
+
131
+ 这样启动应用后,访问 `/dashboard` 路由,会渲染 `Dashboard` 子应用,访问 `/table` 路由,会渲染 `TableList` 子应用。
132
+
133
+
134
+ ### 两种模式混用
135
+
136
+ 当然 **子应用组件** 和 **集中式路由** 是可以混合使用的。
137
+
138
+ - 一部分子应用作为 **子应用组件** 激活,另外一部分作为 **集中式路由** 激活。
139
+ - 一部分子应用既可以作为 **集中式路由** 激活,也可以作为 **子应用组件** 激活。
140
+
141
+
142
+ ### 添加 loading
143
+
144
+ 通过配置 `loadable` 配置,可以为「集中式路由」、「子应用」添加 loading 组件,并可以考虑错误、超时、闪烁等情况的出现,从而为用户提供更好的用户体验。该功能的设计与实现参考至 [react-loadable](https://github.com/jamiebuilds/react-loadable),基本功能较为相似。
145
+
146
+ ```tsx
147
+ function Loading() {
148
+ return <div>Loading...</div>;
149
+ }
150
+
151
+ function App(){
152
+ return <>
153
+ <DashBoard
154
+ loadable={{
155
+ loading: Loading,
156
+ }}
157
+ />
158
+ <>
159
+ }
160
+ ```
161
+
162
+ #### 增加错误状态
163
+
164
+ 当微前端子应用加载失败或渲染失败时,`loading component` 将会接收 `error` 参数(若没有错误时 error 是 null)
165
+
166
+ ```tsx
167
+ function Loading({ error }) {
168
+ if (error) {
169
+ return <div>Error msg {error?.message}</div>;
170
+ } else {
171
+ return <div>Loading...</div>;
172
+ }
173
+ }
174
+ ```
175
+
176
+ #### 避免 loading 闪退
177
+
178
+ 有时 loading 组件的显示时间可能小于 200ms,这个时候会出现 loading 组件闪退的情况。许多用户研究证明,loading 闪退的情况会导致用户感知加载内容的耗时比实际耗时更长,在 loading 小于 200ms 时,不展示内容,用户会认为它更快。
179
+
180
+ 所以 loading 组件还提供了 `pastDelay` 参数,超过设置的延迟展示时才会为 true,可以通过 `delay` 参数设置延迟的时长
181
+
182
+
183
+ ```tsx
184
+ function Loading({ error, pastDelay }) {
185
+ if (error) {
186
+ return <div>Error! {error?.message}</div>;
187
+ } else if (pastDelay) {
188
+ return <div>Loading...</div>;
189
+ } else {
190
+ return null;
191
+ }
192
+ }
193
+ ```
194
+
195
+ `delay` 的默认值为 `200ms`,可以通过 `loadable` 中的 `delay` 来设置延迟展示的时间
196
+
197
+ ```tsx
198
+
199
+ function App(){
200
+ return <>
201
+ <DashBoard
202
+ loadable={{
203
+ loading: Loading,
204
+ delay: 300 // 0.3 seconds
205
+ }}
206
+ />
207
+ <>
208
+ }
209
+ ```
210
+
211
+ #### 增加超时状态
212
+
213
+ 有时因为网络的原因,从而导致微前端子应用加载失败,从而导致一直展示 loading 的状态,这对于用户而言非常糟糕,因为他们不知道合适才会获得具体的响应,他们是否需要刷新页面,通过增加超时状态可以很好的解决该问题。
214
+
215
+ loading 组件在超时时会获得 `timeOut` 参数,当微前端应用加载超时时将会获得 `timeOut` 属性值为 true
216
+
217
+ ```tsx
218
+ function Loading({ error, timeOut, pastDelay }) {
219
+ if (error) {
220
+ return <div>Error! {error?.message}</div>;
221
+ } else if (timeOut) {
222
+ return <div>Loading timed out, please refresh the page... </div>;
223
+ } else if (pastDelay) {
224
+ return <div>Loading...</div>;
225
+ } else {
226
+ return null;
227
+ }
228
+ }
229
+ ```
230
+
231
+ 超时状态是关闭的,可以通过在 `loadable` 中设置 `timeout` 参数开启
232
+
233
+
234
+ ```tsx
235
+
236
+ function App(){
237
+ return <>
238
+ <DashBoard
239
+ loadable={{
240
+ loading: Loading,
241
+ timeOut: 10000 // 10s
242
+ }}
243
+ />
244
+ <>
245
+ }
246
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: 主子应用通信
4
+ ---
5
+
6
+ ## props 通信
7
+
8
+ Modern.js 中,会将子应用包裹成一个 React 组件,直接通过给 React 组件传递 `props` 即可实现主应用和子应用通信的目的。
9
+
10
+ ```tsx title=主应用:App.tsx
11
+ function App() {
12
+ const { MApp } = useModuleApps();
13
+
14
+ return <div>
15
+ <MApp count={100} />
16
+ </div>;
17
+ }
18
+ ```
19
+
20
+ ```tsx title=子应用:App.tsx
21
+ function App(props) {
22
+ console.log(props);
23
+ return ...
24
+ }
25
+ ```
26
+
27
+ 子应用将会打印 `{count: 0}`,目前尚未支持子应用渲染响应式,及时在主应用上更改 `count` 的数据也不会触发视图更新
28
+
29
+ ## channel 通信
30
+
31
+ [Garfish.channel](https://www.garfishjs.org/api/channel) 用于应用间的通信。它是 `EventEmitter2` 的实例
32
+
33
+ ```ts
34
+ // 子应用监听登录事件
35
+ const App = () => {
36
+ const handleLogin = (userInfo) => {
37
+ console.log(`${userInfo.name} has login`);
38
+ };
39
+
40
+ useEffect(() => {
41
+ window?.Garfish.channel.on('login', handleLogin);
42
+ return () => {
43
+ window?.Garfish.channel.removeListener('login', handleLogin);
44
+ };
45
+ });
46
+ };
47
+
48
+ // 主应用触发监听事件
49
+ api.getLoginInfo.then((res) => {
50
+ if (res.code === 0) {
51
+ window.Garfish.channel.emit('login', res.data);
52
+ }
53
+ });
54
+ ```
@@ -3,7 +3,7 @@ sidebar_position: 5
3
3
  title: 混合技术栈
4
4
  ---
5
5
 
6
- Modern.js 微前端方案是基于 [Garfish](https://garfish.top/) 封装的,提供了一些更开箱即用的使用方式。
6
+ Modern.js 微前端方案是基于 [Garfish](https://garfishjs.org/) 封装的,提供了一些更开箱即用的使用方式。
7
7
 
8
8
  当你的主应用和子应用不全是 Modern.js 应用的时候,可以参考这片文档。
9
9
 
@@ -12,7 +12,7 @@ Modern.js 微前端方案是基于 [Garfish](https://garfish.top/) 封装的,
12
12
 
13
13
  ## 子应用是 Modern.js
14
14
 
15
- **Modern.js** 子应用编译后会生成标准的 [Garfish 子应用导出](https://garfish.top/quick-start#%E5%AD%90%E5%BA%94%E7%94%A8)。
15
+ **Modern.js** 子应用编译后会生成标准的 [Garfish 子应用导出](https://www.garfishjs.org/guide/start#2%E5%AF%BC%E5%87%BA-provider-%E5%87%BD%E6%95%B0)。
16
16
  所以可以直接接入标准的微前端主应用。
17
17
 
18
18
  :::info 注
@@ -21,4 +21,4 @@ Modern.js 微前端方案是基于 [Garfish](https://garfish.top/) 封装的,
21
21
 
22
22
  ## 主应用是 Modern.js
23
23
 
24
- 主应用是 **Modern.js**,子应用用的其它技术栈。子应用按照 [Garfish 子应用标准](https://garfish.top/quick-start#%E5%AD%90%E5%BA%94%E7%94%A8) 开发即可。
24
+ 主应用是 **Modern.js**,子应用用的其它技术栈。子应用按照 [Garfish 子应用标准](https://www.garfishjs.org/guide/demo/react) 开发即可。
@@ -57,8 +57,8 @@ pnpm run new
57
57
  [INFO] 创建成功!
58
58
  可在新项目的目录下运行以下命令:
59
59
  pnpm run dev # 按开发环境的要求,运行和调试项目
60
- pnpm run build # 按产品环境的要求,构建项目
61
- pnpm run start # 按产品环境的要求,运行项目
60
+ pnpm run build # 按生产环境的要求,构建项目
61
+ pnpm run serve # 按生产环境的要求,运行项目
62
62
  pnpm run lint # 检查和修复所有代码
63
63
  pnpm run new # 继续创建更多项目要素,比如应用入口
64
64
  ```
@@ -64,20 +64,24 @@ function App() {
64
64
  export default App;
65
65
  ```
66
66
 
67
- 因为框架默认支持 [HMR](https://webpack.js.org/concepts/hot-module-replacement/),可以看到 `http://localhost:8080/` 里的内容会自动变成 Hello Modern.js。
68
-
69
67
  删除多余的 css 文件,保持目录没有多余的文件:
70
68
 
71
69
  ```bash
72
70
  rm src/routes/index.css
73
71
  ```
74
72
 
75
- ## 使用配置
73
+ 因为框架默认支持 [HMR](https://webpack.js.org/concepts/hot-module-replacement/),可以看到 `http://localhost:8080/` 里的内容会自动更新为:
74
+
75
+ ![result](https://lf3-static.bytednsdoc.com/obj/eden-cn/zq-uylkvt/ljhwZthlaukjlkulzlp/screenshot-20221214-141909.png)
76
+
77
+ 此刻的页面还没有样式。下一章节将展开这部分的内容。
78
+
79
+ ## 开启 SSR
76
80
 
77
81
  接下来,我们修改项目中的 `modern.config.ts`,开启 SSR 能力:
78
82
 
79
83
  ```ts
80
- import { defineConfig } from '@modern-js/app-tools';
84
+ import AppToolsPlugin, { defineConfig } from '@modern-js/app-tools';
81
85
 
82
86
  // https://modernjs.dev/docs/apis/app/config
83
87
  export default defineConfig({
@@ -88,6 +92,7 @@ export default defineConfig({
88
92
  server: {
89
93
  ssr: true,
90
94
  },
95
+ plugins: [AppToolsPlugin()],
91
96
  });
92
97
  ```
93
98
 
@@ -118,6 +118,25 @@ Modern.js 集成了主流、轻量、通用的 Utility Class 工具库 [Tailwind
118
118
  ? 启用可选功能 启用 Tailwind CSS 支持
119
119
  ```
120
120
 
121
+ 在 `modern.config.ts` 中注册 Tailwind 插件:
122
+
123
+ ```ts title="modern.config.ts"
124
+ import AppToolsPlugin, { defineConfig } from '@modern-js/app-tools';
125
+ import TailwindCSSPlugin from '@modern-js/plugin-tailwindcss';
126
+
127
+ // https://modernjs.dev/docs/apis/app/config
128
+ export default defineConfig({
129
+ runtime: {
130
+ router: true,
131
+ state: true,
132
+ },
133
+ server: {
134
+ ssr: true,
135
+ },
136
+ plugins: [AppToolsPlugin(), TailwindCSSPlugin()],
137
+ });
138
+ ```
139
+
121
140
  在 `src/routes/page.tsx` 顶部引入 Tailwind CSS 的 css 文件,就可以开始快速实现专业的 UI:
122
141
 
123
142
  ```js
@@ -34,7 +34,7 @@ ni src/routes/archives/page.tsx
34
34
 
35
35
  添加如下代码:
36
36
 
37
- ```tsx
37
+ ```tsx title="src/archives/page.tsx"
38
38
  import { List } from 'antd';
39
39
  import { Helmet } from '@modern-js/runtime/head';
40
40
  import Item from '../../components/Item';
@@ -94,16 +94,16 @@ Modern.js 默认集成了 react-helmet,也可以结合 SSR 使用,满足 SEO
94
94
  import 'tailwindcss/base.css';
95
95
  import 'tailwindcss/components.css';
96
96
  import 'tailwindcss/utilities.css';
97
- import "../styles/utils.css";
97
+ import '../styles/utils.css';
98
98
  ```
99
99
 
100
100
  执行 `pnpm run dev`,访问 `http://localhost:8080`,可以看到完整的联系人,页面的标题是 All:
101
101
 
102
- ![display](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/tutorials/c04-all.png)
102
+ ![display1](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/tutorials/c04-archives.png)
103
103
 
104
104
  访问 `http://localhost:8080/archives`,只会看到已存档的联系人,页面的标题是 Archives:
105
105
 
106
- ![display1](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/tutorials/c04-archives.png)
106
+ ![display](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/tutorials/c04-all.png)
107
107
 
108
108
  查看页面 HTML 源码,可以看到两个页面的内容是一样,是在客户端针对不同 URL 渲染不同内容。
109
109
 
@@ -4,7 +4,7 @@ title: 添加 Loader
4
4
 
5
5
  上一章节中,我们学习了如何添加客户端路由。
6
6
 
7
- 这一章节中,我们将会学习如何**为路由组件添加 Loader**。
7
+ 这一章节中,我们将会学习如何为**路由组件添加 Loader**。
8
8
 
9
9
  到目前为止,我们都是通过硬编码的方式,为组件提供数据。如果要从远端获取数据,通常情况下会使用 `useEffect` 来做。但在启用 SSR 的情况下,`useEffect` 是不会在服务端执行的,所以这种 SSR 只能渲染很有限的 UI。
10
10
 
@@ -20,7 +20,7 @@ pnpm add @types/faker@5 -D
20
20
  修改 `src/routes/page.tsx`:
21
21
 
22
22
  ```tsx
23
- import { name, internet } from "faker";
23
+ import { name, internet } from 'faker';
24
24
 
25
25
  type LoaderData = {
26
26
  code: number;
@@ -55,7 +55,7 @@ Data Loader 并非只为 SSR 工作。在 CSR 项目中,Data Loader 也可以
55
55
  Modern.js 也提供了一个叫 `useLoaderData` 的 hooks API,我们修改 `src/routes/page.tsx` 导出的组件:
56
56
 
57
57
  ```tsx {1,4,13}
58
- import { useLoaderData } from "@modern-js/runtime/router";
58
+ import { useLoaderData } from '@modern-js/runtime/router';
59
59
 
60
60
  function Index() {
61
61
  const { data } = useLoaderData() as LoaderData;