@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
@@ -1,11 +1,11 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: 服务端渲染(SSR)
|
3
3
|
sidebar_position: 3
|
4
4
|
---
|
5
5
|
|
6
|
-
在 Modern.js
|
6
|
+
在 Modern.js 中,SSR 也是开箱即用的。开发者无需为 SSR 编写复杂的服务端逻辑,也无需关心 SSR 的运维,或是创建单独的服务。Modern.js 拥有完备的 SSR 降级策略,保证页面能够安全运行。
|
7
7
|
|
8
|
-
|
8
|
+
启用 SSR 非常简单,只需要设置 [`server.ssr`](/docs/configure/app/server/ssr) 为 `true` 即可:
|
9
9
|
|
10
10
|
```json title="package.json"
|
11
11
|
{
|
@@ -15,9 +15,9 @@ Modern.js 启用 SSR 非常简单,只需要设置 [`server.ssr`](/docs/configu
|
|
15
15
|
}
|
16
16
|
```
|
17
17
|
|
18
|
-
## SSR
|
18
|
+
## SSR 时的数据获取
|
19
19
|
|
20
|
-
Modern.js 中提供了 `useLoader` Hooks API
|
20
|
+
Modern.js 中提供了 [`useLoader`](/docs/apis/app/runtime/core/use-loader) Hooks API,用于在 SSR 环境下同构的获取数据:
|
21
21
|
|
22
22
|
```ts
|
23
23
|
const { data, loading, error } = useLoader(() => {
|
@@ -30,16 +30,14 @@ Modern.js 打破传统的 SSR 开发模式,提供了用户无感的 SSR 开发
|
|
30
30
|
不过,开发者仍然需要关注数据的兜底处理,例如 `null` 值或不符合预期的数据返回。避免在 SSR 时产生 React 渲染错误或是返回凌乱的渲染结果。
|
31
31
|
|
32
32
|
:::info 补充信息
|
33
|
-
|
33
|
+
更多相关内容可以查看[数据获取](/docs/guides/basic-features/data-fetch)。
|
34
34
|
:::
|
35
35
|
|
36
36
|
## 保持渲染一致
|
37
37
|
|
38
|
-
|
38
|
+
有些业务中,通常需要根据当前的运行容器环境特征做不同的 UI 展示,例如 [UA](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) 信息。如果处理不够仔细,此时很有可能出现不符合预期的渲染结果。
|
39
39
|
|
40
|
-
这里通过一个例子,演示当 SSR 与 CSR
|
41
|
-
|
42
|
-
在组件中添加以下代码:
|
40
|
+
这里通过一个例子,演示当 SSR 与 CSR 渲染不一致时出现的问题,在组件中添加以下代码:
|
43
41
|
|
44
42
|
```tsx
|
45
43
|
{
|
@@ -57,7 +55,7 @@ Modern.js 打破传统的 SSR 开发模式,提供了用户无感的 SSR 开发
|
|
57
55
|
Warning: Expected server HTML to contain a matching <div> in <div>.
|
58
56
|
```
|
59
57
|
|
60
|
-
|
58
|
+
这是 React 在客户端执行注水逻辑时,发现渲染结果与 SSR 渲染结果不一致造成的。虽然页面表现正常,但在复杂应用中,很有可能因此出现 DOM 层级混乱、样式混乱等问题。
|
61
59
|
|
62
60
|
:::info 注
|
63
61
|
关于注水逻辑请参考[这里](https://reactjs.org/docs/react-dom.html#hydrate)。
|
@@ -184,3 +182,70 @@ import { PreRender } from '@modern-js/runtime/ssr';
|
|
184
182
|
:::info 补充信息
|
185
183
|
`PreRender` 的详细使用可以参考[这里](/docs/apis/app/runtime/ssr/pre-render)。
|
186
184
|
:::
|
185
|
+
|
186
|
+
## Treeshaking
|
187
|
+
|
188
|
+
开启 SSR 时,Modern.js 会用相同的入口,构建出 SSR Bundle 和 CSR Bundle 两份产物。因此,在 SSR Bundle 中存在 Web API,或是在 CSR Bundle 中存在 Node API 时,都可能导致运行出错。
|
189
|
+
|
190
|
+
### 环境变量区分
|
191
|
+
|
192
|
+
在组件中可以直接使用 EdenX 内置的环境变量 `EDENX_TARGET` 进行判断,方便在构建时删除无用代码:
|
193
|
+
|
194
|
+
```ts
|
195
|
+
export default () => {
|
196
|
+
if (process.env.EDENX_TARGET === 'node') {
|
197
|
+
console.log('server render')
|
198
|
+
} else {
|
199
|
+
console.log('client render')
|
200
|
+
}
|
201
|
+
}
|
202
|
+
```
|
203
|
+
|
204
|
+
在 SSR 中直接调用 RPC 接口时,该环境变量会非常有用,因为 RPC 调用时往往会执行到浏览器中无法运行的代码。
|
205
|
+
|
206
|
+
:::note
|
207
|
+
更多内容可以查看[环境变量](/docs/guides/basic-features/env-vars)。
|
208
|
+
:::
|
209
|
+
|
210
|
+
### 文件后缀区分
|
211
|
+
|
212
|
+
但有时,这种 Treeshaking 的方式并不能保证代码被完全分离。EdenX 也支持通过 `.node.` 后缀的文件来区分 SSR Bundle 和 CSR Bundle 产物的打包文件。
|
213
|
+
|
214
|
+
例如存在 `client-sdk` 中直接使用了 Web API:
|
215
|
+
|
216
|
+
```ts
|
217
|
+
// client-sdk
|
218
|
+
export const href = location.href;
|
219
|
+
```
|
220
|
+
|
221
|
+
这时候直接引用到组件中,会造成 SSR 报错。可以创建同名的 `.ts` 和 `.node.ts` 文件做一层代理:
|
222
|
+
|
223
|
+
```ts title="compat.ts"
|
224
|
+
export { href } from 'client-sdk';
|
225
|
+
```
|
226
|
+
|
227
|
+
```ts title="compat.node.ts"
|
228
|
+
export const href = '';
|
229
|
+
```
|
230
|
+
|
231
|
+
在文件中直接引入 `./compat`,此时 SSR 环境下会优先使用 `.node.ts` 后缀的文件,CSR 环境下会使用 `.ts` 后缀的文件。
|
232
|
+
|
233
|
+
```ts title="App.tsx"
|
234
|
+
import { href } from './compat'
|
235
|
+
|
236
|
+
export default () => {
|
237
|
+
return <div onClick={() => { console.log(href) }}></div>
|
238
|
+
}
|
239
|
+
```
|
240
|
+
|
241
|
+
### 独立文件
|
242
|
+
|
243
|
+
上述两种方式,都会为开发者带来一些心智负担。Modern.js 正在基于[嵌套路由](/docs/guides/basic-features/routes)开发设计更简单的方案来分离 CSR 和 SSR 的代码。。
|
244
|
+
|
245
|
+
## 接口请求
|
246
|
+
|
247
|
+
在 SSR 中发起接口请求时,开发者有时自己封装了同构的请求工具。部分接口需要传递用户 Cookie,开发者可以通过 [`useRuntimeContext`](/docs/apis/app/runtime/core/use-runtime-context) API 获取到请求头来实现。
|
248
|
+
|
249
|
+
需要注意的是,此时获取到的是 HTML 请求的请求头,不一定适用于接口请求,因此**千万不能**透传所有请求头。并且,一些后端接口,或是通用网关,会根据请求头中的信息做校验,全量透传容易出现各种难以排查的问题,推荐**按需透传**。
|
250
|
+
|
251
|
+
如果实在需要透传所有请求头,请务必过滤 `host` 字段。
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
title: 构建能力
|
3
|
+
sidebar_position: 2
|
4
|
+
---
|
5
|
+
|
6
|
+
**Modern.js 的构建能力由 [Modern.js Builder](https://modernjs.dev/builder) 提供。**
|
7
|
+
|
8
|
+
Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向现代 Web 开发场景的构建引擎,可以脱离 Modern.js 被独立使用。Modern.js Builder 同时支持 webpack 和 rspack 等多种打包工具,默认情况下使用最成熟的 webpack 进行打包。
|
9
|
+
|
10
|
+
## 构建架构
|
11
|
+
|
12
|
+
从构建的角度看,Modern.js 分为三层架构,从上到下依次是:
|
13
|
+
|
14
|
+
- 上层研发框架:Modern.js。
|
15
|
+
- 通用构建引擎:Modern.js Builder。
|
16
|
+
- 底层打包工具:webpack 和 rspack。
|
17
|
+
|
18
|
+
<img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/zq-uylkvT/ljhwZthlaukjlkulzlp/builder-layers-1117.png" style={{ maxWidth: '540px' }} />
|
19
|
+
|
20
|
+
## 构建文档
|
21
|
+
|
22
|
+
由于 Modern.js Builder 是一个可独立使用的模块,我们为它提供了单独的文档,文档地址为:[modernjs.dev/builder](https://modernjs.dev/builder)。
|
23
|
+
|
24
|
+
在该文档中,你可以了解到 Modern.js Builder 的详细介绍,同时也可以找到各个构建能力的完整使用指南。当你遇到构建方面的需求或问题时,建议你优先阅读 Modern.js Builder 文档来解决。
|
25
|
+
|
26
|
+
## 构建配置
|
27
|
+
|
28
|
+
Modern.js 的配置继承自 Modern.js Builder,因此你可以在 Modern.js 中使用 Modern.js Builder 提供的所有构建配置。
|
29
|
+
|
30
|
+
以 Modern.js Builder 的 `html.title` 配置项为例,你可以直接在 `modern.config.ts` 文件中使用该配置项,它会被自动传递给 Modern.js Builder。
|
31
|
+
|
32
|
+
```ts title="modern.config.js"
|
33
|
+
export default defineConfig({
|
34
|
+
html: {
|
35
|
+
title: 'example',
|
36
|
+
},
|
37
|
+
});
|
38
|
+
```
|
39
|
+
|
40
|
+
关于构建配置的详细说明,请参考 [「Modern.js Builder - Builder 配置」](https://modernjs.dev/builder/zh/guide/basic/builder-config.html)。
|
41
|
+
|
42
|
+
## 构建能力
|
43
|
+
|
44
|
+
Modern.js Builder 提供了丰富的构建能力,包括 JavaScript 编译、CSS 编译、静态资源处理、代码热更新、代码压缩、TS 类型检查等几十种能力。
|
45
|
+
|
46
|
+
我们推荐你阅读 [「Modern.js Builder - 功能导航」](https://modernjs.dev/builder/zh/guide/features.html) 来了解 Modern.js Builder 提供的所有构建能力。
|
@@ -4,20 +4,7 @@ sidebar_position: 4
|
|
4
4
|
|
5
5
|
# Less 和 Sass
|
6
6
|
|
7
|
-
[Less](https://lesscss.org/) 和 [Sass](https://sass-lang.com/) 是常用的两种 CSS 预处理器,Modern.js
|
8
|
-
|
9
|
-
## 启用 Less 或 Sass
|
10
|
-
|
11
|
-
为了使用 Less 或 Sass 编译能力,我们需要先启用对应的功能。
|
12
|
-
|
13
|
-
以 Less 为例,在当前项目根目录执行 new 命令, 并选择 **启用 Less 支持** 即可。
|
14
|
-
|
15
|
-
```bash
|
16
|
-
$ pnpm run new
|
17
|
-
? 请选择你想要的操作
|
18
|
-
? 启用可选功能 (Use arrow keys)
|
19
|
-
❯ 启用 Less 支持
|
20
|
-
```
|
7
|
+
[Less](https://lesscss.org/) 和 [Sass](https://sass-lang.com/) 是常用的两种 CSS 预处理器,Modern.js 内置了 Less 和 Sass 编译能力的支持。
|
21
8
|
|
22
9
|
## 自定义配置
|
23
10
|
|
@@ -3,7 +3,7 @@ title: 路由
|
|
3
3
|
sidebar_position: 1
|
4
4
|
---
|
5
5
|
|
6
|
-
Modern.js 内置了对 [React Router 6](https://reactrouter.com/en/main) 的**部分**支持,并提供了多种类型的路由模式。根据不同[入口](/docs/guides/concept/entries)
|
6
|
+
Modern.js 内置了对 [React Router 6](https://reactrouter.com/en/main) 的**部分**支持,并提供了多种类型的路由模式。根据不同[入口](/docs/guides/concept/entries)类型,将路由分为三种模式,分别是**约定式路由**,**自控式路由**和**其他路由方案**。
|
7
7
|
|
8
8
|
:::note
|
9
9
|
本小节提到的路由,都是客户端路由,即 SPA 路由。
|
@@ -219,40 +219,21 @@ export default const ErrorBoundary = () => {
|
|
219
219
|
|
220
220
|
## 自控式路由
|
221
221
|
|
222
|
-
以 `routes/` 为约定的入口,Modern.js 不会多路由做额外的操作,开发者可以自行使用 React Router 6 的 API
|
223
|
-
|
224
|
-
例如:
|
222
|
+
以 `routes/` 为约定的入口,Modern.js 不会多路由做额外的操作,开发者可以自行使用 React Router 6 的 API 进行开发,例如:
|
225
223
|
|
226
224
|
```tsx
|
227
|
-
import {
|
228
|
-
|
229
|
-
Routes,
|
230
|
-
BrowserRouter,
|
231
|
-
Outlet,
|
232
|
-
} from '@modern-js/runtime/router';
|
225
|
+
import { Route, Routes, BrowserRouter } from '@modern-js/runtime/router';
|
226
|
+
import { StaticRouter } from '@modern-js/runtime/router/server';
|
233
227
|
|
228
|
+
const Router = typeof window === 'undefined' ? StaticRouter : BrowserRouter;
|
234
229
|
export default () => {
|
235
230
|
return (
|
236
|
-
<
|
237
|
-
<
|
238
|
-
<
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
element={
|
243
|
-
<div>
|
244
|
-
User Layout
|
245
|
-
<Outlet />
|
246
|
-
</div>
|
247
|
-
}
|
248
|
-
>
|
249
|
-
<Route index element={<div>user</div>} />
|
250
|
-
<Route path="profile" element={<div>profile</div>} />
|
251
|
-
</Route>
|
252
|
-
<Route path="about" element={<div>about</div>} />
|
253
|
-
</Routes>
|
254
|
-
</BrowserRouter>
|
255
|
-
</div>
|
231
|
+
<Router location={context.request.pathname}>
|
232
|
+
<Routes>
|
233
|
+
<Route index element={<div>index</div>} />
|
234
|
+
<Route path="about" element={<div>about</div>} />
|
235
|
+
</Routes>
|
236
|
+
</Router>
|
256
237
|
);
|
257
238
|
};
|
258
239
|
```
|
@@ -261,11 +242,27 @@ export default () => {
|
|
261
242
|
在自控式路由下,开发者如果希望在 SSR 中使用 React Router 6 中 [Loader API](https://reactrouter.com/en/main/hooks/use-loader-data#useloaderdata) 的能力会相对复杂,推荐直接使用约定式路由。Modern.js 已经为你封装好了一切。
|
262
243
|
|
263
244
|
<!-- Todo 嵌套路由带来的优化可以补充下文档-->
|
264
|
-
如果项目只想升级到 React Router 6,而不希望使用嵌套路由带来的优化,那[useLoader](/docs/apis/app/runtime/core/use-loader) 在 SSR 下仍然可以工作。
|
245
|
+
如果项目只想升级到 React Router 6,而不希望使用嵌套路由带来的优化,那 [useLoader](/docs/apis/app/runtime/core/use-loader) 在 SSR 下仍然可以工作。
|
265
246
|
:::
|
266
247
|
|
267
|
-
##
|
248
|
+
## 其他路由方案
|
268
249
|
|
269
|
-
|
270
|
-
|
271
|
-
|
250
|
+
默认情况下,Modern.js 会开启内置的路由方案,即 React Router。
|
251
|
+
|
252
|
+
```js
|
253
|
+
export default defineConfig({
|
254
|
+
runtime: {
|
255
|
+
router: true,
|
256
|
+
}
|
257
|
+
})
|
258
|
+
```
|
259
|
+
|
260
|
+
Modern.js 从 `@modern-js/runtime/router` 命名空间暴露了 React Router 的 API 供开发者使用,保证开发者和 Modern.js 中使用同一份代码。另外,这种情况下,React Router 的代码会被打包到 JS 产物中。如果项目已经有自己的路由方案,或者不需要使用客户端路由,可以关闭这个功能。
|
261
|
+
|
262
|
+
```js
|
263
|
+
export default defineConfig({
|
264
|
+
runtime: {
|
265
|
+
router: false,
|
266
|
+
}
|
267
|
+
})
|
268
|
+
```
|
@@ -91,13 +91,13 @@ Modern.js 会将和 `package.json` 中 `name` 同名的目录作为主入口,
|
|
91
91
|
|
92
92
|
如果入口为 `routes/` 约定,Modern.js 会在启动时扫描 `routes` 下的文件,基于文件约定,自动生成客户端路由(react-router)。
|
93
93
|
|
94
|
-
详细内容可以参考[路由](/docs/guides/basic-features/routes)
|
94
|
+
详细内容可以参考[路由](/docs/guides/basic-features/routes)。
|
95
95
|
|
96
96
|
### App 入口
|
97
97
|
|
98
98
|
如果入口为 `App.[jt]sx?` 约定,开发者可以在这个文件中自由的设置客户端路由,或者不设置客户端路由。
|
99
99
|
|
100
|
-
详细内容可以参考[路由](/docs/guides/basic-features/routes)
|
100
|
+
详细内容可以参考[路由](/docs/guides/basic-features/routes)。
|
101
101
|
|
102
102
|
### Index 入口
|
103
103
|
|
@@ -105,12 +105,12 @@ Modern.js 会将和 `package.json` 中 `name` 同名的目录作为主入口,
|
|
105
105
|
|
106
106
|
如果入口为 `index.[jt]sx?` 约定,Modern.js 会根据该文件是否存在默认的组件导出,来决定构建行为。
|
107
107
|
|
108
|
-
详细内容可以参考[自定义 App](/docs/guides/advanced-features/custom-app)
|
108
|
+
详细内容可以参考[自定义 App](/docs/guides/advanced-features/custom-app)。
|
109
109
|
|
110
110
|
## 配置入口
|
111
111
|
|
112
112
|
在 Modern.js 中,除了使用文件约定生成入口外,还可以在 `modern.config.[jt]s` 中手动配置入口。
|
113
113
|
|
114
114
|
:::tip
|
115
|
-
详情可以查看 [source.entries](/docs/configure/app/source/entries)
|
115
|
+
详情可以查看 [source.entries](/docs/configure/app/source/entries)。
|
116
116
|
:::
|
@@ -75,10 +75,10 @@ ni package.json
|
|
75
75
|
"dependencies": {
|
76
76
|
"react": "^17",
|
77
77
|
"react-dom": "^17",
|
78
|
-
"@modern-js/runtime": "^
|
78
|
+
"@modern-js/runtime": "^2.0.0"
|
79
79
|
},
|
80
80
|
"devDependencies": {
|
81
|
-
"@modern-js/app-tools": "^
|
81
|
+
"@modern-js/app-tools": "^2.0.0"
|
82
82
|
}
|
83
83
|
}
|
84
84
|
```
|
@@ -6,18 +6,21 @@ title: 启用 SSR
|
|
6
6
|
|
7
7
|
在项目根目录下创建 `modern.config.js`:
|
8
8
|
|
9
|
+
import Tabs from '@theme/Tabs';
|
10
|
+
import TabItem from '@theme/TabItem';
|
11
|
+
|
9
12
|
<Tabs>
|
10
13
|
<TabItem value="macOS" label="macOS" default>
|
11
14
|
|
12
15
|
```bash
|
13
|
-
touch modern.config.
|
16
|
+
touch modern.config.ts
|
14
17
|
```
|
15
18
|
|
16
19
|
</TabItem>
|
17
20
|
<TabItem value="Windows" label="Windows">
|
18
21
|
|
19
22
|
```bash
|
20
|
-
ni modern.config.
|
23
|
+
ni modern.config.ts
|
21
24
|
```
|
22
25
|
|
23
26
|
</TabItem>
|
@@ -15,17 +15,15 @@ title: 样板文件
|
|
15
15
|
├── .prettierrc
|
16
16
|
├── .vscode
|
17
17
|
├── README.md
|
18
|
-
├── modern.config.
|
18
|
+
├── modern.config.js
|
19
19
|
├── package.json
|
20
|
-
├── pnpm-lock.yaml
|
21
20
|
├── src
|
22
21
|
│ ├── .eslintrc.js
|
23
|
-
│ ├── modern-app-env.d.ts
|
24
22
|
│ └── routes
|
25
23
|
│ ├── index.css
|
26
|
-
│ ├── layout.
|
27
|
-
│ └── page.
|
28
|
-
└──
|
24
|
+
│ ├── layout.jsx
|
25
|
+
│ └── page.jsx
|
26
|
+
└── pnpm-lock.yaml
|
29
27
|
```
|
30
28
|
|
31
29
|
和上一章节手动创建出来的项目一样,仍然是零配置、极简和轻量的,但功能更完整,最佳实践开箱即用,比如:
|
@@ -2,11 +2,9 @@
|
|
2
2
|
title: 配置项目
|
3
3
|
---
|
4
4
|
|
5
|
-
通过命令行工具创建的 Modern.js
|
5
|
+
通过命令行工具创建的 Modern.js 项目,会默认生成 `modern.config.js` 配置文件。
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
这两处都可以进行 Modern.js 项目的配置,并且 `modernConfig` 字段中的配置优先级高于 `modern.config.js` 中相同的内容。
|
7
|
+
Modern.js 也支持使用 `package.json` 文件中的 `modernConfig` 字段进行配置,两个位置不支持同时配置同一字段,推荐使用 `modern.config.js` 配置文件进行配置。
|
10
8
|
|
11
9
|
:::info 注
|
12
10
|
|
@@ -15,7 +15,7 @@ cd hello-modern/
|
|
15
15
|
code .
|
16
16
|
```
|
17
17
|
|
18
|
-

|
19
19
|
|
20
20
|
:::info 补充信息
|
21
21
|
必须打开项目根目录,不能打开其他子目录或父目录,否则 IDE 支持不会生效。
|
@@ -2,65 +2,59 @@
|
|
2
2
|
title: IDE 中的自动提示
|
3
3
|
---
|
4
4
|
|
5
|
-
打开任意 JS/TS 文件(比如 `src/
|
5
|
+
打开任意 JS/TS 文件(比如 `src/routes/page.tsx`),底部状态栏右侧应该有显示 ESLint,点击可以看到运行 log,应该没有报错。
|
6
6
|
|
7
|
-
接下来对 `
|
7
|
+
接下来对 `page.jsx` 代码做如下修改(修改过程中不要保存),增加无用的函数参数、去掉换行、单引号改成双引号、增加缩进(可以直接复制下面的代码替换 App.jsx 的内容),注意修改过程中**先不要保存文件**。
|
8
8
|
|
9
9
|
```js
|
10
|
-
import
|
10
|
+
import './index.css';
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
const App = (a) => (
|
15
|
-
<Switch>
|
16
|
-
<Route exact={true} path="/">
|
12
|
+
const Index = (a) => (
|
17
13
|
<div className="container-box">
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
</main>
|
48
|
-
<footer className="footer">
|
49
|
-
<a href="#" target="_blank" rel="noopener noreferrer">
|
50
|
-
Powered by Modern.JS
|
51
|
-
</a>
|
52
|
-
</footer>
|
14
|
+
<main>
|
15
|
+
<div className='logo'>
|
16
|
+
<img
|
17
|
+
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ylaelkeh7nuhfnuhf/modernjs-cover.png"
|
18
|
+
width="300"
|
19
|
+
alt="Modern.js Logo"
|
20
|
+
/>
|
21
|
+
</div>
|
22
|
+
<p className="description">
|
23
|
+
Get started by editing <code className="code">src/routes/page.tsx</code>
|
24
|
+
</p>
|
25
|
+
<div className="grid">
|
26
|
+
<a href="https://modernjs.dev/docs/start" className="card">
|
27
|
+
<h2>Quick Start</h2>
|
28
|
+
</a>
|
29
|
+
<a href="https://modernjs.dev/docs/guides" className="card">
|
30
|
+
<h2>Handbook</h2>
|
31
|
+
</a>
|
32
|
+
<a href="https://modernjs.dev/docs/apis/app/overview" className="card">
|
33
|
+
<h2>API Reference </h2>
|
34
|
+
</a>
|
35
|
+
<a
|
36
|
+
href="https://modernjs.dev/blog"
|
37
|
+
target="_blank"
|
38
|
+
rel="noopener noreferrer"
|
39
|
+
className="card"
|
40
|
+
>
|
41
|
+
<h2>Blog</h2>
|
42
|
+
</a>
|
53
43
|
</div>
|
54
|
-
</
|
55
|
-
<
|
56
|
-
<
|
57
|
-
|
58
|
-
|
44
|
+
</main>
|
45
|
+
<footer className="footer">
|
46
|
+
<a href="https://modernjs.dev" target="_blank" rel="noopener noreferrer">
|
47
|
+
Powered by Modern.js
|
48
|
+
</a>
|
49
|
+
</footer>
|
50
|
+
</div>
|
59
51
|
);
|
60
52
|
|
61
|
-
export default
|
53
|
+
export default Index;
|
54
|
+
|
55
|
+
|
62
56
|
```
|
63
57
|
|
64
58
|
可以在 VS Code 中看到修改过的代码出现了问题提示,点击底部界面中的 Problems 一栏,可以看到问题列表。
|
65
59
|
|
66
|
-

|
@@ -6,6 +6,6 @@ title: IDE 中的自动修复
|
|
6
6
|
|
7
7
|
只剩下**无用的函数参数**问题,需要人工修复:
|
8
8
|
|
9
|
-

|
10
10
|
|
11
11
|
问题提示中,显示了这个问题来自 ESLint 的 `no-unused-vars` 规则,带下划线的是 ESLint 规则名称,按住 CMD/Alt 键点击,可以打开这条规则的文档,查看问题的解释和解决方法。
|
@@ -7,10 +7,10 @@ title: 命令行中的自动修复
|
|
7
7
|
我们添加一段可自动修复的问题代码(如果在 VS Code 里添加,保存时会自动修复,所以用 CLI 来添加):
|
8
8
|
|
9
9
|
```bash
|
10
|
-
echo ';' >> src/
|
10
|
+
echo ';' >> src/routes/page.jsx
|
11
11
|
```
|
12
12
|
|
13
|
-
打开 `
|
13
|
+
打开 `page.tsx`,可以看到末尾多了一个 ';',有问题提示。
|
14
14
|
|
15
15
|
提交代码:
|
16
16
|
|
@@ -24,7 +24,7 @@ git status
|
|
24
24
|
手动把参数 a 的问题修复(删除 a),再次添加 ';',提交代码:
|
25
25
|
|
26
26
|
```bash
|
27
|
-
echo ';' >> src/
|
27
|
+
echo ';' >> src/routes/page.jsx
|
28
28
|
git commit -am "test: 再次测试准入检查"
|
29
29
|
git log HEAD --stat --graph --name-status
|
30
30
|
```
|
@@ -43,7 +43,7 @@ git log HEAD --stat --graph --name-status
|
|
43
43
|
如果要对整个仓库的所有文件做 lint 检查和自动修复,可以手动执行 `lint` 命令,比如:
|
44
44
|
|
45
45
|
```bash
|
46
|
-
echo ';' >> src/
|
46
|
+
echo ';' >> src/routes/page.jsx
|
47
47
|
pnpm run lint
|
48
48
|
```
|
49
49
|
|
@@ -6,22 +6,9 @@ title: 使用 ES6+ 语法
|
|
6
6
|
|
7
7
|
这一章节中,我们沿用上一章节的项目和编码环境,实现一个最简单的联系人列表。
|
8
8
|
|
9
|
-
Modern.js 支持 `src` 目录下直接使用 ES6+(ES2015
|
9
|
+
Modern.js 支持 `src` 目录下直接使用 ES6+(ES2015+)语法。
|
10
10
|
|
11
|
-
|
12
|
-
2. 部分很有用且确定性较强(重构也容易)的 [Stage 1(提案阶段)](https://github.com/tc39/proposals/blob/master/stage-1-proposals.md)、[Stage 2(草案阶段)](https://github.com/tc39/proposals#stage-2)、[Stage 3(候选阶段)](https://github.com/tc39/proposals#stage-3)语法,比如:
|
13
|
-
|
14
|
-
- [Decorators](https://babeljs.io/docs/en/babel-plugin-proposal-decorators)(默认使用 legacy 提案,可通过 `output.enableLatestDecorators` 使用新版提案)
|
15
|
-
- [Class Public Properties](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties)
|
16
|
-
- [Class Private Properties](https://babeljs.io/docs/en/babel-plugin-proposal-private-property-in-object)、[Class Private Methods](https://babeljs.io/docs/en/babel-plugin-proposal-private-methods)
|
17
|
-
- [Pipeline Operator](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator)(默认为 minimal 提案)
|
18
|
-
- [Partial Application](https://babeljs.io/docs/en/babel-plugin-proposal-partial-application)
|
19
|
-
- [Bind Operator](https://babeljs.io/docs/en/babel-plugin-proposal-function-bind)
|
20
|
-
- [export default from](https://babeljs.io/docs/en/babel-plugin-proposal-export-default-from), [export namespace from](https://babeljs.io/docs/en/babel-plugin-proposal-export-namespace-from)
|
21
|
-
- [Optional Catch Binding](https://babeljs.io/docs/en/babel-plugin-proposal-optional-catch-binding)
|
22
|
-
- [Numeric Separator](https://babeljs.io/docs/en/babel-plugin-proposal-numeric-separator)
|
23
|
-
|
24
|
-
我们把 `src/App.jsx` 改成:
|
11
|
+
我们把 `routes/page.jsx` 改成:
|
25
12
|
|
26
13
|
```js
|
27
14
|
const getAvatar = users =>
|
@@ -30,18 +17,18 @@ const getAvatar = users =>
|
|
30
17
|
avatar: `https://avatars.dicebear.com/v2/identicon/${user.name}.svg`,
|
31
18
|
}));
|
32
19
|
|
33
|
-
const
|
34
|
-
[
|
20
|
+
const getMockData = () =>
|
21
|
+
getAvatar([
|
35
22
|
{ name: 'Thomas', email: 'w.kccip@bllmfbgv.dm' },
|
36
23
|
{ name: 'Chow', email: 'f.lfqljnlk@ywoefljhc.af' },
|
37
24
|
{ name: 'Bradley', email: 'd.wfovsqyo@gpkcjwjgb.fr' },
|
38
25
|
{ name: 'Davis', email: '"t.kqkoj@utlkwnpwk.nu' },
|
39
|
-
]
|
26
|
+
]);
|
40
27
|
|
41
|
-
function
|
28
|
+
function Index() {
|
42
29
|
return (
|
43
30
|
<ul>
|
44
|
-
{
|
31
|
+
{getMockData().map(({ name, avatar, email }) => (
|
45
32
|
<li key={name}>
|
46
33
|
<img src={avatar} width={60} height={60} /> ---
|
47
34
|
<span>{name}</span> ---
|
@@ -52,7 +39,7 @@ function App() {
|
|
52
39
|
);
|
53
40
|
}
|
54
41
|
|
55
|
-
export default
|
42
|
+
export default Index;
|
56
43
|
```
|
57
44
|
|
58
45
|
可以看到其中使用了多种 ES6+ 语法(注意生成 mockData 过程中使用了 [Pipeline Operator](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator) 语法),都不需要做任何配置。
|