@modern-js/main-doc 2.0.0-beta.3 → 2.0.0-beta.4
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/commands/inspect.md +0 -4
- package/en/docusaurus-plugin-content-docs/current/components/init-app.md +42 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/server/routes.md +2 -4
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/esbuild.md +16 -39
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/css-in-js.md +38 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/css-modules.md +86 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/less-sass.md +17 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/postcss.md +81 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +95 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/data-fetch.md +66 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/routes.md +270 -0
- package/en/docusaurus-plugin-content-docs/current/guides/concept/entries.md +116 -0
- package/en/docusaurus-plugin-content-docs/current/guides/concept/lifecycle.md +15 -0
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +162 -0
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/upgrade.md +78 -0
- package/{zh/tutorials/first-app → en/docusaurus-plugin-content-docs/current/guides}/overview.md +4 -4
- package/en/docusaurus-plugin-content-docs/current/tutorials/foundations/introduction.md +1 -1
- package/en/docusaurus-plugin-content-docs/current.json +11 -11
- package/package.json +3 -3
- package/zh/apis/app/commands/inspect.md +0 -4
- package/zh/apis/app/commands/new.md +1 -1
- package/zh/apis/app/hooks/src/index_.md +6 -5
- package/zh/components/debug-app.md +18 -0
- package/zh/components/global-proxy.md +28 -0
- package/zh/components/init-app.md +44 -0
- package/zh/components/prerequisites.md +19 -0
- package/zh/configure/app/server/routes.md +2 -4
- package/zh/configure/app/tools/esbuild.md +16 -39
- package/zh/guides/advanced-features/bff/bff-proxy.md +1 -1
- package/zh/guides/advanced-features/compatibility.md +2 -38
- package/zh/guides/advanced-features/custom-app.md +15 -17
- package/zh/guides/advanced-features/ssg.md +6 -6
- package/zh/guides/advanced-features/ssr.md +94 -51
- package/zh/guides/advanced-features/testing.md +33 -1
- package/zh/guides/advanced-features/web-server.md +2 -2
- package/zh/guides/basic-features/css/tailwindcss.md +2 -6
- package/zh/guides/basic-features/html.md +182 -0
- package/zh/guides/basic-features/mock.md +3 -9
- package/zh/guides/basic-features/proxy.md +2 -27
- package/zh/guides/concept/entries.md +4 -5
- package/zh/guides/get-started/quick-start.md +6 -78
- package/zh/guides/get-started/upgrade.md +8 -8
- package/zh/guides/topic-detail/model/quick-start.md +1 -1
- package/zh/guides/topic-detail/model/test-model.md +2 -2
- package/zh/guides/topic-detail/monorepo/intro.md +1 -1
- package/zh/guides/troubleshooting/dependencies.md +0 -69
- package/zh/tutorials/first-app/_category_.json +1 -1
- package/zh/tutorials/first-app/c01-start.md +94 -0
- package/zh/tutorials/first-app/{c05-component/5.1-use-ui-library.md → c02-component.md} +13 -15
- package/zh/tutorials/first-app/c03-css.md +305 -0
- package/zh/tutorials/first-app/{c08-client-side-routing/8.1-code-based-routing.md → c04-routes.md} +52 -39
- package/zh/tutorials/first-app/c05-loader.md +82 -0
- package/zh/tutorials/first-app/c06-model.md +256 -0
- package/zh/tutorials/first-app/c07-container.md +268 -0
- package/zh/tutorials/first-app/c08-entries.md +134 -0
- package/zh/tutorials/foundations/introduction.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-modern-mode.md +0 -34
- package/zh/apis/generator/overview.md +0 -32
- package/zh/configure/app/output/enable-modern-mode.md +0 -34
- package/zh/guides/topic-detail/monorepo/deploy.md +0 -43
- package/zh/tutorials/first-app/c01-getting-started/1.1-prerequisites.md +0 -25
- package/zh/tutorials/first-app/c01-getting-started/1.2-minimal-mwa.md +0 -118
- package/zh/tutorials/first-app/c01-getting-started/1.3-dev-command.md +0 -29
- package/zh/tutorials/first-app/c01-getting-started/1.4-enable-ssr.md +0 -47
- package/zh/tutorials/first-app/c01-getting-started/1.5-start-command.md +0 -18
- package/zh/tutorials/first-app/c01-getting-started/1.6-create-repo.md +0 -31
- package/zh/tutorials/first-app/c01-getting-started/_category_.json +0 -3
- package/zh/tutorials/first-app/c02-generator-and-studio/2.1-generator.md +0 -79
- package/zh/tutorials/first-app/c02-generator-and-studio/2.2-boilerplates.md +0 -34
- package/zh/tutorials/first-app/c02-generator-and-studio/2.3-configuration.md +0 -19
- package/zh/tutorials/first-app/c02-generator-and-studio/_category_.json +0 -3
- package/zh/tutorials/first-app/c03-ide/3.1-setting-up.md +0 -55
- package/zh/tutorials/first-app/c03-ide/3.2-hints-in-ide.md +0 -60
- package/zh/tutorials/first-app/c03-ide/3.3-autofix-in-ide.md +0 -11
- package/zh/tutorials/first-app/c03-ide/3.4-autofix-in-cli.md +0 -63
- package/zh/tutorials/first-app/c03-ide/_category_.json +0 -3
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.1-use-es6-plus.md +0 -54
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.2-use-typescript.md +0 -135
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.3-compatibility.md +0 -67
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/_category_.json +0 -3
- package/zh/tutorials/first-app/c05-component/5.2-use-standalone-component.md +0 -72
- package/zh/tutorials/first-app/c05-component/_category_.json +0 -3
- package/zh/tutorials/first-app/c06-css-and-component/6.1-css-in-js.md +0 -110
- package/zh/tutorials/first-app/c06-css-and-component/6.2-utility-class.md +0 -143
- package/zh/tutorials/first-app/c06-css-and-component/6.3-postcss.md +0 -84
- package/zh/tutorials/first-app/c06-css-and-component/6.4-design-system.md +0 -83
- package/zh/tutorials/first-app/c06-css-and-component/6.5-storybook.md +0 -77
- package/zh/tutorials/first-app/c06-css-and-component/6.6-testing.md +0 -104
- package/zh/tutorials/first-app/c06-css-and-component/_category_.json +0 -3
- package/zh/tutorials/first-app/c07-app-entry/7.1-intro.md +0 -69
- package/zh/tutorials/first-app/c07-app-entry/7.2-add-entry-in-cli.md +0 -100
- package/zh/tutorials/first-app/c07-app-entry/7.3-manage-entries-by-hand.md +0 -69
- package/zh/tutorials/first-app/c07-app-entry/_category_.json +0 -3
- package/zh/tutorials/first-app/c08-client-side-routing/_category_.json +0 -3
- package/zh/tutorials/first-app/c09-bff/9.1-serverless.md +0 -30
- package/zh/tutorials/first-app/c09-bff/9.2-enable-bff.md +0 -95
- package/zh/tutorials/first-app/c09-bff/9.3-fetch-bff.md +0 -131
- package/zh/tutorials/first-app/c09-bff/_category_.json +0 -3
- package/zh/tutorials/first-app/c10-model/10.1-application-architecture.md +0 -21
- package/zh/tutorials/first-app/c10-model/10.2-add-model.md +0 -185
- package/zh/tutorials/first-app/c10-model/10.3-use-model.md +0 -55
- package/zh/tutorials/first-app/c10-model/10.4-testing.md +0 -69
- package/zh/tutorials/first-app/c10-model/_category_.json +0 -3
- package/zh/tutorials/first-app/c11-container/11.1-use-model-with-app-state.md +0 -240
- package/zh/tutorials/first-app/c11-container/11.2-add-container.md +0 -109
- package/zh/tutorials/first-app/c11-container/11.3-use-loader.md +0 -63
- package/zh/tutorials/first-app/c11-container/11.4-testing.md +0 -56
- package/zh/tutorials/first-app/c11-container/_category_.json +0 -3
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 命令行中的自动修复
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
提交前的自动准入检查,跟 VS Code 里的保存一样,会尽可能自动格式化代码和修复问题,只有遇到无法自动修复的问题,才会报错阻止提交。
|
|
6
|
-
|
|
7
|
-
我们添加一段可自动修复的问题代码(如果在 VS Code 里添加,保存时会自动修复,所以用 CLI 来添加):
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
echo ';' >> src/routes/page.jsx
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
打开 `page.tsx`,可以看到末尾多了一个 ';',有问题提示。
|
|
14
|
-
|
|
15
|
-
提交代码:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
git commit -am "test: 再次测试准入检查"
|
|
19
|
-
git status
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
可以看到虽然仍然提交失败,但新增的问题被自动修复了。
|
|
23
|
-
|
|
24
|
-
手动把参数 a 的问题修复(删除 a),再次添加 ';',提交代码:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
echo ';' >> src/routes/page.jsx
|
|
28
|
-
git commit -am "test: 再次测试准入检查"
|
|
29
|
-
git log HEAD --stat --graph --name-status
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
可以看到提交成功了,新增的问题被自动修复,并且自动被 stage。
|
|
33
|
-
|
|
34
|
-
:::info 注
|
|
35
|
-
在真实项目的开发中,对于以下情况,可以在提交时增加 -n 或 --no-verify 参数,破例跳过准入检查:
|
|
36
|
-
1. Hotfix
|
|
37
|
-
2. merge 过程中解决了冲突,变更的文件里包含别人的代码
|
|
38
|
-
3. 旧项目迁移到 Modern.js,最初做统一自动修复的提交
|
|
39
|
-
:::
|
|
40
|
-
|
|
41
|
-
提交前的自动准入检查,只会检查和修复这次提交中有变更的文件(已经 stage 的文件),也就是说,只会强制要求这次工作过程中修改过的文件没有问题,不会要求你去解决这次工作无关的文件的问题。
|
|
42
|
-
|
|
43
|
-
如果要对整个仓库的所有文件做 lint 检查和自动修复,可以手动执行 `lint` 命令,比如:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
echo ';' >> src/routes/page.jsx
|
|
47
|
-
pnpm run lint
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
:::info 注
|
|
51
|
-
上述命令速度慢,不常用。旧项目刚迁移到 Modern.js 框架的时候,可以用这个命令对所有代码做一次自动修复,单独提交。
|
|
52
|
-
:::
|
|
53
|
-
|
|
54
|
-
本章节中,我们完成了编程环境的初始化和检查,熟悉了相关功能。下一章节开始,我们就可以开始写代码了。
|
|
55
|
-
|
|
56
|
-
:::info 注
|
|
57
|
-
Modern.js 是用 [Modern Lint](/docs/guides/advanced-features/eslint) 规则集来实现上述能力, 集成了 ESLint、TypeScript 支持、Prettier 等主流工具和最佳实践。
|
|
58
|
-
:::
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
> 本章节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c03/hello-modern)。
|
|
63
|
-
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 使用 ES6+ 语法
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
上一章节中,我们确认了当前 IDE 的编程环境。
|
|
6
|
-
|
|
7
|
-
这一章节中,我们沿用上一章节的项目和编码环境,实现一个最简单的联系人列表。
|
|
8
|
-
|
|
9
|
-
Modern.js 支持 `src` 目录下直接使用 ES6+(ES2015+)语法。
|
|
10
|
-
|
|
11
|
-
我们把 `routes/page.jsx` 改成:
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
const getAvatar = users =>
|
|
15
|
-
users.map(user => ({
|
|
16
|
-
...user,
|
|
17
|
-
avatar: `https://avatars.dicebear.com/v2/identicon/${user.name}.svg`,
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
const getMockData = () =>
|
|
21
|
-
getAvatar([
|
|
22
|
-
{ name: 'Thomas', email: 'w.kccip@bllmfbgv.dm' },
|
|
23
|
-
{ name: 'Chow', email: 'f.lfqljnlk@ywoefljhc.af' },
|
|
24
|
-
{ name: 'Bradley', email: 'd.wfovsqyo@gpkcjwjgb.fr' },
|
|
25
|
-
{ name: 'Davis', email: '"t.kqkoj@utlkwnpwk.nu' },
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
function Index() {
|
|
29
|
-
return (
|
|
30
|
-
<ul>
|
|
31
|
-
{getMockData().map(({ name, avatar, email }) => (
|
|
32
|
-
<li key={name}>
|
|
33
|
-
<img src={avatar} width={60} height={60} /> ---
|
|
34
|
-
<span>{name}</span> ---
|
|
35
|
-
<span>{email}</span>
|
|
36
|
-
</li>
|
|
37
|
-
))}
|
|
38
|
-
</ul>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default Index;
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
可以看到其中使用了多种 ES6+ 语法(注意生成 mockData 过程中使用了 [Pipeline Operator](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator) 语法),都不需要做任何配置。
|
|
46
|
-
|
|
47
|
-
运行 `pnpm run dev`,查看运行结果:
|
|
48
|
-
|
|
49
|
-

|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c04/hello-modern)。
|
|
54
|
-
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 使用 TypeScript 语法
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Modern.js 同样对 TypeScript 提供了一等公民、开箱即用的支持。
|
|
6
|
-
|
|
7
|
-
这一小节,我们将当前为 ES6+ 语法的 Demo 修改为 TypeScript 语法。
|
|
8
|
-
|
|
9
|
-
在项目根目录下执行:
|
|
10
|
-
|
|
11
|
-
import Tabs from '@theme/Tabs';
|
|
12
|
-
import TabItem from '@theme/TabItem';
|
|
13
|
-
|
|
14
|
-
<Tabs>
|
|
15
|
-
<TabItem value="macOS" label="macOS" default>
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
mv src/routes/layout.jsx src/routes/layout.tsx
|
|
19
|
-
mv src/routes/page.jsx src/routes/page.tsx
|
|
20
|
-
mv modern.config.js modern.config.ts
|
|
21
|
-
touch src/modern-app-env.d.ts
|
|
22
|
-
|
|
23
|
-
pnpm add typescript @types/react @types/react-dom @types/node -D
|
|
24
|
-
|
|
25
|
-
touch tsconfig.json
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
</TabItem>
|
|
29
|
-
<TabItem value="Windows" label="Windows">
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
mv src/routes/layout.jsx src/routes/layout.tsx
|
|
33
|
-
mv src/routes/page.jsx src/routes/page.tsx
|
|
34
|
-
mv modern.config.js modern.config.ts
|
|
35
|
-
ni src/modern-app-env.d.ts
|
|
36
|
-
|
|
37
|
-
pnpm add typescript @types/react @types/react-dom @types/node -D
|
|
38
|
-
|
|
39
|
-
ni tsconfig.json
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
</TabItem>
|
|
43
|
-
</Tabs>
|
|
44
|
-
|
|
45
|
-
:::info 注
|
|
46
|
-
接下来所有章节的项目,都会使用 TS 来进行开发。
|
|
47
|
-
:::
|
|
48
|
-
|
|
49
|
-
`tsconfig.json` 内容如下:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"extends": "@modern-js/tsconfig/base",
|
|
54
|
-
"compilerOptions": {
|
|
55
|
-
"declaration": false,
|
|
56
|
-
"jsx": "preserve",
|
|
57
|
-
"baseUrl": "./",
|
|
58
|
-
"paths": {
|
|
59
|
-
"@/*": ["./src/*"]
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"include": ["src", "shared", "config"]
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`modern.config.ts` 内容修改如下:
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
import { defineConfig } from '@modern-js/app-tools';
|
|
70
|
-
|
|
71
|
-
export default defineConfig({
|
|
72
|
-
runtime: {
|
|
73
|
-
router: true,
|
|
74
|
-
state: true,
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
`modern-app-env.d.ts` 内容如下
|
|
80
|
-
|
|
81
|
-
```ts
|
|
82
|
-
/// <reference types='@modern-js/app-tools/types' />
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
打开 `src/routes/page.tsx`,把代码改成以下内容:
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
const getAvatar = (users: Array<{ name: string; email: string }>) =>
|
|
89
|
-
users.map(user => ({
|
|
90
|
-
...user,
|
|
91
|
-
avatar: `https://avatars.dicebear.com/v2/identicon/${user.name}.svg`,
|
|
92
|
-
}));
|
|
93
|
-
|
|
94
|
-
const getMockData = () =>
|
|
95
|
-
getAvatar([
|
|
96
|
-
{ name: 'Thomas', email: 'w.kccip@bllmfbgv.dm' },
|
|
97
|
-
{ name: 'Chow', email: 'f.lfqljnlk@ywoefljhc.af' },
|
|
98
|
-
{ name: 'Bradley', email: 'd.wfovsqyo@gpkcjwjgb.fr' },
|
|
99
|
-
{ name: 'Davis', email: '"t.kqkoj@utlkwnpwk.nu' },
|
|
100
|
-
]);
|
|
101
|
-
|
|
102
|
-
function Index() {
|
|
103
|
-
return (
|
|
104
|
-
<ul>
|
|
105
|
-
{getMockData().map(({ name, avatar, email }) => (
|
|
106
|
-
<li key={name}>
|
|
107
|
-
<img src={avatar} width={60} height={60} /> ---
|
|
108
|
-
<span>{name}</span> ---
|
|
109
|
-
<span>{email}</span>
|
|
110
|
-
</li>
|
|
111
|
-
))}
|
|
112
|
-
</ul>
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export default Index;
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
可以看到,跟 ES6+ 的代码相比有以下不同:
|
|
120
|
-
|
|
121
|
-
1. 由于 TS 还不支持 [Pipeline Operator](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator) 语法,需要把 mockData 的生成过程改成普通的函数调用语法。
|
|
122
|
-
2. 需要声明 `getAvatar` 参数的类型。
|
|
123
|
-
|
|
124
|
-
在 VS Code 里,把鼠标悬停在 `mockData` 上,可以看到它的类型已经被自动推导出来。如果把 `key={name}` 改成 `key={name * 2}`,可以看到 TS 的报错。
|
|
125
|
-
|
|
126
|
-
运行 `pnpm run dev`,可以看到一样的运行结果。
|
|
127
|
-
|
|
128
|
-
:::info 注
|
|
129
|
-
更简单、开箱即用的方式,是在创建项目的时候,**开发语言**选择 TS,会自动生成上述样板代码,源代码文件也会自动默认采用 .ts 和 .tsx。
|
|
130
|
-
:::
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c04/hello-modern-2)。
|
|
135
|
-
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 客户端兼容性
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
前两个小节我们学习了如何使用 ES6+ 与 TypeScript 语法来编写应用。
|
|
6
|
-
|
|
7
|
-
这一小节,我们来学习如何在 Modern.js 中解决客户端兼容性的问题。
|
|
8
|
-
|
|
9
|
-
在实际项目中,往往会因为需要兼容老版本浏览器,而无法利用现代浏览器的最新特性与最佳实践。
|
|
10
|
-
|
|
11
|
-
Modern.js 提供了开箱即用的解决客户端兼容性的能力,支持自动 Polyfill、Browserslist 配置、差异化分发。
|
|
12
|
-
|
|
13
|
-
我们首先使用微生成器开启该功能:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
? 请选择你想要的操作:启用可选功能
|
|
17
|
-
? 启用可选功能:启用「基于 UA 的 Polyfill」功能
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
接着我们修改 `modern.config.ts`,添加以下配置:
|
|
21
|
-
|
|
22
|
-
```typescript title="modern.config.ts"
|
|
23
|
-
export default defineConfig({
|
|
24
|
-
output: {
|
|
25
|
-
polyfill: 'ua',
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
以上配置将会开启「 自动 Polyfill 」,Modern.js 会根据浏览器对规范的支持程度,返回不同内容的 polyfill,我们不需要再担心低版本浏览器对新版本浏览器的拖累。
|
|
31
|
-
|
|
32
|
-
执行 `pnpm run dev`,可以看到浏览器中请求了当前服务上 `/__polyfill__` 这一资源,但是当前请求到的资源是空的:
|
|
33
|
-
|
|
34
|
-

|
|
35
|
-
|
|
36
|
-
我们切换到 Chrome Mobile 模式,选择设备为 iPhone 5/SE,重新刷新页面,可以看到请求到了有内容的资源:
|
|
37
|
-
|
|
38
|
-

|
|
39
|
-
|
|
40
|
-
:::info 注
|
|
41
|
-
如果遇到无法识别的浏览器,Modern.js 将会返回全量的 polyfill。
|
|
42
|
-
:::
|
|
43
|
-
|
|
44
|
-
接下里我们继续修改 `modern.config.ts`:
|
|
45
|
-
|
|
46
|
-
```typescript title="modern.config.ts"
|
|
47
|
-
export default defineConfig({
|
|
48
|
-
output: {
|
|
49
|
-
enableModernMode: true,
|
|
50
|
-
polyfill: 'ua',
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
以上配置将会开启「 差异化分发 」,在原生支持模块功能的浏览器中,Modern.js 优先使用带有 ESM 模块语法静态资源的 HTML,浏览器能够最优化的加载模块,带来更好的页面性能。
|
|
56
|
-
|
|
57
|
-
执行 `pnpm run build && pnpm run start`,打开页面,可以看到已经加载了带有 `-es6` 后缀的资源文件:
|
|
58
|
-
|
|
59
|
-

|
|
60
|
-
|
|
61
|
-
:::info 注
|
|
62
|
-
更多相关内容可以查看 [**客户端兼容性**](/docs/guides/advanced-features/compatibility)。
|
|
63
|
-
:::
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c04/hello-modern-3)。
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 使用独立开源组件
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
上一小节我们使用 Ant Design 组件库中的组件来实现列表。
|
|
6
|
-
|
|
7
|
-
这一小节我们用独立开源组件来实现联系人的操作按钮。
|
|
8
|
-
|
|
9
|
-
以按钮库 [Ladda](https://lab.hakim.se/ladda/) 的 [React 实现](https://www.npmjs.com/package/react-ladda) 为例,先添加依赖:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
pnpm add react-ladda ladda
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
在 `src/routes/page.tsx` 里导入组件,同时手动导入需要的 CSS:
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import LaddaButton, { S, SLIDE_UP } from 'react-ladda';
|
|
19
|
-
import 'ladda/dist/ladda.min.css';
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
修改 `List.Item` 组件的调用代码,添加 actions:
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
<List.Item
|
|
26
|
-
key={name}
|
|
27
|
-
actions={[
|
|
28
|
-
<LaddaButton
|
|
29
|
-
key={email}
|
|
30
|
-
loading={false}
|
|
31
|
-
data-size={S}
|
|
32
|
-
data-style={SLIDE_UP}
|
|
33
|
-
data-spinner-size={20}
|
|
34
|
-
data-spinner-color="#ddd"
|
|
35
|
-
data-spinner-lines={8}>
|
|
36
|
-
Call
|
|
37
|
-
</LaddaButton>
|
|
38
|
-
]}>
|
|
39
|
-
<List.Item.Meta
|
|
40
|
-
avatar={<img alt="avatar" src={avatar} width={60} height={60} />}
|
|
41
|
-
title={name}
|
|
42
|
-
description={email}
|
|
43
|
-
/>
|
|
44
|
-
</List.Item>
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
`react-ladda` 组件库没有提供 types 文件,我们添加一个 `.d.ts` 文件:
|
|
48
|
-
|
|
49
|
-
在 `modern-app-env.d.ts` 中添加模块定义:
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
declare module 'react-ladda' {
|
|
53
|
-
const LaddaButton: any;
|
|
54
|
-
export default LaddaButton;
|
|
55
|
-
export const S: any;
|
|
56
|
-
export const SLIDE_UP: any;
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
执行 `pnpm run dev`,查看运行结果:
|
|
61
|
-
|
|
62
|
-

|
|
63
|
-
|
|
64
|
-
:::info 注
|
|
65
|
-
CSS 文件会自动经过 Modern.js 内置的 [PostCSS](/docs/guides/basic-features/css/postcss) 的处理,能够满足大多数项目的样式开发需求。
|
|
66
|
-
|
|
67
|
-
Modern.js 也支持导入 SCSS、Less 文件。此外,有的组件使用 CSS in JS,不需要额外导入样式文件,下一节会有相关介绍。
|
|
68
|
-
:::
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c05/hello-modern-2)。
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 用 CSS in JS 写组件
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
上一章节中,我们学习了如何使用 UI 组件库、标准三方库中的组件。
|
|
6
|
-
|
|
7
|
-
这一章节中,我们将学习如何实现 UI 组件。
|
|
8
|
-
|
|
9
|
-
首先我们希望自己控制联系人头像的展示,实现这种设计稿:
|
|
10
|
-
|
|
11
|
-

|
|
12
|
-
|
|
13
|
-
假设没有现成的组件可以实现,那就需要自己写些 CSS 了,传统上,我们有如下选择:
|
|
14
|
-
|
|
15
|
-
1. 直接在元素的 style 属性上写样式,缺点是:不方便维护,UI 视觉上的细节也会跟 UI 结构上的细节和业务逻辑混在一起。
|
|
16
|
-
2. 在 CSS 代码里用选择器找到这个头像元素,写样式,避免了 1 的缺点,但新的缺点是:不方便在其他有头像出现的地方复用,集中维护,做到 [DRY](https://en.wikipedia.org/wiki/Don't_repeat_yourself)。
|
|
17
|
-
3. 在 CSS 代码里写一个 classname,封装这个样式,避免了 2 的缺点,但新的缺点是:需要考虑命名问题,避免在全局命名空间下重名,可能要用到 [BEM](http://getbem.com/) 之类的规范。
|
|
18
|
-
4. 用 CSS Modules 技术,让 CSS 文件和其中的 classname 变得【 模块化 】,避免了 3 的缺点。
|
|
19
|
-
|
|
20
|
-
Modern.js 开箱即用的支持 CSS Modules,但我们更推荐优先采用 CSS Modules 的继承者、在【 模块化 】上更进一步的 [styled-components](https://styled-components.com/),来实现类似的需求。
|
|
21
|
-
|
|
22
|
-
Modern.js 同样开箱即用的支持 styled-components,既不需要安装依赖,也不需要做任何配置。
|
|
23
|
-
|
|
24
|
-
在 `src/routes/page.tsx` 里修改顶部的代码:
|
|
25
|
-
|
|
26
|
-
```js
|
|
27
|
-
import styled from '@modern-js/runtime/styled';
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
添加以下代码:
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
const Avatar = styled.img`
|
|
34
|
-
width: 50px;
|
|
35
|
-
height: 50px;
|
|
36
|
-
border: 4px solid #0ef;
|
|
37
|
-
border-radius: 50%;
|
|
38
|
-
`;
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
修改 `List.Item.Meta` 的代码:
|
|
42
|
-
|
|
43
|
-
```tsx
|
|
44
|
-
<List.Item.Meta
|
|
45
|
-
avatar={<Avatar src={avatar} />}
|
|
46
|
-
title={name}
|
|
47
|
-
description={email}
|
|
48
|
-
/>
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
执行 `pnpm run dev`,可以看到预期的运行结果:
|
|
52
|
-
|
|
53
|
-

|
|
54
|
-
|
|
55
|
-
接下来我们做一点重构,为了增强可读性,让代码更容易维护,可以把 Avatar 组件拆分出去
|
|
56
|
-
|
|
57
|
-
在终端执行以下命令:
|
|
58
|
-
|
|
59
|
-
import Tabs from '@theme/Tabs';
|
|
60
|
-
import TabItem from '@theme/TabItem';
|
|
61
|
-
|
|
62
|
-
<Tabs>
|
|
63
|
-
<TabItem value="macOS" label="macOS" default>
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
mkdir -p src/routes/components/Avatar
|
|
67
|
-
touch src/routes/components/Avatar/index.tsx
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
</TabItem>
|
|
71
|
-
<TabItem value="Windows" label="Windows">
|
|
72
|
-
|
|
73
|
-
```powershell
|
|
74
|
-
mkdir -p src/routes/components/Avatar
|
|
75
|
-
ni src/routes/components/Avatar/index.tsx
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
</TabItem>
|
|
79
|
-
</Tabs>
|
|
80
|
-
|
|
81
|
-
把 `src/routes/page.tsx` 里的 Avatar 实现删掉,改成:
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
import Avatar from './components/Avatar';
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
`src/routes/components/Avatar/index.tsx` 的内容:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
import styled from '@modern-js/runtime/styled';
|
|
91
|
-
|
|
92
|
-
const Avatar = styled.img`
|
|
93
|
-
width: 50px;
|
|
94
|
-
height: 50px;
|
|
95
|
-
border: 4px solid #0ef;
|
|
96
|
-
border-radius: 50%;
|
|
97
|
-
`;
|
|
98
|
-
|
|
99
|
-
export default Avatar;
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
执行 `pnpm run dev`,运行结果应该是一样的。
|
|
103
|
-
|
|
104
|
-
:::info 注
|
|
105
|
-
采用目录形式(Avatar/index.tsx)而不是单文件形式(Avatar.tsx)的原因是,之后可以方便在目录内部增加子文件,包括专用的资源(图片等)、专用子组件、CSS 文件等,在这个**黑盒**内部可以随意重构,只考虑**最小局部**。
|
|
106
|
-
:::
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c06/hello-modern)。
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 用 Utility Class 写组件
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
上一小节我们学习了如何使用 style-components 实现 `Avatar` 组件。
|
|
6
|
-
|
|
7
|
-
但当前的 UI 仍然不能让人满意,缺乏专业感,例如列表项内部的布局有点粗糙,很多地方没对齐。
|
|
8
|
-
|
|
9
|
-
本小节中,我们自己来实现一个更好的 `Item` 组件,实现这样的设计稿:
|
|
10
|
-
|
|
11
|
-

|
|
12
|
-
|
|
13
|
-
这次要实现的 UI 更复杂,有内部结构,但另一方面,并没有 `Avatar` 组件的**很粗的亮蓝色边框**这样很特殊的 UI,都是很常规的水平垂直布局、居中、字体样式等。
|
|
14
|
-
|
|
15
|
-
这种情况下,其实根本没必要写 CSS,有更高效的、跟 styled-components 互补的实现方式:Utility Class。
|
|
16
|
-
|
|
17
|
-
Modern.js 集成了主流、轻量、通用的 Utility Class 工具库 [Tailwind CSS](https://tailwindcss.com/)。
|
|
18
|
-
|
|
19
|
-
执行 `pnpm run new`,进行如下选择,开启 Tailwind CSS:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
# 启用可选功能
|
|
23
|
-
❯ 启用 Tailwind CSS 支持
|
|
24
|
-
...
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
在 `src/routes/page.tsx` 顶部引入 Tailwind CSS 的 css 文件,就可以开始快速实现专业的 UI:
|
|
28
|
-
|
|
29
|
-
```js
|
|
30
|
-
import 'tailwindcss/base.css';
|
|
31
|
-
import 'tailwindcss/components.css';
|
|
32
|
-
import 'tailwindcss/utilities.css';
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
先创建 Item 组件:
|
|
36
|
-
|
|
37
|
-
import Tabs from '@theme/Tabs';
|
|
38
|
-
import TabItem from '@theme/TabItem';
|
|
39
|
-
|
|
40
|
-
<Tabs>
|
|
41
|
-
<TabItem value="macOS" label="macOS" default>
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
mkdir -p src/routes/components/Item
|
|
45
|
-
touch src/routes/components/Item/index.tsx
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
</TabItem>
|
|
49
|
-
<TabItem value="Windows" label="Windows">
|
|
50
|
-
|
|
51
|
-
```powershell
|
|
52
|
-
mkdir -p src/routes/components/Item
|
|
53
|
-
ni src/routes/components/Item/index.tsx
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
</TabItem>
|
|
57
|
-
</Tabs>
|
|
58
|
-
|
|
59
|
-
修改 `src/routes/page.tsx`,把 `List` 的 `render` 实现交给 `Item` 组件:
|
|
60
|
-
|
|
61
|
-
```js
|
|
62
|
-
import { List } from 'antd';
|
|
63
|
-
import 'tailwindcss/base.css';
|
|
64
|
-
import 'tailwindcss/components.css';
|
|
65
|
-
import 'tailwindcss/utilities.css';
|
|
66
|
-
import Item from './components/Item';
|
|
67
|
-
|
|
68
|
-
const getAvatar = (users: Array<{ name: string; email: string }>) =>
|
|
69
|
-
users.map(user => ({
|
|
70
|
-
...user,
|
|
71
|
-
avatar: `https://avatars.dicebear.com/v2/identicon/${user.name}.svg`,
|
|
72
|
-
}));
|
|
73
|
-
|
|
74
|
-
const mockData = getAvatar([
|
|
75
|
-
{ name: 'Thomas', email: 'w.kccip@bllmfbgv.dm' },
|
|
76
|
-
{ name: 'Chow', email: 'f.lfqljnlk@ywoefljhc.af' },
|
|
77
|
-
{ name: 'Bradley', email: 'd.wfovsqyo@gpkcjwjgb.fr' },
|
|
78
|
-
{ name: 'Davis', email: '"t.kqkoj@utlkwnpwk.nu' },
|
|
79
|
-
]);
|
|
80
|
-
|
|
81
|
-
function Index() {
|
|
82
|
-
return (
|
|
83
|
-
<div className="container lg mx-auto">
|
|
84
|
-
<List
|
|
85
|
-
dataSource={mockData}
|
|
86
|
-
renderItem={info => <Item key={info.name} info={info} />}
|
|
87
|
-
/>
|
|
88
|
-
</div>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export default Index;
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
在父容器的上使用了 [Utility Class](https://tailwindcss.com/docs/container) ,快速实现了最基本的 [RWD](https://tailwindcss.com/docs/responsive-design)(最大宽度、居中)。
|
|
96
|
-
|
|
97
|
-
接下来实现 `src/routes/components/Item/index.tsx`:
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
import Avatar from '../Avatar';
|
|
101
|
-
|
|
102
|
-
type InfoProps = {
|
|
103
|
-
avatar: string;
|
|
104
|
-
name: string;
|
|
105
|
-
email: string;
|
|
106
|
-
archived?: boolean;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const Item = ({ info }: { info: InfoProps }) => {
|
|
110
|
-
const { avatar, name, email, archived } = info;
|
|
111
|
-
return (
|
|
112
|
-
<div className="flex p-4 items-center border-gray-200 border-b">
|
|
113
|
-
<Avatar src={avatar} />
|
|
114
|
-
<div className="ml-4 flex-1 flex justify-between">
|
|
115
|
-
<div className="flex-1">
|
|
116
|
-
<p>{name}</p>
|
|
117
|
-
<p>{email}</p>
|
|
118
|
-
</div>
|
|
119
|
-
<button
|
|
120
|
-
type="button"
|
|
121
|
-
disabled={archived}
|
|
122
|
-
className={`bg-blue-500 text-white font-bold
|
|
123
|
-
py-2 px-4 rounded-full hover:bg-blue-700`}>
|
|
124
|
-
Archive
|
|
125
|
-
</button>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export default Item;
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
执行 `pnpm run dev`,可以看到预期的运行结果:
|
|
135
|
-
|
|
136
|
-

|
|
137
|
-
|
|
138
|
-
这一小节中,我们只使用了少量 Utility Class,比如 [Flex](https://tailwindcss.com/docs/display/)、[Padding](https://tailwindcss.com/docs/padding/)、[Margin](https://tailwindcss.com/docs/margin/)、[Text](https://tailwindcss.com/docs/text-color/)、[Font](https://tailwindcss.com/docs/font-weight/)、[Border](https://tailwindcss.com/docs/border-width),不写一行 CSS 就实现了有【 设计系统(Design System)】的、符合设计稿的专业 UI。
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c06/hello-modern-2)。
|
|
143
|
-
|