@modern-js/main-doc 0.0.0-next-20221203140534 → 0.0.0-next-20221205074243
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/CHANGELOG.md +2 -2
- package/en/docusaurus-plugin-content-docs/current/apis/app/commands/new.md +0 -2
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/bootstrap.md +17 -3
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/builder.md +46 -0
- package/en/docusaurus-plugin-content-docs/current.json +18 -18
- package/package.json +3 -3
- package/zh/apis/app/commands/new.md +0 -2
- package/zh/apis/app/runtime/app/_category_.json +1 -1
- package/zh/apis/app/runtime/bff/_category_.json +1 -1
- package/zh/apis/app/runtime/core/_category_.json +1 -1
- package/zh/apis/app/runtime/core/bootstrap.md +17 -3
- package/zh/apis/app/runtime/model/_category_.json +1 -1
- package/zh/apis/app/runtime/router/_category_.json +1 -1
- package/zh/apis/app/runtime/ssr/_category_.json +1 -1
- package/zh/apis/app/runtime/testing/_category_.json +1 -1
- package/zh/apis/app/runtime/utility/_category_.json +1 -1
- package/zh/apis/app/runtime/web-server/_category_.json +1 -1
- package/zh/configure/app/output/ssg.md +118 -114
- package/zh/configure/app/server/ssr.md +0 -2
- package/zh/guides/advanced-features/custom-app.md +8 -2
- package/zh/guides/advanced-features/ssg.md +74 -63
- package/zh/guides/advanced-features/ssr.md +76 -11
- package/zh/guides/basic-features/builder.md +46 -0
- package/zh/guides/basic-features/css/_category_.json +1 -1
- package/zh/guides/basic-features/css/less-sass.md +1 -14
- package/zh/guides/basic-features/data-fetch.md +1 -1
- package/zh/guides/basic-features/routes.md +32 -35
- package/zh/guides/concept/entries.md +4 -4
- package/zh/tutorials/first-app/c01-getting-started/1.2-minimal-mwa.md +2 -2
- package/zh/tutorials/first-app/c01-getting-started/1.4-enable-ssr.md +5 -2
- package/zh/tutorials/first-app/c02-generator-and-studio/2.2-boilerplates.md +4 -6
- package/zh/tutorials/first-app/c02-generator-and-studio/2.3-configuration.md +2 -4
- package/zh/tutorials/first-app/c03-ide/3.1-setting-up.md +1 -1
- package/zh/tutorials/first-app/c03-ide/3.2-hints-in-ide.md +44 -50
- package/zh/tutorials/first-app/c03-ide/3.3-autofix-in-ide.md +1 -1
- package/zh/tutorials/first-app/c03-ide/3.4-autofix-in-cli.md +4 -4
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.1-use-es6-plus.md +8 -21
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.2-use-typescript.md +37 -13
- package/zh/tutorials/first-app/c05-component/5.1-use-ui-library.md +3 -13
- package/zh/tutorials/first-app/c05-component/5.2-use-standalone-component.md +1 -21
- package/zh/tutorials/first-app/c06-css-and-component/6.1-css-in-js.md +9 -9
- package/zh/tutorials/first-app/c06-css-and-component/6.2-utility-class.md +9 -14
- package/zh/tutorials/first-app/c06-css-and-component/6.3-postcss.md +7 -7
- package/zh/tutorials/first-app/c06-css-and-component/6.4-design-system.md +1 -1
- package/zh/tutorials/first-app/c06-css-and-component/6.5-storybook.md +2 -2
- package/zh/tutorials/first-app/c06-css-and-component/6.6-testing.md +8 -17
- package/zh/tutorials/first-app/c07-app-entry/7.1-intro.md +23 -18
- package/zh/tutorials/first-app/c07-app-entry/7.2-add-entry-in-cli.md +30 -30
- package/zh/tutorials/first-app/c07-app-entry/7.3-manage-entries-by-hand.md +4 -9
- package/zh/tutorials/first-app/c08-client-side-routing/8.1-code-based-routing.md +66 -63
- package/zh/tutorials/first-app/c09-bff/9.2-enable-bff.md +35 -33
- package/zh/tutorials/first-app/c09-bff/9.3-fetch-bff.md +28 -102
- package/zh/tutorials/first-app/c10-model/10.1-application-architecture.md +4 -6
- package/zh/tutorials/first-app/c10-model/10.2-add-model.md +3 -3
- package/zh/tutorials/first-app/c10-model/10.3-use-model.md +21 -20
- package/zh/tutorials/first-app/c10-model/10.4-testing.md +2 -2
- package/zh/tutorials/first-app/c11-container/11.1-use-model-with-app-state.md +34 -68
- package/zh/tutorials/first-app/c11-container/11.2-add-container.md +40 -37
- package/zh/tutorials/first-app/c11-container/11.3-use-loader.md +6 -4
- package/zh/tutorials/first-app/c11-container/11.4-testing.md +2 -2
- package/zh/tutorials/foundations/introduction.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/default-alias.md +0 -25
- package/zh/apis/app/runtime/default-alias.md +0 -23
- package/zh/guides/basic-features/image.md +0 -43
- package/zh/guides/topic-detail/compile-speed.md +0 -182
- package/zh/guides/troubleshooting/compile.md +0 -379
- package/zh/tutorials/first-app/c08-client-side-routing/8.2-file-based-routing.md +0 -310
@@ -2,13 +2,13 @@
|
|
2
2
|
title: 完整使用 Model
|
3
3
|
---
|
4
4
|
|
5
|
-
上一章节中,我们初步引入**客户端应用架构**,从【 视图组件 】中拆分出【 业务模型(Model)】,`
|
5
|
+
上一章节中,我们初步引入**客户端应用架构**,从【 视图组件 】中拆分出【 业务模型(Model)】,`page.tsx` 中不再包含 UI 无关的业务逻辑实现细节,只需要使用 Model,就能实现同样的功能。
|
6
6
|
|
7
|
-
这一章节中,我们要进一步利用 Model 中实现的业务逻辑,让 `
|
7
|
+
这一章节中,我们要进一步利用 Model 中实现的业务逻辑,让 `archived/page.ts` 也从 BFF 获取数据,实现 Archive 按钮,点击按钮能把联系人归档,只显示在 Archives 列表里,不显示在 All 列表里。
|
8
8
|
|
9
9
|
先改造 `Item` 组件,增加 Archive 按钮的交互实现:
|
10
10
|
|
11
|
-
```tsx title="src/contacts/components/Item/index.tsx"
|
11
|
+
```tsx title="src/contacts/routes/components/Item/index.tsx"
|
12
12
|
import Avatar from '../Avatar';
|
13
13
|
|
14
14
|
type InfoProps = {
|
@@ -42,7 +42,8 @@ const Item = ({
|
|
42
42
|
archived
|
43
43
|
? 'bg-gray-400 cursor-default'
|
44
44
|
: 'bg-blue-500 hover:bg-blue-700'
|
45
|
-
}`}
|
45
|
+
}`}
|
46
|
+
>
|
46
47
|
{archived ? 'Archived' : 'Archive'}
|
47
48
|
</button>
|
48
49
|
</div>
|
@@ -53,9 +54,9 @@ const Item = ({
|
|
53
54
|
export default Item;
|
54
55
|
```
|
55
56
|
|
56
|
-
|
57
|
+
两个页面需要共用同一套状态(联系人列表数据、联系人是否被归档),并且由于 Archives 列表和 All 列表都可能是第一屏页面(从不同 URL 访问),这两个组件都需要包含加载初始数据的逻辑(如果客户端没有联系人列表数据,就请求 BFF),所以这类两个组件公用的实现逻辑应该合并到一起:
|
57
58
|
|
58
|
-
|
59
|
+
我们创建一个新的 `Contacts` 组件:
|
59
60
|
|
60
61
|
import Tabs from '@theme/Tabs';
|
61
62
|
import TabItem from '@theme/TabItem';
|
@@ -64,18 +65,16 @@ import TabItem from '@theme/TabItem';
|
|
64
65
|
<TabItem value="macOS" label="macOS" default>
|
65
66
|
|
66
67
|
```bash
|
67
|
-
|
68
|
-
|
69
|
-
touch src/contacts/components/Contacts/index.tsx
|
68
|
+
mkdir -p src/contacts/routes/components/Contacts/
|
69
|
+
touch src/contacts/routes/components/Contacts/index.tsx
|
70
70
|
```
|
71
71
|
|
72
72
|
</TabItem>
|
73
73
|
<TabItem value="Windows" label="Windows">
|
74
74
|
|
75
75
|
```powershell
|
76
|
-
|
77
|
-
|
78
|
-
ni src/contacts/components/Contacts/index.tsx
|
76
|
+
mkdir -p src/contacts/routes/components/Contacts/
|
77
|
+
ni src/contacts/routes/components/Contacts/index.tsx
|
79
78
|
```
|
80
79
|
|
81
80
|
</TabItem>
|
@@ -83,7 +82,7 @@ ni src/contacts/components/Contacts/index.tsx
|
|
83
82
|
|
84
83
|
修改`components/Contacts/index.tsx` ,内容如下:
|
85
84
|
|
86
|
-
```tsx title="src/contacts/components/Contacts/index.tsx"
|
85
|
+
```tsx title="src/contacts/routes/components/Contacts/index.tsx"
|
87
86
|
import { useEffect } from 'react';
|
88
87
|
import { useLocalModel } from '@modern-js/runtime/model';
|
89
88
|
import { List } from 'antd';
|
@@ -128,57 +127,39 @@ const Contacts = ({ source }: { source: 'archived' | 'items' }) => {
|
|
128
127
|
export default Contacts;
|
129
128
|
```
|
130
129
|
|
131
|
-
|
132
|
-
由于 computed 功能还未提供,这里先在组件里将传入的数据做预处理。
|
133
|
-
:::
|
130
|
+
最后改造 `page.tsx` 和 `archived/page.ts`,利用 Contacts 实现 Archives 列表和 All 列表:
|
134
131
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
import { useState } from 'react';
|
139
|
-
import { Radio, RadioChangeEvent } from 'antd';
|
140
|
-
import { Route, useHistory } from '@modern-js/runtime/router';
|
141
|
-
import { Helmet } from '@modern-js/runtime/head';
|
132
|
+
```tsx title="src/contacts/page.tsx"
|
133
|
+
import Contacts from './components/Contacts';
|
134
|
+
import 'ladda/dist/ladda.min.css';
|
142
135
|
import 'tailwindcss/base.css';
|
143
136
|
import 'tailwindcss/components.css';
|
144
137
|
import 'tailwindcss/utilities.css';
|
145
138
|
import './styles/utils.css';
|
146
|
-
import Contacts from './components/Contacts';
|
147
139
|
|
148
|
-
function
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
140
|
+
function Index() {
|
141
|
+
return (
|
142
|
+
<div className="container lg mx-auto">
|
143
|
+
<Contacts source="items" />
|
144
|
+
</div>
|
145
|
+
);
|
146
|
+
}
|
147
|
+
|
148
|
+
export default Index;
|
149
|
+
```
|
150
|
+
|
151
|
+
```tsx title="src/contacts/archived/page.tsx"
|
152
|
+
import Contacts from './components/Contacts';
|
156
153
|
|
154
|
+
function Index() {
|
157
155
|
return (
|
158
156
|
<div className="container lg mx-auto">
|
159
|
-
<
|
160
|
-
<Radio.Group onChange={handleSetList} value={currentList}>
|
161
|
-
<Radio value="/">All</Radio>
|
162
|
-
<Radio value="/archives">Archives</Radio>
|
163
|
-
</Radio.Group>
|
164
|
-
</div>
|
165
|
-
<Route path="/" exact={true}>
|
166
|
-
<Helmet>
|
167
|
-
<title>All</title>
|
168
|
-
</Helmet>
|
169
|
-
<Contacts source="items" />
|
170
|
-
</Route>
|
171
|
-
<Route path="/archives" exact={true}>
|
172
|
-
<Helmet>
|
173
|
-
<title>Archives</title>
|
174
|
-
</Helmet>
|
175
|
-
<Contacts source="archived" />
|
176
|
-
</Route>
|
157
|
+
<Contacts source="archived" />
|
177
158
|
</div>
|
178
159
|
);
|
179
160
|
}
|
180
161
|
|
181
|
-
export default
|
162
|
+
export default Index;
|
182
163
|
```
|
183
164
|
|
184
165
|
执行 `pnpm run dev`,访问 `http://localhost:8080/contacts/`,点击 Archive 按钮后,可以看到按钮置灰:
|
@@ -189,22 +170,7 @@ export default App;
|
|
189
170
|
|
190
171
|

|
191
172
|
|
192
|
-
出现这个问题的原因是,我们继续沿用了上一节的 `useLocalModel` API 来使用 Model,状态被保存到了组件内部的 state 里,而 `All` 列表和 `Archives` 列表中分别调用的 `Contacts`
|
193
|
-
|
194
|
-
```tsx title="src/contacts/App.tsx"
|
195
|
-
<Route path="/" exact={true}>
|
196
|
-
<Helmet>
|
197
|
-
<title>All</title>
|
198
|
-
</Helmet>
|
199
|
-
<Contacts source="items" />
|
200
|
-
</Route>
|
201
|
-
<Route path="/archives" exact={true}>
|
202
|
-
<Helmet>
|
203
|
-
<title>Archives</title>
|
204
|
-
</Helmet>
|
205
|
-
<Contacts source="archived" />
|
206
|
-
</Route>
|
207
|
-
```
|
173
|
+
出现这个问题的原因是,我们继续沿用了上一节的 `useLocalModel` API 来使用 Model,状态被保存到了组件内部的 state 里,而 `All` 列表和 `Archives` 列表中分别调用的 `Contacts` 组件,是两个各自独立的组件.
|
208
174
|
|
209
175
|
所以它们有各自独立的内部 state,互相不共享状态,渲染 `Archives` 列表的时候,`items` 仍然是初始状态。
|
210
176
|
|
@@ -215,7 +181,7 @@ export default App;
|
|
215
181
|
修改 `components/Contacts/index.tsx` 的内容:
|
216
182
|
|
217
183
|
|
218
|
-
```tsx title="src/contacts/components/Contacts/index.tsx"
|
184
|
+
```tsx title="src/contacts/routes/components/Contacts/index.tsx"
|
219
185
|
import { useEffect } from 'react';
|
220
186
|
import { useModel } from '@modern-js/runtime/model';
|
221
187
|
import { List } from 'antd';
|
@@ -19,9 +19,9 @@ import TabItem from '@theme/TabItem';
|
|
19
19
|
<TabItem value="macOS" label="macOS" default>
|
20
20
|
|
21
21
|
```bash
|
22
|
-
mkdir -p src/contacts/containers/
|
23
|
-
mv src/contacts/components/Contacts/index.tsx src/contacts/containers/Contacts.tsx
|
24
|
-
rm -r src/contacts/components/Contacts/
|
22
|
+
mkdir -p src/contacts/routes/containers/
|
23
|
+
mv src/contacts/routes/components/Contacts/index.tsx src/contacts/routes/containers/Contacts.tsx
|
24
|
+
rm -r src/contacts/routes/components/Contacts/
|
25
25
|
```
|
26
26
|
|
27
27
|
</TabItem>
|
@@ -43,7 +43,7 @@ import Item from '../components/Item';
|
|
43
43
|
import contacts from '../models/contacts';
|
44
44
|
```
|
45
45
|
|
46
|
-
修改 `
|
46
|
+
修改 `page.tsx` 和 `archives/page.tsx` 的代码:
|
47
47
|
|
48
48
|
```tsx
|
49
49
|
import Contacts from './containers/Contacts';
|
@@ -53,45 +53,48 @@ import Contacts from './containers/Contacts';
|
|
53
53
|
|
54
54
|
```md
|
55
55
|
.
|
56
|
-
├── .
|
57
|
-
├── api/
|
58
|
-
│ ├── .eslintrc.json
|
59
|
-
│ └── contacts.ts
|
60
|
-
├── src/
|
61
|
-
│ ├── contacts/
|
62
|
-
│ │ ├── components/
|
63
|
-
│ │ │ ├── Avatar/
|
64
|
-
│ │ │ │ ├── index.stories.tsx
|
65
|
-
│ │ │ │ └── index.tsx
|
66
|
-
│ │ │ └── Item/
|
67
|
-
│ │ │ ├── index.test.tsx
|
68
|
-
│ │ │ └── index.tsx
|
69
|
-
│ │ ├── containers/
|
70
|
-
│ │ │ └── Contacts.tsx
|
71
|
-
│ │ ├── models/
|
72
|
-
│ │ │ ├── contacts.test.ts
|
73
|
-
│ │ │ └── contacts.ts
|
74
|
-
│ │ ├── styles/
|
75
|
-
│ │ │ └── utils.css
|
76
|
-
│ │ ├── App.css
|
77
|
-
│ │ └── App.tsx
|
78
|
-
│ ├── landing-page/
|
79
|
-
│ │ └── pages/
|
80
|
-
│ │ ├── comments/
|
81
|
-
│ │ │ └── [commentTitle]/
|
82
|
-
│ │ │ └── index.tsx
|
83
|
-
│ │ ├── _app.tsx
|
84
|
-
│ │ ├── docs.tsx
|
85
|
-
│ │ └── index.tsx
|
86
|
-
│ ├── .eslintrc.json
|
87
|
-
│ └── modern-app-env.d.ts
|
88
|
-
├── .editorconfig
|
56
|
+
├── .eslintrc.js
|
89
57
|
├── .gitignore
|
58
|
+
├── .husky
|
90
59
|
├── .npmrc
|
91
60
|
├── .nvmrc
|
61
|
+
├── .prettierrc
|
62
|
+
├── .vscode
|
92
63
|
├── README.md
|
64
|
+
├── api
|
65
|
+
│ └── contacts.ts
|
66
|
+
├── modern.config.ts
|
93
67
|
├── package.json
|
94
68
|
├── pnpm-lock.yaml
|
69
|
+
├── src
|
70
|
+
│ ├── .eslintrc.js
|
71
|
+
│ ├── contacts
|
72
|
+
│ │ └── routes
|
73
|
+
│ │ ├── archives
|
74
|
+
│ │ │ └── page.tsx
|
75
|
+
│ │ ├── components
|
76
|
+
│ │ │ ├── Avatar
|
77
|
+
│ │ │ │ ├── index.stories.tsx
|
78
|
+
│ │ │ │ └── index.tsx
|
79
|
+
│ │ │ └── Item
|
80
|
+
│ │ │ ├── index.test.tsx
|
81
|
+
│ │ │ └── index.tsx
|
82
|
+
│ │ ├── containers
|
83
|
+
│ │ │ └── Contacts.tsx
|
84
|
+
│ │ ├── index.css
|
85
|
+
│ │ ├── layout.tsx
|
86
|
+
│ │ ├── models
|
87
|
+
│ │ │ ├── contacts.test.ts
|
88
|
+
│ │ │ └── contacts.ts
|
89
|
+
│ │ ├── page.tsx
|
90
|
+
│ │ └── styles
|
91
|
+
│ │ └── utils.css
|
92
|
+
│ ├── landing-page
|
93
|
+
│ │ └── routes
|
94
|
+
│ │ ├── index.css
|
95
|
+
│ │ ├── layout.tsx
|
96
|
+
│ │ └── page.tsx
|
97
|
+
│ └── modern-app-env.d.ts
|
95
98
|
└── tsconfig.json
|
96
99
|
```
|
97
100
|
|
@@ -8,10 +8,12 @@ title: 使用 Loader
|
|
8
8
|
|
9
9
|
可以在当前项目中开启 [SSR](/docs/configure/app/server/ssr),看下这种效果。
|
10
10
|
|
11
|
-
```
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
```js
|
12
|
+
export default defineConfig({
|
13
|
+
server: {
|
14
|
+
ssr: true,
|
15
|
+
},
|
16
|
+
});
|
15
17
|
```
|
16
18
|
|
17
19
|
执行 `pnpm run dev`,在 devtools 的 network 面板里查看 HTML 请求的 Preview 面板,可以看到 SSR 的渲染结果只有导航栏和 Pending... 字符,并没有联系人数据:
|
@@ -13,14 +13,14 @@ import TabItem from '@theme/TabItem';
|
|
13
13
|
<TabItem value="macOS" label="macOS" default>
|
14
14
|
|
15
15
|
```bash
|
16
|
-
touch src/contacts/containers/contacts.test.tsx
|
16
|
+
touch src/contacts/routes/containers/contacts.test.tsx
|
17
17
|
```
|
18
18
|
|
19
19
|
</TabItem>
|
20
20
|
<TabItem value="Windows" label="Windows">
|
21
21
|
|
22
22
|
```powershell
|
23
|
-
ni src/contacts/containers/contacts.test.tsx
|
23
|
+
ni src/contacts/routes/containers/contacts.test.tsx
|
24
24
|
```
|
25
25
|
|
26
26
|
</TabItem>
|
@@ -31,7 +31,7 @@ Modern.js 能为开发者提供极致的**开发体验(Development Experience
|
|
31
31
|
- 🏠 **一体化**:开发与生产环境 Web Server 唯一,CSR 和 SSR 同构开发,函数即接口的 API 服务调用。
|
32
32
|
- 📦 **开箱即用**:默认 TS 支持,内置构建、ESLint、调试工具,全功能可测试。
|
33
33
|
- 🌏 **周边生态**:自研状态管理、微前端、模块打包、Monorepo 方案等周边需求。
|
34
|
-
- 🕸
|
34
|
+
- 🕸 **多种路由模式**:包含自控路由、基于文件约定的路由(嵌套路由)等。
|
35
35
|
- 🚀 **独立构建核心**:支持多种打包工具,深度优化构建产物。
|
36
36
|
|
37
37
|
## 下一步
|
@@ -1,25 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 1
|
3
|
-
title: Default Alias
|
4
|
-
---
|
5
|
-
|
6
|
-
Modern.js recommend referring to the source code by alias, which contains 3 default aliases:
|
7
|
-
- `@/`: the file under the project root directory `src/* `.
|
8
|
-
- `@api/`: the file under the `api/*` in the project root directory (you need to enable the BFF first).
|
9
|
-
- `@shared/`: the file under the project root directory `shared/* `.
|
10
|
-
|
11
|
-
:::tip
|
12
|
-
In addition, developers can customize aliases in modern.config.js, see [Aliases](/docs/configure/app/source/alias) for detail.
|
13
|
-
:::
|
14
|
-
|
15
|
-
|
16
|
-
## Example
|
17
|
-
|
18
|
-
The following example shows how to reference a function by default alias.
|
19
|
-
|
20
|
-
```tsx
|
21
|
-
import { hello } from '@/common/utils';
|
22
|
-
|
23
|
-
hello();
|
24
|
-
```
|
25
|
-
A reference to `@/common/utils` is equal to a reference to `src/common/utils`.
|
@@ -1,23 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 1
|
3
|
-
title: 默认别名
|
4
|
-
---
|
5
|
-
|
6
|
-
Modern.js 推荐通过别名的方式引用源码,其中包含 3 种默认别名:
|
7
|
-
- `@/`:等价于引用项目根目录 `src/*` 下的文件。
|
8
|
-
- `@api/`:等价于引用项目根目录下 `api/*` 下的文件(需要先开启 BFF 功能)。
|
9
|
-
- `@shared/`:等价于引用项目根目录下 `shared/*` 下的文件。
|
10
|
-
|
11
|
-
:::tip 提示
|
12
|
-
- 除了以下默认别名,开发者可以在 `modern.config.js` 中自定义别名,详见[如何配置别名](/docs/configure/app/source/alias)。
|
13
|
-
:::
|
14
|
-
|
15
|
-
## 示例
|
16
|
-
下面的例子展示了如何通过默认别名引用函数。
|
17
|
-
```tsx
|
18
|
-
import { hello } from '@/common/utils';
|
19
|
-
|
20
|
-
hello();
|
21
|
-
|
22
|
-
```
|
23
|
-
引用 `@/common/utils` 相当于引用 `src/common/utils`。
|
@@ -1,43 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: 图片资源
|
3
|
-
sidebar_position: 4
|
4
|
-
---
|
5
|
-
|
6
|
-
## JS 中使用图片
|
7
|
-
|
8
|
-
JS 文件中引入的图片资源会返回解析之后的 URL:
|
9
|
-
|
10
|
-
```js title=src/App.jsx
|
11
|
-
import logoUrl from './logo.png';
|
12
|
-
|
13
|
-
console.log(logoUrl); // 输出: '/src/logo.png';
|
14
|
-
```
|
15
|
-
|
16
|
-
## Base64 编码内联
|
17
|
-
|
18
|
-
默认情况下,小于 10kb 的图片、字体文件,会经过 Base64 编码,内联进页面,不会再发送独立的请求。
|
19
|
-
|
20
|
-
可以通过配置 [`output.dataUriLimit`](/docs/configure/app/output/data-uri-limit) 修改这个阈值。
|
21
|
-
|
22
|
-
## JS 中使用 SVG
|
23
|
-
|
24
|
-
针对 SVG 资源,默认启用了 [SVGR](https://react-svgr.com/),可以通过 React 组件的形式导入:
|
25
|
-
|
26
|
-
```js title=App.jsx
|
27
|
-
import logoUrl, { ReactComponent as LogoComponent } from './logo.svg';
|
28
|
-
```
|
29
|
-
|
30
|
-
## CSS 中使用图片
|
31
|
-
|
32
|
-
在 CSS 文件中既可以通过相对路径也可以通过别名的方式引入图片:
|
33
|
-
|
34
|
-
```css
|
35
|
-
.logo {
|
36
|
-
background: url('./foo.png');
|
37
|
-
}
|
38
|
-
|
39
|
-
/** or **/
|
40
|
-
.logo {
|
41
|
-
background: url('@/foo.png');
|
42
|
-
}
|
43
|
-
```
|
@@ -1,182 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: 提升编译速度
|
3
|
-
sidebar_position: 9
|
4
|
-
---
|
5
|
-
|
6
|
-
Modern.js 默认内置了一系列的编译性能优化策略,但是随着业务场景变复杂、仓库的代码量增大,在使用过程中可能会遇到一些编译性能的问题。
|
7
|
-
|
8
|
-
本文档提供了一些可选的提速策略,**开发者可以根据实际场景选取其中的部分策略**,从而进一步提升编译速度。
|
9
|
-
|
10
|
-
## 通用优化策略
|
11
|
-
|
12
|
-
以下是一些通用的优化策略,对 `modern dev` 和 `modern build` 均有提速效果,其中部分策略对包体积也有优化。
|
13
|
-
|
14
|
-
### 减少重复依赖
|
15
|
-
|
16
|
-
在实际项目中,会存在某些第三方依赖被安装了多个版本的现象。重复依赖会导致包体积变大、编译速度变慢。
|
17
|
-
|
18
|
-
我们可以通过社区中的一些工具来自动消除重复依赖,比如 [yarn-deduplicate](https://github.com/scinos/yarn-deduplicate)。
|
19
|
-
|
20
|
-
```bash
|
21
|
-
npx yarn-deduplicate && yarn
|
22
|
-
```
|
23
|
-
|
24
|
-
如果你在使用 `pnpm`,可以考虑通过**重新生成 lock 文件**来减少重复依赖,
|
25
|
-
|
26
|
-
```bash
|
27
|
-
rm -rf ./node_modules pnpm-lock.yaml && pnpm install
|
28
|
-
```
|
29
|
-
|
30
|
-
:::info
|
31
|
-
删除 lock 文件会使项目中的依赖版本自动升级到指定范围下的最新版,请进行充分的测试。
|
32
|
-
:::
|
33
|
-
|
34
|
-
### 替换体积较大的依赖
|
35
|
-
|
36
|
-
建议将项目中体积较大的第三方依赖替换为更轻量的库,比如将 [moment](https://momentjs.com/) 替换为 [day.js](https://day.js.org/)。
|
37
|
-
|
38
|
-
如果不清楚项目中哪些三方依赖的体积较大,可以在执行构建时添加 `--analyze` 参数:
|
39
|
-
|
40
|
-
```bash
|
41
|
-
npx modern build --analyze
|
42
|
-
```
|
43
|
-
|
44
|
-
该参数会生成一个分析构建产物体积的 HTML 文件,手动在浏览器中打开该文件,可以看到打包产物的瓦片图。区块的面积越大,说明该模块的体积越大。
|
45
|
-
|
46
|
-
<img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/mwa-build-analyze-8784f762c1ab0cb20935829d5f912c4c.png" />
|
47
|
-
|
48
|
-
### 避免使用 ts-loader
|
49
|
-
|
50
|
-
默认情况下,Modern.js 使用 Babel 编译 TS 文件,开启 `output.enableTsLoader` 选项后,会使用 `ts-loader` 编译 TS 文件。
|
51
|
-
|
52
|
-
由于 `ts-loader` 需要进行额外的语法解析和类型检查,因此会导致项目编译速度变慢,请避免使用。
|
53
|
-
|
54
|
-
```typescript title="modern.config.ts"
|
55
|
-
export default defineConfig({
|
56
|
-
output: {
|
57
|
-
// 移除这项配置
|
58
|
-
enableTsLoader: true,
|
59
|
-
},
|
60
|
-
});
|
61
|
-
```
|
62
|
-
|
63
|
-
详见 [tools.tsLoader 文档](/docs/configure/app/tools/ts-loader)。
|
64
|
-
|
65
|
-
### 提升 Browserslist 范围
|
66
|
-
|
67
|
-
**减少 Polyfill 的代码量可以提升编译速度。**Modern.js 会根据项目的 Browserslist 配置范围进行代码编译,并注入相应的 Polyfill。如果项目对兼容性的要求较低,可以根据实际情况,提升 Browserslist 范围,从而减少 Polyfill 的代码量。
|
68
|
-
|
69
|
-
默认的 Browserslist 配置为:
|
70
|
-
|
71
|
-
```js
|
72
|
-
['> 0.01%', 'not dead', 'not op_mini all'];
|
73
|
-
```
|
74
|
-
|
75
|
-
比如只兼容 Chrome 53 以上的浏览器,可以改成:
|
76
|
-
|
77
|
-
```js
|
78
|
-
['Chrome >= 53'];
|
79
|
-
```
|
80
|
-
|
81
|
-
详见 [客户端兼容性 - Browserslist 配置](/docs/guides/advanced-features/compatibility#browserslist-配置)。
|
82
|
-
|
83
|
-
### 按需引入 Polyfill
|
84
|
-
|
85
|
-
明确第三方依赖不需要 Polyfill 的情况下,可以将 `output.polyfill` 设置为 `usage`,根据代码中使用到的语法,按需注入所需的 Polyfill 代码,从而减少 Polyfill 的代码量。
|
86
|
-
|
87
|
-
```typescript title="modern.config.ts"
|
88
|
-
export default defineConfig({
|
89
|
-
output: {
|
90
|
-
polyfill: 'usage',
|
91
|
-
},
|
92
|
-
});
|
93
|
-
```
|
94
|
-
|
95
|
-
详见 [客户端兼容性 - Polyfill 模式](/docs/guides/advanced-features/compatibility#polyfill-模式)。
|
96
|
-
|
97
|
-
## dev 优化策略
|
98
|
-
|
99
|
-
以下是针对 `modern dev` 进行提速的策略。
|
100
|
-
|
101
|
-
### 调整开发环境 SourceMap 格式
|
102
|
-
|
103
|
-
为了提供良好的调试体验,Modern.js 在开发环境下默认使用 webpack 提供的 `cheap-module-source-map` 格式 SourceMap。
|
104
|
-
|
105
|
-
由于生成高质量的 SourceMap 需要额外的性能开销,通过调整开发环境的 SourceMap 格式,可以提升 dev 编译速度。
|
106
|
-
|
107
|
-
比如禁用 SourceMap:
|
108
|
-
|
109
|
-
```typescript title="modern.config.ts"
|
110
|
-
export default defineConfig({
|
111
|
-
tools: {
|
112
|
-
webpackChain(chain, { env }) {
|
113
|
-
if (env === 'development') {
|
114
|
-
chain.devtool(false);
|
115
|
-
}
|
116
|
-
},
|
117
|
-
},
|
118
|
-
});
|
119
|
-
```
|
120
|
-
|
121
|
-
或是把开发环境的 SourceMap 格式设置为开销最小的 `eval` 格式:
|
122
|
-
|
123
|
-
```typescript title="modern.config.ts"
|
124
|
-
export default defineConfig({
|
125
|
-
tools: {
|
126
|
-
webpackChain(chain, { env }) {
|
127
|
-
if (env === 'development') {
|
128
|
-
chain.devtool('eval');
|
129
|
-
}
|
130
|
-
},
|
131
|
-
},
|
132
|
-
});
|
133
|
-
```
|
134
|
-
|
135
|
-
> 关于不同 SourceMap 格式之间的详细差异,请查看 [webpack - devtool](https://webpack.js.org/configuration/devtool/)。
|
136
|
-
|
137
|
-
### 调整开发环境的 Browserslist 范围
|
138
|
-
|
139
|
-
这项优化的原理与「提升 Browserslist 范围」类似,区别在于,我们可以为开发环境和生产环境设置不同的 browserslist,使开发环境下不需要引入额外的 Polyfill 编译逻辑。
|
140
|
-
|
141
|
-
比如在 `package.json` 中添加以下配置,在开发环境下只兼容最新的浏览器,在生产环境下兼容实际需要的浏览器:
|
142
|
-
|
143
|
-
```json
|
144
|
-
{
|
145
|
-
"browserslist": {
|
146
|
-
"production": [">0.2%", "not dead", "not op_mini all"],
|
147
|
-
"development": [
|
148
|
-
"last 1 chrome version",
|
149
|
-
"last 1 firefox version",
|
150
|
-
"last 1 safari version"
|
151
|
-
]
|
152
|
-
}
|
153
|
-
}
|
154
|
-
```
|
155
|
-
|
156
|
-
注意,这项优化策略会导致 `dev` 构建的产物与 `build` 构建的产物存在一定差异。
|
157
|
-
|
158
|
-
## build 优化策略
|
159
|
-
|
160
|
-
以下是针对 `modern build` 进行提速的策略。
|
161
|
-
|
162
|
-
### 禁用生产环境 SourceMap
|
163
|
-
|
164
|
-
如果项目在生产环境下不需要 SourceMap,可以通过 `disableSourceMap` 配置项关闭,从而提升 build 构建的速度。
|
165
|
-
|
166
|
-
```typescript title="modern.config.ts"
|
167
|
-
export default defineConfig({
|
168
|
-
output: {
|
169
|
-
disableSourceMap: true,
|
170
|
-
},
|
171
|
-
});
|
172
|
-
```
|
173
|
-
|
174
|
-
详见 [output.disableSourceMap](/docs/configure/app/output/disable-source-map)。
|
175
|
-
|
176
|
-
### 使用 esbuild 压缩
|
177
|
-
|
178
|
-
Modern.js 基于 esbuild 提供了代码编译和压缩的能力,在大型工程中开启后,**可以大幅度减少代码压缩所需的时间,同时有效避免 OOM (heap out of memory) 问题**。
|
179
|
-
|
180
|
-
使用 esbuild 压缩虽然带来了构建效率上的提升,但 esbuild 的压缩比例是低于 terser 的,因此**构建产物的体积会增大**,请根据业务情况酌情使用(比较适合中后台场景)。
|
181
|
-
|
182
|
-
详见 [tools.esbuild](/docs/configure/app/tools/esbuild)。
|