@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.
Files changed (67) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/en/docusaurus-plugin-content-docs/current/apis/app/commands/new.md +0 -2
  3. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/bootstrap.md +17 -3
  4. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/builder.md +46 -0
  5. package/en/docusaurus-plugin-content-docs/current.json +18 -18
  6. package/package.json +3 -3
  7. package/zh/apis/app/commands/new.md +0 -2
  8. package/zh/apis/app/runtime/app/_category_.json +1 -1
  9. package/zh/apis/app/runtime/bff/_category_.json +1 -1
  10. package/zh/apis/app/runtime/core/_category_.json +1 -1
  11. package/zh/apis/app/runtime/core/bootstrap.md +17 -3
  12. package/zh/apis/app/runtime/model/_category_.json +1 -1
  13. package/zh/apis/app/runtime/router/_category_.json +1 -1
  14. package/zh/apis/app/runtime/ssr/_category_.json +1 -1
  15. package/zh/apis/app/runtime/testing/_category_.json +1 -1
  16. package/zh/apis/app/runtime/utility/_category_.json +1 -1
  17. package/zh/apis/app/runtime/web-server/_category_.json +1 -1
  18. package/zh/configure/app/output/ssg.md +118 -114
  19. package/zh/configure/app/server/ssr.md +0 -2
  20. package/zh/guides/advanced-features/custom-app.md +8 -2
  21. package/zh/guides/advanced-features/ssg.md +74 -63
  22. package/zh/guides/advanced-features/ssr.md +76 -11
  23. package/zh/guides/basic-features/builder.md +46 -0
  24. package/zh/guides/basic-features/css/_category_.json +1 -1
  25. package/zh/guides/basic-features/css/less-sass.md +1 -14
  26. package/zh/guides/basic-features/data-fetch.md +1 -1
  27. package/zh/guides/basic-features/routes.md +32 -35
  28. package/zh/guides/concept/entries.md +4 -4
  29. package/zh/tutorials/first-app/c01-getting-started/1.2-minimal-mwa.md +2 -2
  30. package/zh/tutorials/first-app/c01-getting-started/1.4-enable-ssr.md +5 -2
  31. package/zh/tutorials/first-app/c02-generator-and-studio/2.2-boilerplates.md +4 -6
  32. package/zh/tutorials/first-app/c02-generator-and-studio/2.3-configuration.md +2 -4
  33. package/zh/tutorials/first-app/c03-ide/3.1-setting-up.md +1 -1
  34. package/zh/tutorials/first-app/c03-ide/3.2-hints-in-ide.md +44 -50
  35. package/zh/tutorials/first-app/c03-ide/3.3-autofix-in-ide.md +1 -1
  36. package/zh/tutorials/first-app/c03-ide/3.4-autofix-in-cli.md +4 -4
  37. package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.1-use-es6-plus.md +8 -21
  38. package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.2-use-typescript.md +37 -13
  39. package/zh/tutorials/first-app/c05-component/5.1-use-ui-library.md +3 -13
  40. package/zh/tutorials/first-app/c05-component/5.2-use-standalone-component.md +1 -21
  41. package/zh/tutorials/first-app/c06-css-and-component/6.1-css-in-js.md +9 -9
  42. package/zh/tutorials/first-app/c06-css-and-component/6.2-utility-class.md +9 -14
  43. package/zh/tutorials/first-app/c06-css-and-component/6.3-postcss.md +7 -7
  44. package/zh/tutorials/first-app/c06-css-and-component/6.4-design-system.md +1 -1
  45. package/zh/tutorials/first-app/c06-css-and-component/6.5-storybook.md +2 -2
  46. package/zh/tutorials/first-app/c06-css-and-component/6.6-testing.md +8 -17
  47. package/zh/tutorials/first-app/c07-app-entry/7.1-intro.md +23 -18
  48. package/zh/tutorials/first-app/c07-app-entry/7.2-add-entry-in-cli.md +30 -30
  49. package/zh/tutorials/first-app/c07-app-entry/7.3-manage-entries-by-hand.md +4 -9
  50. package/zh/tutorials/first-app/c08-client-side-routing/8.1-code-based-routing.md +66 -63
  51. package/zh/tutorials/first-app/c09-bff/9.2-enable-bff.md +35 -33
  52. package/zh/tutorials/first-app/c09-bff/9.3-fetch-bff.md +28 -102
  53. package/zh/tutorials/first-app/c10-model/10.1-application-architecture.md +4 -6
  54. package/zh/tutorials/first-app/c10-model/10.2-add-model.md +3 -3
  55. package/zh/tutorials/first-app/c10-model/10.3-use-model.md +21 -20
  56. package/zh/tutorials/first-app/c10-model/10.4-testing.md +2 -2
  57. package/zh/tutorials/first-app/c11-container/11.1-use-model-with-app-state.md +34 -68
  58. package/zh/tutorials/first-app/c11-container/11.2-add-container.md +40 -37
  59. package/zh/tutorials/first-app/c11-container/11.3-use-loader.md +6 -4
  60. package/zh/tutorials/first-app/c11-container/11.4-testing.md +2 -2
  61. package/zh/tutorials/foundations/introduction.md +1 -1
  62. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/default-alias.md +0 -25
  63. package/zh/apis/app/runtime/default-alias.md +0 -23
  64. package/zh/guides/basic-features/image.md +0 -43
  65. package/zh/guides/topic-detail/compile-speed.md +0 -182
  66. package/zh/guides/troubleshooting/compile.md +0 -379
  67. 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)】,`AllContacts` 中不再包含 UI 无关的业务逻辑实现细节,只需要使用 Model,就能实现同样的功能。
5
+ 上一章节中,我们初步引入**客户端应用架构**,从【 视图组件 】中拆分出【 业务模型(Model)】,`page.tsx` 中不再包含 UI 无关的业务逻辑实现细节,只需要使用 Model,就能实现同样的功能。
6
6
 
7
- 这一章节中,我们要进一步利用 Model 中实现的业务逻辑,让 `AllContacts` 和 `ArchivedContacts` 都从 BFF 获取数据,实现 Archive 按钮,点击按钮能把联系人归档,只显示在 Archives 列表里,不显示在 All 列表里。
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
- `ArchivedContacts` 和 `AllContacts` 需要共用同一套状态(联系人列表数据、联系人是否被归档),并且由于 Archives 列表和 All 列表都可能是第一屏页面(从不同 URL 访问),这两个组件都需要包含加载初始数据的逻辑(如果客户端没有联系人列表数据,就请求 BFF),所以这类两个组件公用的实现逻辑应该合并到一起:
57
+ 两个页面需要共用同一套状态(联系人列表数据、联系人是否被归档),并且由于 Archives 列表和 All 列表都可能是第一屏页面(从不同 URL 访问),这两个组件都需要包含加载初始数据的逻辑(如果客户端没有联系人列表数据,就请求 BFF),所以这类两个组件公用的实现逻辑应该合并到一起:
57
58
 
58
- 我们删除原有的两个组件,创建一个新的 `Contacts` 组件:
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
- rm -r src/contacts/components/*Contacts
68
- mkdir -p src/contacts/components/Contacts/
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
- rm -r src/contacts/components/*Contacts
77
- mkdir -p src/contacts/components/Contacts/
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
- :::info
132
- 由于 computed 功能还未提供,这里先在组件里将传入的数据做预处理。
133
- :::
130
+ 最后改造 `page.tsx` 和 `archived/page.ts`,利用 Contacts 实现 Archives 列表和 All 列表:
134
131
 
135
- 最后改造 `App.tsx`,利用 Contacts 实现 Archives 列表和 All 列表:
136
-
137
- ```tsx title="src/contacts/App.tsx"
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 App() {
149
- const history = useHistory();
150
- const [currentList, setList] = useState(history.location.pathname || '/');
151
- const handleSetList = (e: RadioChangeEvent) => {
152
- const { value } = e.target;
153
- setList(value);
154
- history.push(value);
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
- <div className="h-16 p-2 flex items-center justify-center">
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 App;
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
  ![display7](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/docs/11/display7.png)
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
- 修改 `App.tsx` 的代码:
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
- ├── .vscode/
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
- ```json
12
- "server": {
13
- "ssr": true,
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)。