@modern-js/main-doc 2.5.0 → 2.7.0
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/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).
|