@modern-js/main-doc 2.34.0 → 2.35.1
Sign up to get free protection for your applications and to get access to all the features.
- package/docs/en/apis/app/commands.mdx +12 -11
- package/docs/en/apis/app/hooks/config/public.mdx +2 -2
- package/docs/en/apis/app/hooks/config/upload.mdx +3 -3
- package/docs/en/components/debug-app.mdx +1 -3
- package/docs/en/components/global-proxy-config.mdx +4 -13
- package/docs/en/components/global-proxy.mdx +2 -4
- package/docs/en/components/init-app.mdx +1 -1
- package/docs/en/components/tech-stack-node-framework.mdx +1 -0
- package/docs/en/configure/app/builder-plugins.mdx +2 -2
- package/docs/en/configure/app/plugins.mdx +3 -4
- package/docs/en/configure/app/server/base-url.mdx +0 -2
- package/docs/en/configure/app/source/config-dir.mdx +2 -2
- package/docs/en/configure/app/source/enable-async-entry.mdx +1 -1
- package/docs/en/guides/advanced-features/eslint.mdx +1 -1
- package/docs/en/guides/basic-features/alias.mdx +12 -51
- package/docs/en/guides/basic-features/css.mdx +35 -15
- package/docs/en/guides/basic-features/data-fetch.mdx +12 -12
- package/docs/en/guides/basic-features/env-vars.mdx +1 -1
- package/docs/en/guides/basic-features/html.mdx +2 -2
- package/docs/en/guides/basic-features/routes.mdx +31 -19
- package/docs/en/guides/concept/builder.mdx +1 -1
- package/docs/en/guides/get-started/glossary.mdx +1 -1
- package/docs/en/guides/get-started/introduction.mdx +21 -1
- package/docs/en/guides/get-started/quick-start.mdx +8 -17
- package/docs/en/guides/get-started/tech-stack.mdx +138 -0
- package/docs/en/guides/get-started/upgrade.mdx +10 -4
- package/docs/en/guides/topic-detail/changesets/add.mdx +1 -1
- package/docs/en/guides/topic-detail/changesets/changelog.mdx +3 -3
- package/docs/en/guides/topic-detail/changesets/commit.mdx +3 -3
- package/docs/en/guides/topic-detail/changesets/release-note.mdx +3 -3
- package/docs/en/guides/topic-detail/changesets/release.mdx +1 -1
- package/docs/en/guides/topic-detail/framework-plugin/implement.mdx +6 -4
- package/docs/en/guides/topic-detail/generator/create/use.mdx +1 -9
- package/docs/en/guides/topic-detail/generator/plugin/context.md +1 -1
- package/docs/en/guides/topic-detail/micro-frontend/c01-introduction.mdx +1 -0
- package/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx +24 -17
- package/docs/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +51 -37
- package/docs/en/guides/topic-detail/micro-frontend/c04-communicate.mdx +1 -0
- package/docs/en/guides/topic-detail/micro-frontend/c05-mixed-stack.mdx +1 -1
- package/docs/en/tutorials/first-app/c02-component.mdx +4 -3
- package/docs/zh/apis/app/commands.mdx +10 -9
- package/docs/zh/apis/app/hooks/api/api.mdx +2 -1
- package/docs/zh/apis/app/hooks/server/index_.mdx +2 -1
- package/docs/zh/community/blog/2022-0708-updates.md +4 -4
- package/docs/zh/community/blog/overview.md +1 -1
- package/docs/zh/components/debug-app.mdx +1 -3
- package/docs/zh/components/global-proxy-config.mdx +4 -13
- package/docs/zh/components/global-proxy.mdx +2 -4
- package/docs/zh/components/tech-stack-node-framework.mdx +1 -0
- package/docs/zh/configure/app/builder-plugins.mdx +1 -1
- package/docs/zh/configure/app/plugins.mdx +1 -2
- package/docs/zh/configure/app/server/base-url.mdx +0 -2
- package/docs/zh/configure/app/source/enable-async-entry.mdx +1 -1
- package/docs/zh/guides/advanced-features/eslint.mdx +1 -1
- package/docs/zh/guides/basic-features/alias.mdx +12 -51
- package/docs/zh/guides/basic-features/css.mdx +35 -15
- package/docs/zh/guides/basic-features/data-fetch.mdx +11 -12
- package/docs/zh/guides/basic-features/html.mdx +4 -5
- package/docs/zh/guides/basic-features/routes.mdx +26 -19
- package/docs/zh/guides/get-started/introduction.mdx +20 -0
- package/docs/zh/guides/get-started/quick-start.mdx +8 -17
- package/docs/zh/guides/get-started/tech-stack.mdx +138 -0
- package/docs/zh/guides/get-started/upgrade.mdx +10 -4
- package/docs/zh/guides/topic-detail/changesets/add.mdx +1 -1
- package/docs/zh/guides/topic-detail/changesets/changelog.mdx +3 -3
- package/docs/zh/guides/topic-detail/changesets/commit.mdx +3 -3
- package/docs/zh/guides/topic-detail/changesets/release-note.mdx +3 -3
- package/docs/zh/guides/topic-detail/changesets/release.mdx +1 -1
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +1 -1
- package/docs/zh/guides/topic-detail/framework-plugin/implement.mdx +7 -5
- package/docs/zh/guides/topic-detail/generator/create/use.mdx +0 -8
- package/docs/zh/guides/topic-detail/generator/plugin/context.md +1 -1
- package/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx +45 -21
- package/docs/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +51 -33
- package/docs/zh/guides/topic-detail/micro-frontend/c04-communicate.mdx +1 -0
- package/docs/zh/guides/topic-detail/micro-frontend/c05-mixed-stack.mdx +1 -0
- package/docs/zh/tutorials/first-app/c02-component.mdx +4 -3
- package/package.json +7 -7
@@ -2,6 +2,7 @@
|
|
2
2
|
sidebar_position: 2
|
3
3
|
title: 体验微前端
|
4
4
|
---
|
5
|
+
|
5
6
|
# 体验微前端
|
6
7
|
|
7
8
|
通过本章你可以了解到:
|
@@ -10,7 +11,9 @@ title: 体验微前端
|
|
10
11
|
- 微前端项目开发的基本流程。
|
11
12
|
|
12
13
|
## 创建应用
|
14
|
+
|
13
15
|
目前支持两种路由模式
|
16
|
+
|
14
17
|
- 自控式路由
|
15
18
|
- 约定式路由
|
16
19
|
|
@@ -27,7 +30,7 @@ mkdir masterApp && cd masterApp
|
|
27
30
|
npx @modern-js/create@latest
|
28
31
|
```
|
29
32
|
|
30
|
-
import DefaultMWAGenerate from
|
33
|
+
import DefaultMWAGenerate from '@site-docs/components/default-mwa-generate';
|
31
34
|
|
32
35
|
<DefaultMWAGenerate />
|
33
36
|
|
@@ -40,17 +43,19 @@ import DefaultMWAGenerate from "@site-docs/components/default-mwa-generate";
|
|
40
43
|
|
41
44
|
接下来,让我们注册微前端插件并添加开启微前端主应用,并增加子应用列表:
|
42
45
|
|
43
|
-
import EnableMicroFrontend from
|
46
|
+
import EnableMicroFrontend from '@site-docs/components/enable-micro-frontend';
|
44
47
|
|
45
48
|
<EnableMicroFrontend />
|
46
49
|
|
47
50
|
然后我们在 routes 文件夹下新建两个目录
|
51
|
+
|
48
52
|
- table (用于加载约定式路由子应用)
|
49
53
|
- dashboard (用于加载自控式路由子应用)
|
50
54
|
|
51
55
|
在这两个目录下我们需要新建一个 `$.tsx` 文件作为主应用约定式路由的入口($ 代表模糊匹配,即 `/table` 和 `/table/test` 都会匹配到这个 `$.tsx` 作为该路由的入口文件,这会保证在微前端场景下正确加载子应用路由)
|
52
56
|
|
53
57
|
#### 加载约定式路由子应用
|
58
|
+
|
54
59
|
```js title="src/routes/table/$.tsx"
|
55
60
|
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
|
56
61
|
|
@@ -61,13 +66,14 @@ const Index = () => {
|
|
61
66
|
<div>
|
62
67
|
<Table />
|
63
68
|
</div>
|
64
|
-
)
|
65
|
-
}
|
69
|
+
);
|
70
|
+
};
|
66
71
|
|
67
72
|
export default Index;
|
68
73
|
```
|
69
74
|
|
70
75
|
#### 加载自控式路由子应用
|
76
|
+
|
71
77
|
```js title="src/routes/dashboard/$.tsx"
|
72
78
|
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
|
73
79
|
|
@@ -78,21 +84,30 @@ const Index = () => {
|
|
78
84
|
<div>
|
79
85
|
<Dashboard />
|
80
86
|
</div>
|
81
|
-
)
|
82
|
-
}
|
87
|
+
);
|
88
|
+
};
|
83
89
|
|
84
90
|
export default Index;
|
85
91
|
```
|
92
|
+
|
86
93
|
#### 路由跳转
|
94
|
+
|
87
95
|
此时主应用配置已经完成,通过路由即可加载子应用,修改主应用的 `layout.tsx` 来跳转路由
|
96
|
+
|
88
97
|
```js title="src/route/layout.tsx"
|
89
98
|
import { Outlet, Link } from '@modern-js/runtime/router';
|
90
99
|
|
91
100
|
const Layout = () => (
|
92
101
|
<div>
|
93
|
-
<div
|
94
|
-
|
95
|
-
|
102
|
+
<div>
|
103
|
+
<Link to={'/table'}>加载约定式路由子应用</Link>
|
104
|
+
</div>
|
105
|
+
<div>
|
106
|
+
<Link to={'/dashboard'}>加载自控式路由子应用</Link>
|
107
|
+
</div>
|
108
|
+
<div>
|
109
|
+
<Link to={'/'}>卸载子应用</Link>
|
110
|
+
</div>
|
96
111
|
<Outlet />
|
97
112
|
</div>
|
98
113
|
);
|
@@ -123,8 +138,10 @@ npx @modern-js/create@latest
|
|
123
138
|
<EnableMicroFrontend />
|
124
139
|
|
125
140
|
由于是自控式路由,我们删除掉 `routes` 文件夹并在 `src` 目录下增加 `App.tsx` 文件,此处如果使用的 `非 MApp` 组件,需要通过 `React Router v6` 的 `createBrowserRouter` API 来创建路由
|
141
|
+
|
126
142
|
#### 加载子应用
|
127
|
-
|
143
|
+
|
144
|
+
import CustomRouterMicroFrontend from '@site-docs/components/custom-router-micro-frontend';
|
128
145
|
|
129
146
|
<CustomRouterMicroFrontend />
|
130
147
|
|
@@ -139,7 +156,7 @@ npx @modern-js/create@latest
|
|
139
156
|
|
140
157
|
按照如下选择,生成项目:
|
141
158
|
|
142
|
-
<DefaultMWAGenerate/>
|
159
|
+
<DefaultMWAGenerate />
|
143
160
|
|
144
161
|
我们执行 `pnpm run new` 来开启 `微前端` 功能:
|
145
162
|
|
@@ -156,7 +173,7 @@ import { garfishPlugin } from '@modern-js/plugin-garfish';
|
|
156
173
|
|
157
174
|
export default defineConfig({
|
158
175
|
dev: {
|
159
|
-
port: 8081
|
176
|
+
port: 8081,
|
160
177
|
},
|
161
178
|
runtime: {
|
162
179
|
router: true,
|
@@ -170,12 +187,13 @@ export default defineConfig({
|
|
170
187
|
```
|
171
188
|
|
172
189
|
添加 `src/routes/page.tsx` 代码
|
190
|
+
|
173
191
|
```js title="src/routes/page.tsx"
|
174
192
|
const Index = () => {
|
175
193
|
return (
|
176
194
|
<div className="container-box">subApp: 约定式路由的子应用的根路由</div>
|
177
|
-
)
|
178
|
-
}
|
195
|
+
);
|
196
|
+
};
|
179
197
|
|
180
198
|
export default Index;
|
181
199
|
```
|
@@ -191,7 +209,7 @@ npx @modern-js/create@latest
|
|
191
209
|
|
192
210
|
按照如下选择,生成项目:
|
193
211
|
|
194
|
-
<DefaultMWAGenerate/>
|
212
|
+
<DefaultMWAGenerate />
|
195
213
|
|
196
214
|
我们执行 `pnpm run new` 来开启 `微前端`:
|
197
215
|
|
@@ -208,7 +226,7 @@ import { garfishPlugin } from '@modern-js/plugin-garfish';
|
|
208
226
|
|
209
227
|
export default defineConfig({
|
210
228
|
dev: {
|
211
|
-
port: 8082
|
229
|
+
port: 8082,
|
212
230
|
},
|
213
231
|
runtime: {
|
214
232
|
router: true,
|
@@ -220,6 +238,7 @@ export default defineConfig({
|
|
220
238
|
plugins: [appTools(), garfishPlugin()],
|
221
239
|
});
|
222
240
|
```
|
241
|
+
|
223
242
|
自控式路由需要删除掉 `routes` 文件夹并在 `src` 目录下新建 `App.tsx`
|
224
243
|
|
225
244
|
并在 `src/App.tsx` 添加代码,注意需要从 `props` 中解析并传递 `basename` 给 `BrowserRouter`
|
@@ -227,7 +246,7 @@ export default defineConfig({
|
|
227
246
|
```js title="src/App.tsx"
|
228
247
|
import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
|
229
248
|
|
230
|
-
export default (props: {basename: string}) => {
|
249
|
+
export default (props: { basename: string }) => {
|
231
250
|
const { basename } = props;
|
232
251
|
|
233
252
|
return (
|
@@ -242,7 +261,9 @@ export default (props: {basename: string}) => {
|
|
242
261
|
```
|
243
262
|
|
244
263
|
## 调试
|
264
|
+
|
245
265
|
按顺序在目录执行 `pnpm run dev` 命令启动应用:
|
266
|
+
|
246
267
|
- masterApp 主应用 `http://localhost:8080`
|
247
268
|
- table 子应用(约定式路由) `http://localhost:8081`
|
248
269
|
- dashboard 子应用(自控式路由) `http://localhost:8082`
|
@@ -254,6 +275,7 @@ export default (props: {basename: string}) => {
|
|
254
275
|
## Modern.js 微前端和直接使用 Garfish 的区别
|
255
276
|
|
256
277
|
使用纯 `Garfish` API 开发微前端应用时
|
278
|
+
|
257
279
|
- 主应用:
|
258
280
|
- 安装 Garfish 依赖并使用 `Garfish.run` 注册子应用 [参考](https://www.garfishjs.org/api/run)
|
259
281
|
- 提供一个常驻的 `DOM` 节点供子应用挂载 [参考](https://www.garfishjs.org/api/registerApp#domgetter)
|
@@ -264,6 +286,7 @@ export default (props: {basename: string}) => {
|
|
264
286
|
区别于直接使用 `Garfish` 运行时 API 开发微前端项目,`Modern.js` 的微前端方案更加开箱即用。
|
265
287
|
使用 `pnpm new` 启用微前端模式后会自动在 `Modern.js` 应用中集成 `Garfish` 插件,在 `Garfish`
|
266
288
|
插件的加持下,你只需要
|
289
|
+
|
267
290
|
- 主应用:
|
268
291
|
- 配置 `runtime.masterApp.apps` 参数注册子应用
|
269
292
|
- 使用 `useModuleApps` API 获取子应用实例并在组件中完成渲染
|
@@ -271,10 +294,11 @@ export default (props: {basename: string}) => {
|
|
271
294
|
- 配置 `deploy.microFrontend`
|
272
295
|
|
273
296
|
所以插件中为你做了如下事情
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
297
|
+
|
298
|
+
- 帮助你通过 `Garfish` 运行时 API 自动注册子应用(主应用)
|
299
|
+
- `useModulesApps` 函数的返回值提供了一个常驻的 `DOM` 节点供子应用挂载(主应用)
|
300
|
+
- 帮助你正确导出了 `provider`(子应用)
|
301
|
+
- 帮助你正确设置了 `basename` 给 `Modern.js` 运行时提供 `Router` 实例,如果是`自控式路由`或`手动引入的 react-router-dom` 那么需要从 `App.tsx` 的 `props` 中获取 `basename` 手动传递给引入的 `Router 实例`(子应用)
|
278
302
|
|
279
303
|
## 常见问题
|
280
304
|
|
@@ -2,13 +2,14 @@
|
|
2
2
|
sidebar_position: 3
|
3
3
|
title: 开发主应用
|
4
4
|
---
|
5
|
+
|
5
6
|
# 开发主应用
|
6
7
|
|
7
8
|
在上一章 [体验微前端](/guides/topic-detail/micro-frontend/c02-development) 通过一个示例演示了如何创建和配置微前端子应用,通过本章你可以进一步了解如何开发主应用,以及它的常见配置。
|
8
9
|
|
9
|
-
在通过 `@modern-js/create`
|
10
|
+
在通过 `@modern-js/create` 命令创建 Modern.js 工程后,可以在项目中执行 `pnpm run new`(实际执行了 `modern new` 命令),在选择了「微前端」模式后,会安装微前端依赖依赖,只需手动注册插件即可。
|
10
11
|
|
11
|
-
import EnableMicroFrontend from
|
12
|
+
import EnableMicroFrontend from '@site-docs/components/enable-micro-frontend';
|
12
13
|
|
13
14
|
<EnableMicroFrontend />
|
14
15
|
|
@@ -26,7 +27,7 @@ import EnableMicroFrontend from "@site-docs/components/enable-micro-frontend";
|
|
26
27
|
|
27
28
|
:::
|
28
29
|
|
29
|
-
import MicroRuntimeConfig from
|
30
|
+
import MicroRuntimeConfig from '@site-docs/components/micro-runtime-config';
|
30
31
|
|
31
32
|
<MicroRuntimeConfig />
|
32
33
|
|
@@ -40,15 +41,18 @@ defineConfig(App, {
|
|
40
41
|
manifest: {
|
41
42
|
getAppList: async () => {
|
42
43
|
// 可以从其他远程接口获取
|
43
|
-
return [
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
return [
|
45
|
+
{
|
46
|
+
name: 'Table',
|
47
|
+
entry: 'http://localhost:8001',
|
48
|
+
// activeWhen: '/table'
|
49
|
+
},
|
50
|
+
{
|
51
|
+
name: 'Dashboard',
|
52
|
+
entry: 'http://localhost:8002',
|
53
|
+
// activeWhen: '/dashboard'
|
54
|
+
},
|
55
|
+
];
|
52
56
|
},
|
53
57
|
},
|
54
58
|
},
|
@@ -77,16 +81,30 @@ defineConfig(App, {
|
|
77
81
|
```js title="App.tsx"
|
78
82
|
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
|
79
83
|
|
80
|
-
import {
|
84
|
+
import {
|
85
|
+
RouterProvider,
|
86
|
+
Route,
|
87
|
+
createBrowserRouter,
|
88
|
+
createRoutesFromElements,
|
89
|
+
BrowserRouter,
|
90
|
+
Link,
|
91
|
+
Outlet,
|
92
|
+
} from '@modern-js/runtime/router';
|
81
93
|
|
82
94
|
const AppLayout = () => (
|
83
95
|
<>
|
84
|
-
<div
|
85
|
-
|
86
|
-
|
96
|
+
<div>
|
97
|
+
<Link to={'/table'}>加载约定式路由子应用</Link>
|
98
|
+
</div>
|
99
|
+
<div>
|
100
|
+
<Link to={'/dashboard'}>加载自控式路由子应用</Link>
|
101
|
+
</div>
|
102
|
+
<div>
|
103
|
+
<Link to={'/'}>卸载子应用</Link>
|
104
|
+
</div>
|
87
105
|
<Outlet />
|
88
106
|
</>
|
89
|
-
)
|
107
|
+
);
|
90
108
|
|
91
109
|
export default () => {
|
92
110
|
const { apps, MApp } = useModuleApps();
|
@@ -103,25 +121,25 @@ export default () => {
|
|
103
121
|
key={app.name}
|
104
122
|
path={`${app.name.toLowerCase()}/*`}
|
105
123
|
element={
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
124
|
+
<Component
|
125
|
+
loadable={{
|
126
|
+
loading: ({ pastDelay, error }: any) => {
|
127
|
+
if (error) {
|
128
|
+
return <div>error: {error?.message}</div>;
|
129
|
+
} else if (pastDelay) {
|
130
|
+
return <div>loading</div>;
|
131
|
+
} else {
|
132
|
+
return null;
|
133
|
+
}
|
134
|
+
},
|
135
|
+
}}
|
136
|
+
/>
|
119
137
|
}
|
120
138
|
/>
|
121
|
-
)
|
139
|
+
);
|
122
140
|
})}
|
123
|
-
</Route
|
124
|
-
)
|
141
|
+
</Route>,
|
142
|
+
),
|
125
143
|
);
|
126
144
|
|
127
145
|
return (
|
@@ -1,6 +1,7 @@
|
|
1
1
|
---
|
2
2
|
title: 编写 UI 组件
|
3
3
|
---
|
4
|
+
|
4
5
|
# 编写 UI 组件
|
5
6
|
|
6
7
|
上一章节中,我们学习了如何初始化项目,并使用配置修改 Modern.js 的默认行为。
|
@@ -9,9 +10,9 @@ title: 编写 UI 组件
|
|
9
10
|
|
10
11
|
为了做更好的 UI 展示和交互,我们引入组件库 [Antd](https://ant.design/index-cn) 来开发,使用 `<List>` 组件来代替原始的列表。先添加依赖:
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
import { PackageManagerTabs } from '@theme';
|
14
|
+
|
15
|
+
<PackageManagerTabs command="add antd" />
|
15
16
|
|
16
17
|
修改 `src/routes/page.tsx`,在顶部导入组件:
|
17
18
|
|
package/package.json
CHANGED
@@ -15,17 +15,17 @@
|
|
15
15
|
"modern",
|
16
16
|
"modern.js"
|
17
17
|
],
|
18
|
-
"version": "2.
|
18
|
+
"version": "2.35.1",
|
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.
|
25
|
+
"@modern-js/sandpack-react": "2.35.1"
|
26
26
|
},
|
27
27
|
"peerDependencies": {
|
28
|
-
"@modern-js/builder-doc": "^2.
|
28
|
+
"@modern-js/builder-doc": "^2.35.1"
|
29
29
|
},
|
30
30
|
"devDependencies": {
|
31
31
|
"classnames": "^2",
|
@@ -35,12 +35,12 @@
|
|
35
35
|
"ts-node": "^10.9.1",
|
36
36
|
"typescript": "^5",
|
37
37
|
"fs-extra": "^10",
|
38
|
-
"rspress": "0.0.
|
39
|
-
"@rspress/shared": "0.0.
|
38
|
+
"rspress": "0.0.13",
|
39
|
+
"@rspress/shared": "0.0.13",
|
40
40
|
"@types/node": "^16",
|
41
41
|
"@types/fs-extra": "^9",
|
42
|
-
"@modern-js/builder-doc": "2.
|
43
|
-
"@modern-js/doc-plugin-auto-sidebar": "2.
|
42
|
+
"@modern-js/builder-doc": "2.35.1",
|
43
|
+
"@modern-js/doc-plugin-auto-sidebar": "2.35.1"
|
44
44
|
},
|
45
45
|
"scripts": {
|
46
46
|
"dev": "rspress dev",
|