@modern-js/main-doc 2.5.0 → 2.7.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/apis/app/commands.mdx +297 -0
- package/en/apis/app/hooks/_category_.json +1 -1
- package/en/apis/app/hooks/config/upload.mdx +10 -0
- package/en/apis/app/hooks/src/routes.mdx +2 -2
- package/en/components/init-app.mdx +5 -5
- package/en/configure/app/bff/prefix.mdx +2 -3
- package/en/configure/app/bff/proxy.mdx +1 -1
- package/en/configure/app/dev/before-start-url.mdx +13 -0
- package/en/configure/app/dev/host.mdx +13 -0
- package/en/configure/app/output/ssg.mdx +3 -3
- package/en/configure/app/runtime/master-app.mdx +1 -1
- package/en/configure/app/server/ssr.mdx +18 -0
- package/en/configure/app/source/entries-dir.mdx +1 -1
- package/en/configure/app/testing/transformer.mdx +1 -1
- package/en/configure/app/tools/jest.mdx +1 -1
- package/en/guides/advanced-features/rspack-start.mdx +69 -0
- package/en/guides/advanced-features/ssg.mdx +8 -8
- package/en/guides/advanced-features/ssr.mdx +210 -5
- package/en/guides/basic-features/alias.mdx +4 -4
- package/en/guides/{css/tailwindcss.mdx → basic-features/css.mdx} +60 -3
- package/en/guides/basic-features/data-fetch.mdx +4 -4
- package/en/guides/basic-features/env-vars.mdx +4 -0
- package/en/guides/basic-features/routes.mdx +23 -7
- package/en/guides/concept/builder.mdx +1 -1
- package/en/guides/get-started/quick-start.mdx +2 -2
- package/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +1 -1
- package/en/tutorials/first-app/c03-css.mdx +1 -1
- package/en/tutorials/first-app/c07-container.mdx +17 -17
- package/en/tutorials/first-app/c08-entries.mdx +23 -23
- package/package.json +3 -3
- package/scripts/summary.en.json +1 -1
- package/scripts/summary.zh.json +1 -1
- package/zh/apis/app/commands.mdx +299 -0
- package/zh/apis/app/hooks/_category_.json +1 -1
- package/zh/apis/app/hooks/config/upload.mdx +12 -2
- package/zh/apis/app/hooks/src/routes.mdx +2 -2
- package/zh/components/init-app.mdx +5 -5
- package/zh/configure/app/bff/prefix.mdx +1 -1
- package/zh/configure/app/bff/proxy.mdx +1 -1
- package/zh/configure/app/dev/before-start-url.mdx +13 -0
- package/zh/configure/app/dev/host.mdx +13 -0
- package/zh/configure/app/output/ssg.mdx +3 -3
- package/zh/configure/app/server/ssr.mdx +19 -1
- package/zh/configure/app/source/entries-dir.mdx +1 -1
- package/zh/guides/advanced-features/rspack-start.mdx +69 -0
- package/zh/guides/advanced-features/ssg.mdx +8 -8
- package/zh/guides/advanced-features/ssr.mdx +213 -6
- package/zh/guides/basic-features/alias.mdx +4 -4
- package/zh/guides/{css/tailwindcss.mdx → basic-features/css.mdx} +60 -3
- package/zh/guides/basic-features/data-fetch.mdx +4 -4
- package/zh/guides/basic-features/env-vars.mdx +4 -0
- package/zh/guides/basic-features/routes.mdx +23 -7
- package/zh/guides/concept/builder.mdx +2 -2
- package/zh/guides/get-started/quick-start.mdx +2 -2
- package/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +1 -1
- package/zh/tutorials/first-app/c03-css.mdx +1 -1
- package/zh/tutorials/first-app/c07-container.mdx +17 -17
- package/zh/tutorials/first-app/c08-entries.mdx +23 -23
- package/en/apis/app/commands/_category_.json +0 -5
- package/en/apis/app/commands/build.mdx +0 -39
- package/en/apis/app/commands/dev.mdx +0 -61
- package/en/apis/app/commands/inspect.mdx +0 -61
- package/en/apis/app/commands/lint.mdx +0 -19
- package/en/apis/app/commands/new.mdx +0 -55
- package/en/apis/app/commands/serve.mdx +0 -27
- package/en/apis/app/commands/test.mdx +0 -35
- package/en/apis/app/commands/upgrade.mdx +0 -18
- package/en/guides/css/_category_.json +0 -5
- package/en/guides/css/css-in-js.mdx +0 -40
- package/en/guides/css/css-modules.mdx +0 -87
- package/en/guides/css/less-sass.mdx +0 -17
- package/en/guides/css/postcss.mdx +0 -79
- package/zh/apis/app/commands/_category_.json +0 -5
- package/zh/apis/app/commands/build.mdx +0 -39
- package/zh/apis/app/commands/dev.mdx +0 -61
- package/zh/apis/app/commands/inspect.mdx +0 -61
- package/zh/apis/app/commands/lint.mdx +0 -19
- package/zh/apis/app/commands/new.mdx +0 -54
- package/zh/apis/app/commands/serve.mdx +0 -27
- package/zh/apis/app/commands/test.mdx +0 -35
- package/zh/apis/app/commands/upgrade.mdx +0 -18
- package/zh/guides/css/_category_.json +0 -5
- package/zh/guides/css/css-in-js.mdx +0 -40
- package/zh/guides/css/css-modules.mdx +0 -87
- package/zh/guides/css/less-sass.mdx +0 -17
- package/zh/guides/css/postcss.mdx +0 -80
@@ -20,8 +20,8 @@ sidebar_position: 3
|
|
20
20
|
|
21
21
|
Modern.js 中提供了 Data Loader,方便开发者在 SSR、CSR 下同构的获取数据。每个路由模块,如 `layout.tsx` 和 `page.tsx` 都可以定义自己的 Data Loader:
|
22
22
|
|
23
|
-
```ts title="src/routes/page.
|
24
|
-
export
|
23
|
+
```ts title="src/routes/page.loader.ts"
|
24
|
+
export default () => {
|
25
25
|
return {
|
26
26
|
message: 'Hello World',
|
27
27
|
};
|
@@ -31,6 +31,7 @@ export const loader = () => {
|
|
31
31
|
在组件中可以通过 Hooks API 的方式获取 `loader` 函数返回的数据:
|
32
32
|
|
33
33
|
```tsx
|
34
|
+
import { useLoaderData } from '@modern-js/runtime/router'
|
34
35
|
export default () => {
|
35
36
|
const data = useLoaderData();
|
36
37
|
return <div>{data.message}</div>;
|
@@ -42,10 +43,13 @@ Modern.js 打破传统的 SSR 开发模式,提供了用户无感的 SSR 开发
|
|
42
43
|
不过,开发者仍然需要关注数据的兜底处理,例如 `null` 值或不符合预期的数据返回。避免在 SSR 时产生 React 渲染错误或是返回凌乱的渲染结果。
|
43
44
|
|
44
45
|
:::info 补充信息
|
45
|
-
|
46
|
+
1. 当以客户端路由的方式请求页面时,Modern.js 会发送一个 HTTP 请求,服务端接收到请求后执行页面对应的 Data Loader 函数,然后将执行结果作为请求的响应返回浏览器。
|
46
47
|
|
48
|
+
2. 使用 Data Loader 时,数据获取发生在渲染前,Modern.js 也仍然支持在组件渲染时获取数据。更多相关内容可以查看[数据获取](/guides/basic-features/data-fetch)。
|
47
49
|
:::
|
48
50
|
|
51
|
+
|
52
|
+
|
49
53
|
## 保持渲染一致
|
50
54
|
|
51
55
|
有些业务中,通常需要根据当前的运行容器环境特征做不同的 UI 展示,例如 [UA](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) 信息。如果处理不够仔细,此时很有可能出现不符合预期的渲染结果。
|
@@ -276,7 +280,7 @@ export const loader = () => {
|
|
276
280
|
|
277
281
|
## 流式渲染
|
278
282
|
|
279
|
-
Modern.js 支持了 React 18
|
283
|
+
Modern.js 支持了 React 18 的流式渲染,可以通过如下配置启用:
|
280
284
|
|
281
285
|
```json
|
282
286
|
{
|
@@ -288,7 +292,210 @@ Modern.js 支持了 React 18 的流式渲染,可以通过如下配置修改默
|
|
288
292
|
}
|
289
293
|
```
|
290
294
|
|
291
|
-
|
292
|
-
|
295
|
+
Modern.js 的流式渲染基于 React Router 实现,主要涉及 API 有:
|
296
|
+
|
297
|
+
- [`defer`](https://reactrouter.com/en/main/utils/defer):在 Data Loader 中使用,用于支持异步获取数据。
|
298
|
+
- [`Await`](https://reactrouter.com/en/main/components/await):用于渲染 Data Loader 返回的异步数据。
|
299
|
+
- [`useAsyncValue`](https://reactrouter.com/en/main/hooks/use-async-value):用于从最近的父级 `Await` 组件中获取数据。
|
300
|
+
|
301
|
+
|
302
|
+
### 异步获取数据
|
303
|
+
|
304
|
+
```ts title='page.loader.ts'
|
305
|
+
import { defer, type LoaderFunctionArgs } from '@modern-js/runtime/router';
|
306
|
+
|
307
|
+
interface User {
|
308
|
+
name: string;
|
309
|
+
age: number;
|
310
|
+
}
|
311
|
+
|
312
|
+
export interface Data {
|
313
|
+
data: User;
|
314
|
+
}
|
315
|
+
|
316
|
+
export default ({ params }: LoaderFunctionArgs) => {
|
317
|
+
const userId = params.id;
|
318
|
+
|
319
|
+
const user = new Promise<User>(resolve => {
|
320
|
+
setTimeout(() => {
|
321
|
+
resolve({
|
322
|
+
name: `user-${userId}`,
|
323
|
+
age: 18,
|
324
|
+
});
|
325
|
+
}, 200);
|
326
|
+
});
|
327
|
+
|
328
|
+
return defer({ data: user });
|
329
|
+
};
|
330
|
+
|
331
|
+
```
|
332
|
+
|
333
|
+
`user` 是一个 Promise 类型的对象,表示需要异步获取的数据,通过 `defer` 处理需要异步获取的 `user`。注意,`defer` 必须接收一个对象类型的参数,
|
334
|
+
因此, 传入 `defer` 的参数为 `{data: user}`。
|
335
|
+
|
336
|
+
`defer` 还可以同时接收异步数据和同步数据。例如:
|
337
|
+
|
338
|
+
```ts title='page.loader.ts'
|
339
|
+
|
340
|
+
// 省略部分代码
|
341
|
+
|
342
|
+
export default ({ params }: LoaderFunctionArgs) => {
|
343
|
+
const userId = params.id;
|
344
|
+
|
345
|
+
const user = new Promise<User>(resolve => {
|
346
|
+
setTimeout(() => {
|
347
|
+
resolve({
|
348
|
+
name: `user-${userId}`,
|
349
|
+
age: 18,
|
350
|
+
});
|
351
|
+
}, 200);
|
352
|
+
});
|
353
|
+
|
354
|
+
const otherData = new Promise<string>(resolve => {
|
355
|
+
setTimeout(() => {
|
356
|
+
resolve('some sync data');
|
357
|
+
}, 200);
|
358
|
+
});
|
359
|
+
|
360
|
+
return defer({
|
361
|
+
data: user,
|
362
|
+
other: await otherData
|
363
|
+
});
|
364
|
+
};
|
365
|
+
|
366
|
+
```
|
367
|
+
|
368
|
+
`otherData` 前加了 `await`,所以是同步获取的数据,它可以和异步获取的数据 `user` 同时传入 `defer`。
|
369
|
+
|
370
|
+
|
371
|
+
### 渲染异步数据
|
372
|
+
|
373
|
+
通过 `Await` 组件,可以获取到 Data Loader 中异步返回的数据,然后进行渲染。例如:
|
374
|
+
|
375
|
+
```ts title='page.tsx'
|
376
|
+
import { Await, useLoaderData } from '@modern-js/runtime/router';
|
377
|
+
import { Suspense } from 'react';
|
378
|
+
import type { Data } from './page.loader';
|
379
|
+
|
380
|
+
const Page = () => {
|
381
|
+
const data = useLoaderData() as Data;
|
382
|
+
|
383
|
+
return (
|
384
|
+
<div>
|
385
|
+
User info:
|
386
|
+
<Suspense fallback={<div id="loading">loading user data ...</div>}>
|
387
|
+
<Await resolve={data.data}>
|
388
|
+
{(user) => {
|
389
|
+
return (
|
390
|
+
<div id="data">
|
391
|
+
name: {user.name}, age: {user.age}
|
392
|
+
</div>
|
393
|
+
);
|
394
|
+
}}
|
395
|
+
</Await>
|
396
|
+
</Suspense>
|
397
|
+
</div>
|
398
|
+
);
|
399
|
+
};
|
400
|
+
|
401
|
+
export default Page;
|
402
|
+
```
|
403
|
+
|
404
|
+
`Await` 需要包裹在 `Suspense` 组件内部,`Await` 的 `resolve` 传入的是 Data Loader 异步获取的数据,当数据获取完成后,
|
405
|
+
通过 [Render Props](https://reactjs.org/docs/render-props.html) 模式,渲染获取到的数据。在数据的获取阶段,将展示
|
406
|
+
`Suspense` 组件 `fallback` 属性设置的内容。
|
407
|
+
|
408
|
+
:::warning 注意
|
409
|
+
从 Data Loader 文件导入类型时,需要使用 import type 语法,保证只导入类型信息,这样可以避免 Data Loader 的代码打包到前端产物的 bundle 文件中。
|
410
|
+
|
411
|
+
所以,这里的导入方式为:`import type { Data } from './page.loader'`;
|
412
|
+
:::
|
413
|
+
|
414
|
+
也可以通过 `useAsyncValue` 获取 Data Loader 返回的异步数据。例如:
|
415
|
+
|
416
|
+
```
|
417
|
+
```ts title='page.tsx'
|
418
|
+
import { useAsyncValue } from '@modern-js/runtime/router';
|
419
|
+
|
420
|
+
// 省略部分代码
|
421
|
+
|
422
|
+
const UserInfo = () => {
|
423
|
+
const user = useAsyncValue();
|
424
|
+
|
425
|
+
return (
|
426
|
+
<div>
|
427
|
+
name: {user.name}, age: {user.age}
|
428
|
+
</div>
|
429
|
+
)
|
430
|
+
}
|
431
|
+
|
432
|
+
const Page = () => {
|
433
|
+
const data = useLoaderData() as Data;
|
434
|
+
|
435
|
+
return (
|
436
|
+
<div>
|
437
|
+
User info:
|
438
|
+
<Suspense fallback={<div id="loading">loading user data ...</div>}>
|
439
|
+
<Await resolve={data.data}>
|
440
|
+
<UserInfo />
|
441
|
+
</Await>
|
442
|
+
</Suspense>
|
443
|
+
</div>
|
444
|
+
);
|
445
|
+
};
|
446
|
+
|
447
|
+
export default Page;
|
448
|
+
```
|
449
|
+
|
450
|
+
### 错误处理
|
293
451
|
|
452
|
+
`Await` 组件的 `errorElement` 属性,可以用来处理当 Data Loader 执行时,或者子组件渲染时抛出的错误。
|
453
|
+
例如,我们故意在 Data Loader 函数中抛出错误:
|
454
|
+
|
455
|
+
```ts title='page.loader.ts'
|
456
|
+
import { defer } from '@modern-js/runtime/router';
|
457
|
+
|
458
|
+
export default () => {
|
459
|
+
const data = new Promise((resolve, reject) => {
|
460
|
+
setTimeout(() => {
|
461
|
+
reject(new Error('error occurs'));
|
462
|
+
}, 200);
|
463
|
+
});
|
464
|
+
|
465
|
+
return defer({ data });
|
466
|
+
};
|
467
|
+
```
|
468
|
+
|
469
|
+
然后通过 `useAsyncError` 获取错误,并将用于渲染错误信息的组件赋值给 `Await` 组件的 `errorElement` 属性:
|
470
|
+
|
471
|
+
```ts title='page.ts'
|
472
|
+
import { Await, useAsyncError, useLoaderData } from '@modern-js/runtime/router';
|
473
|
+
import { Suspense } from 'react';
|
474
|
+
|
475
|
+
export default function Page() {
|
476
|
+
const data = useLoaderData();
|
477
|
+
|
478
|
+
return (
|
479
|
+
<div>
|
480
|
+
Error page
|
481
|
+
<Suspense fallback={<div>loading ...</div>}>
|
482
|
+
<Await resolve={data.data} errorElement={<ErrorElement />}>
|
483
|
+
{(data: any) => {
|
484
|
+
return <div>never displayed</div>;
|
485
|
+
}}
|
486
|
+
</Await>
|
487
|
+
</Suspense>
|
488
|
+
</div>
|
489
|
+
);
|
490
|
+
}
|
491
|
+
|
492
|
+
function ErrorElement() {
|
493
|
+
const error = useAsyncError() as Error;
|
494
|
+
return <p>Something went wrong! {error.message}</p>;
|
495
|
+
}
|
496
|
+
```
|
497
|
+
|
498
|
+
:::info 补充信息
|
499
|
+
1. [Deferred Data](https://reactrouter.com/en/main/guides/deferred)
|
500
|
+
2. [New Suspense SSR Architecture in React 18](https://github.com/reactwg/react-18/discussions/37)
|
294
501
|
:::
|
@@ -2,7 +2,64 @@
|
|
2
2
|
sidebar_position: 2
|
3
3
|
---
|
4
4
|
|
5
|
-
#
|
5
|
+
# CSS 开发方案
|
6
|
+
|
7
|
+
Modern.js 内置多种常用的 CSS 开发方案,包括 Less / Sass / Stylus 预处理器、PostCSS、CSS Modules、CSS-in-JS 和 Tailwind CSS。
|
8
|
+
|
9
|
+
## 使用 Less、Sass 和 Stylus
|
10
|
+
|
11
|
+
Modern.js 内置了社区流行的 CSS 预处理器,包括 Less 和 Sass。
|
12
|
+
|
13
|
+
默认情况下,你不需要对 Less 和 Sass 进行任何配置。如果你有自定义 loader 配置的需求,可以通过配置 [tools.less](/configure/app/tools/less)、[tools.sass](/configure/app/tools/sass) 来进行设置。
|
14
|
+
|
15
|
+
你也可以在 Modern.js 中使用 Stylus,只需要安装 Modern.js Builder 提供的 Stylus 插件即可,使用方式请参考 [Stylus 插件](https://modernjs.dev/builder/plugins/plugin-stylus.html)。
|
16
|
+
|
17
|
+
## 使用 PostCSS
|
18
|
+
|
19
|
+
Modern.js 内置了 [PostCSS](https://postcss.org/) 来转换 CSS 代码。
|
20
|
+
|
21
|
+
请阅读 [Modern.js Builder - 使用 PostCSS](https://modernjs.dev/builder/guide/basic/css-usage.html#%E4%BD%BF%E7%94%A8-postcss) 了解更多用法。
|
22
|
+
|
23
|
+
## 使用 CSS Modules
|
24
|
+
|
25
|
+
请阅读 [使用 CSS Modules](https://modernjs.dev/builder/guide/basic/css-modules.html) 章节来了解 CSS Modules 的完整用法。
|
26
|
+
|
27
|
+
## 使用 CSS-in-JS
|
28
|
+
|
29
|
+
CSS-in-JS 是一种可以将 CSS 样式写在 JS 文件里的技术。
|
30
|
+
|
31
|
+
Modern.js 集成了社区常用的 CSS-in-JS 实现库 [styled-components](https://styled-components.com/),它使用 JavaScript 的新特性 [Tagged template](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) 编写组件的 CSS 样式。可以直接从 `@modern-js/runtime/styled` 引入 [styled-components](https://styled-components.com/) 的 API 进行使用。
|
32
|
+
|
33
|
+
当需要编写一个内部字体为红色的 `div` 组件时,可以如下实现:
|
34
|
+
|
35
|
+
```js
|
36
|
+
import styled from '@modern-js/runtime/styled';
|
37
|
+
|
38
|
+
const RedDiv = styled.div`
|
39
|
+
color: red;
|
40
|
+
`;
|
41
|
+
```
|
42
|
+
|
43
|
+
当需要根据组件的 `props` 动态设置组件样式时,例如 `props` 的属性 `primary` 为 `true` 时,按钮的颜色为白色,其他情况为红色,实现代码如下:
|
44
|
+
|
45
|
+
```js
|
46
|
+
import styled from '@modern-js/runtime/styled';
|
47
|
+
|
48
|
+
const Button = styled.button`
|
49
|
+
color: ${props => (props.primary ? 'white' : 'red')};
|
50
|
+
font-size: 1em;
|
51
|
+
`;
|
52
|
+
```
|
53
|
+
|
54
|
+
关于 styled-components 的更多用法,请参考 [styled-components 官网](https://styled-components.com/)。
|
55
|
+
|
56
|
+
Modern.js 内部集成了 Babel 的 [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) 插件,你可以通过 [tools.styledComponents](/configure/app/tools/styled-components) 对插件进行配置。
|
57
|
+
|
58
|
+
:::tip 提示
|
59
|
+
如果需要使用 [styled-jsx](https://www.npmjs.com/package/styled-jsx)、[Emotion](https://emotion.sh/) 等其他 CSS-in-JS 库,需要先安装对应库的依赖。具体使用方式请参考对应库的官网。
|
60
|
+
:::
|
61
|
+
|
62
|
+
## 使用 Tailwind CSS
|
6
63
|
|
7
64
|
[Tailwind CSS](https://tailwindcss.com/) 是一个以 Utility Class 为基础的 CSS 框架和设计系统,可以快速地为组件添加常用样式,同时支持主题样式的灵活扩展。在 Modern.js 中使用 [Tailwind CSS](https://tailwindcss.com/),只需要在项目根目录下执行 `pnpm run new` 并开启。
|
8
65
|
|
@@ -46,7 +103,7 @@ const App = () => (
|
|
46
103
|
|
47
104
|
:::
|
48
105
|
|
49
|
-
|
106
|
+
### Tailwind CSS 版本
|
50
107
|
|
51
108
|
Modern.js 同时支持 Tailwind CSS v2 和 v3 版本,框架会识别项目 `package.json` 中的 `tailwindcss` 依赖版本,并启用相应的配置。默认情况下,我们会为你安装 Tailwind CSS v3 版本。
|
52
109
|
|
@@ -64,7 +121,7 @@ Tailwind CSS v2 和 v3 均不支持 IE 11 浏览器,相关背景请参考:
|
|
64
121
|
|
65
122
|
如果你在 IE 11 浏览器上使用 Tailwind CSS,可能会出现部分样式不可用的现象,请谨慎使用。
|
66
123
|
|
67
|
-
|
124
|
+
### Theme 配置
|
68
125
|
|
69
126
|
当需要自定义 Tailwind CSS 的 [theme](https://tailwindcss.com/docs/theme) 配置的时候,可以在配置 [`source.designSystem`](/configure/app/source/design-system) 中修改,例如,颜色主题中增加一个 `primary`:
|
70
127
|
|
@@ -82,9 +82,9 @@ export default async (): Promise<ProfileData> => {
|
|
82
82
|
|
83
83
|
```tsx
|
84
84
|
// routes/user/[id]/page.loader.ts
|
85
|
-
import {
|
85
|
+
import { LoaderFunctionArgs } from '@modern-js/runtime/router';
|
86
86
|
|
87
|
-
export default async ({ params }:
|
87
|
+
export default async ({ params }: LoaderFunctionArgs) => {
|
88
88
|
const { id } = params;
|
89
89
|
const res = await fetch(`https://api/user/${id}`);
|
90
90
|
return res.json();
|
@@ -101,9 +101,9 @@ export default async ({ params }: LoaderArgs) => {
|
|
101
101
|
|
102
102
|
```tsx
|
103
103
|
// routes/user/[id]/page.loader.ts
|
104
|
-
import {
|
104
|
+
import { LoaderFunctionArgs } from '@modern-js/runtime/router';
|
105
105
|
|
106
|
-
export default async ({ request }:
|
106
|
+
export default async ({ request }: LoaderFunctionArgs) => {
|
107
107
|
const url = new URL(request.url);
|
108
108
|
const userId = url.searchParams.get('id');
|
109
109
|
return queryUser(userId);
|
@@ -109,7 +109,7 @@ export default () => {
|
|
109
109
|
.
|
110
110
|
└── routes
|
111
111
|
├── blog
|
112
|
-
│
|
112
|
+
│ └── page.tsx
|
113
113
|
├── layout.tsx
|
114
114
|
├── page.tsx
|
115
115
|
└── user
|
@@ -156,9 +156,9 @@ export default () => {
|
|
156
156
|
```
|
157
157
|
└── routes
|
158
158
|
├── [id]
|
159
|
-
│
|
159
|
+
│ └── page.tsx
|
160
160
|
├── blog
|
161
|
-
│
|
161
|
+
│ └── page.tsx
|
162
162
|
└── page.tsx
|
163
163
|
```
|
164
164
|
|
@@ -181,7 +181,7 @@ export default () => {
|
|
181
181
|
└── routes
|
182
182
|
├── $.tsx
|
183
183
|
├── blog
|
184
|
-
│
|
184
|
+
│ └── page.tsx
|
185
185
|
└── page.tsx
|
186
186
|
```
|
187
187
|
|
@@ -248,9 +248,9 @@ Modern.js 会生成 `/login` 和 `/sign` 两条路由,`__auth/layout.tsx` 组
|
|
248
248
|
.
|
249
249
|
└── routes
|
250
250
|
├── blog
|
251
|
-
│
|
252
|
-
│
|
253
|
-
│
|
251
|
+
│ ├── [id]
|
252
|
+
│ │ └── page.tsx
|
253
|
+
│ └── page.tsx
|
254
254
|
├── layout.tsx
|
255
255
|
├── loading.tsx
|
256
256
|
└── page.tsx
|
@@ -292,6 +292,22 @@ Modern.js 建议必须有根 layout 和根 loading。
|
|
292
292
|
|
293
293
|
同理,当路由从 `/` 或者 `/blog` 跳转到 `/blog/123` 时,如果 `blog/[id]/page` 组件的 JS Chunk 还未加载,也会先展示 `loading.tsx` 中导出的组件 UI。
|
294
294
|
|
295
|
+
### 路由重定向
|
296
|
+
|
297
|
+
可以通过创建 [`data loader`](/guides/basic-features/data-fetch) 文件做路由的重定向,如有文件 `routes/user/page.tsx`,想对这个文件对应的路由做重定向,可以创建 `routes/user/page.loader.ts` 文件:
|
298
|
+
|
299
|
+
```ts title="routes/user/page.loader.ts"
|
300
|
+
import { redirect } from "@edenx/runtime/router"
|
301
|
+
|
302
|
+
export default () => {
|
303
|
+
const user = await getUser();
|
304
|
+
if(!user){
|
305
|
+
return redirect('/login');
|
306
|
+
}
|
307
|
+
return null;
|
308
|
+
}
|
309
|
+
```
|
310
|
+
|
295
311
|
### 错误处理
|
296
312
|
|
297
313
|
`routes/` 下每一层目录中,开发者同样可以定义一个 `error.tsx` 文件,默认导出一个 `<ErrorBoundary>` 组件。
|
@@ -6,7 +6,7 @@ sidebar_position: 2
|
|
6
6
|
|
7
7
|
**Modern.js 的构建能力由 [Modern.js Builder](https://modernjs.dev/builder) 提供。**
|
8
8
|
|
9
|
-
Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向 Web 开发场景的构建引擎,可以脱离 Modern.js 被独立使用。Modern.js Builder 同时支持 webpack 和
|
9
|
+
Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向 Web 开发场景的构建引擎,可以脱离 Modern.js 被独立使用。Modern.js Builder 同时支持 webpack 和 rspack 等多种打包工具,默认情况下使用最成熟的 webpack 进行打包。
|
10
10
|
|
11
11
|
## 构建架构
|
12
12
|
|
@@ -14,7 +14,7 @@ Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向
|
|
14
14
|
|
15
15
|
- 上层研发框架:Modern.js。
|
16
16
|
- 通用构建引擎:Modern.js Builder。
|
17
|
-
- 底层打包工具:webpack 和
|
17
|
+
- 底层打包工具:webpack 和 rspack。
|
18
18
|
|
19
19
|
<img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/zq-uylkvT/ljhwZthlaukjlkulzlp/builder-layers-1117.png" style={{ maxWidth: '540px' }} />
|
20
20
|
|
@@ -149,7 +149,7 @@ export default () => {
|
|
149
149
|
然后在主应用中使用 `useModuleApp` 方法获取 `MApp` 组件, 并在主应用渲染 `MApp`。
|
150
150
|
|
151
151
|
```tsx title=主应用:App.tsx
|
152
|
-
import { useModuleApp } from '@modern-js/plugin-runtime';
|
152
|
+
import { useModuleApp } from '@modern-js/plugin-garfish/runtime';
|
153
153
|
|
154
154
|
function App() {
|
155
155
|
const { MApp } = useModuleApps();
|
@@ -293,7 +293,7 @@ import '../styles/utils.css';
|
|
293
293
|
```
|
294
294
|
|
295
295
|
:::info
|
296
|
-
Modern.js 集成了 [PostCSS](/guides/css
|
296
|
+
Modern.js 集成了 [PostCSS](/guides/basic-features/css),支持现代 CSS 语法特性,比如 [custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)。
|
297
297
|
|
298
298
|
:::
|
299
299
|
|
@@ -255,23 +255,23 @@ export default Index;
|
|
255
255
|
├── package.json
|
256
256
|
├── pnpm-lock.yaml
|
257
257
|
├── src
|
258
|
-
│
|
259
|
-
│
|
260
|
-
│
|
261
|
-
│
|
262
|
-
│
|
263
|
-
│
|
264
|
-
│
|
265
|
-
│
|
266
|
-
│
|
267
|
-
│
|
268
|
-
│
|
269
|
-
│
|
270
|
-
│
|
271
|
-
│
|
272
|
-
│
|
273
|
-
│
|
274
|
-
│
|
258
|
+
│ ├── components
|
259
|
+
│ │ ├── Avatar
|
260
|
+
│ │ │ └── index.tsx
|
261
|
+
│ │ └── Item
|
262
|
+
│ │ └── index.tsx
|
263
|
+
│ ├── containers
|
264
|
+
│ │ └── Contacts.tsx
|
265
|
+
│ ├── models
|
266
|
+
│ │ └── contacts.ts
|
267
|
+
│ ├── modern-app-env.d.ts
|
268
|
+
│ ├── routes
|
269
|
+
│ │ ├── archives
|
270
|
+
│ │ │ └── page.tsx
|
271
|
+
│ │ ├── layout.tsx
|
272
|
+
│ │ └── page.tsx
|
273
|
+
│ └── styles
|
274
|
+
│ └── utils.css
|
275
275
|
└── tsconfig.json
|
276
276
|
```
|
277
277
|
|
@@ -29,29 +29,29 @@ title: 添加应用入口
|
|
29
29
|
├── package.json
|
30
30
|
├── pnpm-lock.yaml
|
31
31
|
├── src
|
32
|
-
│
|
33
|
-
│
|
34
|
-
│
|
35
|
-
│
|
36
|
-
│
|
37
|
-
│
|
38
|
-
│
|
39
|
-
│
|
40
|
-
│
|
41
|
-
│
|
42
|
-
│
|
43
|
-
│
|
44
|
-
│
|
45
|
-
│
|
46
|
-
│
|
47
|
-
│
|
48
|
-
│
|
49
|
-
│
|
50
|
-
│
|
51
|
-
│
|
52
|
-
│
|
53
|
-
│
|
54
|
-
│
|
32
|
+
│ ├── modern-app-env.d.ts
|
33
|
+
│ ├── landing-page
|
34
|
+
│ │ └── routes
|
35
|
+
│ │ ├── index.css
|
36
|
+
│ │ ├── layout.tsx
|
37
|
+
│ │ └── page.tsx
|
38
|
+
│ └── myapp
|
39
|
+
│ ├── components
|
40
|
+
│ │ ├── Avatar
|
41
|
+
│ │ │ └── index.tsx
|
42
|
+
│ │ └── Item
|
43
|
+
│ │ └── index.tsx
|
44
|
+
│ ├── containers
|
45
|
+
│ │ └── Contacts.tsx
|
46
|
+
│ ├── models
|
47
|
+
│ │ └── contacts.ts
|
48
|
+
│ ├── routes
|
49
|
+
│ │ ├── archives
|
50
|
+
│ │ │ └── page.tsx
|
51
|
+
│ │ ├── layout.tsx
|
52
|
+
│ │ └── page.tsx
|
53
|
+
│ └── styles
|
54
|
+
│ └── utils.css
|
55
55
|
└── tsconfig.json
|
56
56
|
```
|
57
57
|
|
@@ -1,39 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 5
|
3
|
-
---
|
4
|
-
# build
|
5
|
-
|
6
|
-
```bash
|
7
|
-
Usage: modern build [options]
|
8
|
-
|
9
|
-
build application
|
10
|
-
|
11
|
-
Options:
|
12
|
-
-c --config <config> configuration file path, which can be a relative path or an absolute path
|
13
|
-
-h, --help show command help
|
14
|
-
--analyze analyze the bundle and view size of each module
|
15
|
-
```
|
16
|
-
|
17
|
-
`modern build` command will by default build production in `dist/`.
|
18
|
-
|
19
|
-
you can configure the [`output.distPath`](/configure/app/output/dist-path) specifies the output directory for the product.
|
20
|
-
|
21
|
-
## Analyze Bundle
|
22
|
-
|
23
|
-
execute `npx modern build --analyze` command,can produce an HTML file that analyzes the volume of the bundle while packaging the production code:
|
24
|
-
|
25
|
-
```
|
26
|
-
Bundle Analyzer saved report to /example/dist/report.html
|
27
|
-
File sizes after production build:
|
28
|
-
|
29
|
-
122.35 KB dist/static/js/885.1d4fbe5a.js
|
30
|
-
2.3 KB dist/static/js/main.4b8e8d64.js
|
31
|
-
761 B dist/static/js/runtime-main.edb7cf35.js
|
32
|
-
645 B dist/static/css/main.0dd3ecc1.css
|
33
|
-
```
|
34
|
-
|
35
|
-
Open the above HTML file in the browser, you can see the tile diagram of the packaged product, and perform package volume analysis and optimization:
|
36
|
-
|
37
|
-
<img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/mwa-build-analyze-8784f762c1ab0cb20935829d5f912c4c.png" />
|
38
|
-
|
39
|
-
> this features based on [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer).
|