Skip to content

Commit

Permalink
Merge: master
Browse files Browse the repository at this point in the history
  • Loading branch information
fz6m committed Nov 7, 2023
2 parents 36f0aa1 + b3b956a commit 0657e5e
Show file tree
Hide file tree
Showing 52 changed files with 326 additions and 176 deletions.
5 changes: 5 additions & 0 deletions docs/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,27 @@ export default defineConfig({
{
title: '介绍',
link: '/docs/introduce/introduce',
activePath: '/docs/introduce',
},
{
title: '指南',
link: '/docs/guides/getting-started',
activePath: '/docs/guides',
},
{
title: 'API',
link: '/docs/api/api',
activePath: '/docs/api',
},
{
title: 'Umi Max',
link: '/docs/max/introduce',
activePath: '/docs/max',
},
{
title: '博客',
link: '/blog/umi-4-rc',
activePath: '/blog',
},
],
},
Expand Down
3 changes: 1 addition & 2 deletions docs/docs/blog/mfsu-faster-than-vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ Umi 4 中同时支持 webpack 和 vite 两种构建方式,跑通了后,迫
<span style={{ color: 'red', fontWeight: 'bold' }}>
两个示例、四种模式、四个维度的对比。
</span>
两个示例分别是大型的全量 ant-design-pro 和小型的 libs example;四种模式分别是 webpack、webpack
+ MFSU、webpack + MFSU with esbuild mode、Vite in umi;四个维度分别是无缓存的冷启动、有缓存的热启动、修改代码后的热更新、页面打开速度。
两个示例分别是大型的全量 ant-design-pro 和小型的 libs example;四种模式分别是 webpack、webpack + MFSU、webpack + MFSU with esbuild mode、Vite in umi;四个维度分别是无缓存的冷启动、有缓存的热启动、修改代码后的热更新、页面打开速度。
</p>

多说几点和统计相关的。上述 webpack 相关模式全部开启物理缓存;Vite 是 Umi 中集成后的 Vite,也有担心是不是 Umi 对于 Vite 的误用,经开发者确认,基本排除误用的可能性,大段时间消耗在预编译依赖上;Ant Design Pro 中包含 less 的使用,这是使用 esbuild 无法加速的部分,这有影响,但对于不同模式应该是公平的;下图数据是本地用 13-inch M1 2022 重启电脑后跑 5 次后平均取值的结果;Vite 的热更速度没统计是因为由于 esm 的特性,改完后要等请求过来后处理完才算结束,无法统计,但肯定是很快的。
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/docs/api/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ crossorigin: {}

## cssMinifierOptions

- 类型:`Object`
- 类型:`object`
- 默认值:`{}`

`cssMinifier` CSS 压缩工具配置选项。
Expand Down Expand Up @@ -904,7 +904,7 @@ import { Icon } from 'umi';

## lessLoader

- 类型:`Object`
- 类型:`object`
- 默认值:`{ modifyVars: userConfig.theme, javascriptEnabled: true }`

设置 less-loader 的 Options。具体参考参考 [less-loader 的 Options](https://github.com/webpack-contrib/less-loader#lessoptions)
Expand Down Expand Up @@ -1450,7 +1450,7 @@ import SmileUrl, { ReactComponent as SvgSmile } from './smile.svg';
```js
// 兼容 ie11
targets: {
ie: 11;
ie: 11,
}
```

Expand Down
7 changes: 5 additions & 2 deletions docs/docs/docs/guides/boilerplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ toc: content
Umi 官方提供了一个脚手架 ,可以轻松快速创建一个项目:

```bash
pnpm dlx create-umi@latest
# 在当前文件夹下创建项目
pnpm create umi
# 在当前目录的 my-umi-app 文件夹下创建项目
pnpm create umi my-umi-app
```

这个命令会安装 `create-umi` 脚手架并自动运行,运行后提供了两个可选项可以选择
这个命令会安装 `create-umi` 脚手架并自动运行,运行后提供了两个可选项

1. Pick Npm Client - 选择 Npm 客户端

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/docs/guides/debug.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ toc: content

## 调试 dev 产物

如果你需要在 dev 阶段调试项目的构建产物,以 `umi.js` 举例。先将原来的 `umi.js` 下载到当前项目根目录下。根据调试需要进行编辑后,刷新浏览器,项目使用的 `umi.js` 就替换成了根目录下的 `umi.js` 文件。调试完毕需要恢复就直接删除根目录的 `umi.js` 即可。
如果你需要在 dev 阶段调试项目的构建产物,以 `umi.js` 举例。先将原来的 `umi.js` 下载到当前项目根目录下。根据调试需要进行编辑后,刷新浏览器,项目使用的 `umi.js` 就替换成了根目录下的 `umi.js` 文件。如果调试完毕需要恢复,直接删除根目录的 `umi.js` 即可。

举例:
```bash
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/docs/guides/directory-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ toc: content
---
# 目录结构

这里罗列了 Umi 项目中约定(或推荐)的目录结构,在项目开发中,请遵照这个目录结构组织代码。
这里罗列了 Umi 项目中约定或推荐的目录结构,在项目开发中,请遵照这个目录结构组织代码。

```bash
.
Expand Down
12 changes: 6 additions & 6 deletions docs/docs/docs/guides/env-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Umi 可以通过环境变量来完成一些特殊的配置和功能。

### 执行命令时设置

例如需要改变 `umi dev` 开发服务器的端口,进可以通过如下命令实现
例如需要改变 `umi dev` 开发服务器的端口,可以通过如下命令实现

```bash
# OS X, Linux
Expand All @@ -20,7 +20,7 @@ $ PORT=3000 umi dev
$ set PORT=3000&&umi dev
```

如果需要同时在不同的操作系统中使用环境变量,推荐使用工具 [cross-env](https://github.com/kentcdodds/cross-env)
如果需要同时在不同的操作系统中使用环境变量,推荐使用工具 [cross-env](https://github.com/kentcdodds/cross-env)

```bash
$ pnpm install cross-env -D
Expand Down Expand Up @@ -78,7 +78,7 @@ CONCAT=$FOO$BAR # CONCAT=foobar

注意:

* APP_ROOT 不能配在 .env 中,只能在命令行里添加
* `APP_ROOT` 不能配在 `.env` 中,只能在命令行里添加


### ANALYZE
Expand All @@ -101,7 +101,7 @@ $ ANALYZE=1 umi build

### COMPRESS

默认压缩 CSS 和 JS,值为 none 时不压缩,build 时有效。
默认压缩 CSS 和 JS,值为 `none` 时不压缩,`build` 时有效。

### DID_YOU_KNOW

Expand All @@ -113,11 +113,11 @@ $ ANALYZE=1 umi build

### FS_LOGGER

默认会开启保存物理日志,值为 none 时不保存,同时针对 webcontainer 场景(比如 stackbliz)暂不保存。
默认会开启保存物理日志,值为 `none` 时不保存,同时针对 webcontainer 场景(比如 stackbliz)暂不保存。

### HMR

默认开启 HMR 功能,值为 none 时关闭。
默认开启 HMR 功能,值为 `none` 时关闭。

### HOST

Expand Down
12 changes: 6 additions & 6 deletions docs/docs/docs/guides/generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ toc: content
---
# 微生成器

Umi 中内置了众多微生成器,协助你在开发中快速的完成一些繁琐的工作
Umi 中内置了众多微生成器,协助你在开发中快速地完成一些繁琐的工作

## 如何使用

Expand All @@ -22,7 +22,7 @@ $ umi g

### 页面生成器

快速生成一个新页面,有以下使用方式
快速生成一个新页面,有以下多种使用方式

#### 基本使用

Expand Down Expand Up @@ -124,7 +124,7 @@ const count = 10

##### 预设变量

在上一小节生成的内容中,我们并没有指定 `name`但它被还是设置值了。这是因为它属于模板中预设的变量,下面是目前页面模板所有的预设变量:
在上一小节生成的内容中,我们并没有指定 `name`但它还是被设置为了一个值。这是因为它属于模板中预设的变量,下面是目前页面模板所有的预设变量:

|参数|默认值|说明|
|:-:|:-:|:-|
Expand Down Expand Up @@ -203,7 +203,7 @@ Write: src/components/Orange/component.tsx

#### 对组件模板内容进行自定义

[页面生成器](#对页面模板内容进行自定义)相同,组件生成器也支持对模板内容自定义。首先,先将原始模板写入到项目的 `/templates/component` 目录:
[页面生成器](#对页面模板内容进行自定义)相同,组件生成器也支持对模板内容自定义。首先,将原始模板写入到项目的 `/templates/component` 目录:

```bash
$umi g component --eject
Expand Down Expand Up @@ -309,7 +309,7 @@ info - Write jest.config.ts

### Tailwind CSS 配置生成器

为项目开启 [Tailwind CSS](https://tailwindcss.com/) 配置,命令执行后,`umi` 会生成 Tailwind CSS 和安装相应的的依赖
为项目开启 [Tailwind CSS](https://tailwindcss.com/) 配置,命令执行后,`umi` 会生成 Tailwind CSS 和安装相应的依赖

```bash
$umi g tailwindcss
Expand All @@ -323,7 +323,7 @@ info - Write tailwind.css

### DvaJS 配置生成器

为项目开启 [Dva](https://dvajs.com/) 配置,命令执行后,`umi` 会生成 Dva
为项目开启 [Dva](https://dvajs.com/) 配置,命令执行后,`umi` 会生成 Dva

```bash
$umi g dva
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/docs/guides/mock.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default {

### 请求方法

Http 的请求方法是 GET 时,可以省略方法部分,只需要路径即可,例如:
HTTP 的请求方法是 GET 时,可以省略方法部分,只需要路径即可,例如:

```ts
// ./mock/users.ts
Expand Down Expand Up @@ -140,7 +140,7 @@ MOCK=none umi dev

## 引入 Mock.js

在 Mock 中我们经常使用 [Mock.js](http://mockjs.com/) 来帮我们方便的生成随机的模拟数据,如果你使用了 Umi 的 Mock
在 Mock 中我们经常使用 [Mock.js](http://mockjs.com/) 来帮我们方便地生成随机的模拟数据。如果你使用了 Umi 的 Mock
功能,建议你搭配这个库来提升模拟数据的真实性:

```ts
Expand All @@ -156,4 +156,4 @@ export default {

## 其他配置

关于 Mock 功能完整的的其他配置项,请在文档的 [配置](../api/config#mock) 章节中查看。
关于 Mock 功能完整的其他配置项,请在文档的 [配置](../api/config#mock) 章节中查看。
6 changes: 3 additions & 3 deletions docs/docs/docs/guides/mpa.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ MPA 的目录结构是 `src/pages/${dir}/index.tsx` ,每个文件夹 `${dir}`

## 约定的入口文件

默认的入口文件是 `src/pages` 目录下 `*/index.[jt]sx?` 文件。
默认的入口文件是 `src/pages` 目录下的 `*/index.[jt]sx?` 文件。

比如:

Expand Down Expand Up @@ -115,7 +115,7 @@ export const config = {

### 按需启动

支持通过设置 `env.MPA_FILTER` 来指定需要启动的页面,以提高构建速度
支持通过设置 `env.MPA_FILTER` 来指定需要启动的页面,以提高构建速度

```text
# file .env
Expand All @@ -133,7 +133,7 @@ export default function Page() {
}
```

默认启用 React 18,如果需要 React 17 的渲染方式,请在项目中安装 react 17 的依赖,框架会自动适配 react 版本。
默认启用 React 18,如果需要 React 17 的渲染方式,请在项目中安装 React 17 的依赖,框架会自动适配 React 版本。

```bash
$ pnpm i react@17 react-dom@17
Expand Down
24 changes: 12 additions & 12 deletions docs/docs/docs/guides/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ order: 16
toc: content
---
# 开发插件
Umi 的核心就在于它的插件机制。基于 Umi 的插件机制,你可以获得扩展项目的编译时和运行时的能力。你可以利用我们提供的 [插件API](../api/plugin-api) 来自由编写插件,进而实现修改代码打包配置修改启动代码约定目录结构修改 HTML 等丰富的功能。
Umi 的核心就在于它的插件机制。基于 Umi 的插件机制,你可以获得扩展项目的编译时和运行时的能力。你可以利用我们提供的 [插件API](../api/plugin-api) 来自由地编写插件,进而实现修改代码打包配置修改启动代码约定目录结构修改 HTML 等丰富的功能。

## 核心概念
插件的本质就是一个方法,该方法接收了一个参数:api。在插件中,你可以调用 api 提供的方法进行一些 hook 的注册,随后 Umi 会在特定的时机执行这些 hook。
Expand All @@ -28,7 +28,7 @@ export default (api: IApi) => {
});
};
```
这个插件的作用是根据用户配置的 changeFavicon 值来更改配置中的 favicons,(一个很简单且没有实际用途的例子XD)。可以看到插件其实就是一个接收了参数 api 的方法。在这个方法中,我们调用了 `api.modifyConfig` 注册了一个 hook: `(memo)=>{...}`。当你在配置中配置了 `changeFavicon` 之后, Umi 会注册该插件。在 Umi 收集配置的生命周期里,我们在插件里注册的 hook 将被执行,此时配置中的 `favicon` 就会被修改为用户配置中的 `changeFavicon`
这个插件的作用是根据用户配置的 changeFavicon 值来更改配置中的 favicons,(一个很简单且没有实际用途的例子XD)。可以看到插件其实就是一个接收了参数 api 的方法。在这个方法中,我们调用了 `api.modifyConfig` 注册了一个 hook: `(memo)=>{...}`。当你在配置中配置了 `changeFavicon` 之后, Umi 会注册该插件。在 Umi 收集配置的生命周期里,我们在插件里注册的 hook 将被执行,此时配置中的 `favicon` 就会被修改为用户配置中的 `changeFavicon`

### plugin 和 preset
preset 的作用是预设一些插件,它通常用来注册一批 presets 和 plugins。在 preset 中,上述提到的接受 api 的方法可以有返回值,该返回值是一个包含 plugins 和 presets 属性的对象,其作用就是注册相应的插件或者插件集。
Expand All @@ -44,7 +44,7 @@ export default (api: IApi) => {
}
};
```
它们的注册顺序是值得注意的: presets 始终先于 plugins 注册。Umi 维护了两个队列分别用来依次注册 presets 和 plugins,这个例子中的注册的 `preset_foo` 将被置于 presets 队列队首,而 `plugin_foo``plugin_bar` 将被依次置于 plugins 队列队尾。这里把 preset 放在队首的目的在于保证 presets 之间的顺序和关系是可控的。
它们的注册顺序是值得注意的:presets 始终先于 plugins 注册。Umi 维护了两个队列分别用来依次注册 presets 和 plugins,这个例子中的注册的 `preset_foo` 将被置于 presets 队列队首,而 `plugin_foo``plugin_bar` 将被依次置于 plugins 队列队尾。这里把 preset 放在队首的目的在于保证 presets 之间的顺序和关系是可控的。

另外一个值得注意的点是:在 plugin 中,你也可以 return 一些 plugins 或者 presets,但是 Umi 不会对它做任何事情。

Expand Down Expand Up @@ -124,9 +124,9 @@ export default{
### 插件 key 的默认命名规则
如果插件是一个包的话,key 的默认值将是去除前缀的包名。比如 `@umijs/plugin-foo` 的 key 默认为 `foo``@alipay/umi-plugin-bar` 的 key 默认为 `bar`。值得注意的是,该默认规则要求你的包名符合 Umi 插件的命名规范。

如果插件不是一个包的话,key 的默认值将是插件的文件名。比如 `./plugins/foo.js` 的 key 默认为 `foo`
如果插件不是一个包的话,key 的默认值将是插件的文件名。比如 `./plugins/foo.js` 的 key 默认为 `foo`

为了避免不必要的麻烦,我们建议你为自己编写的插件显示地声明其 key。
为了避免不必要的麻烦,我们建议你为自己编写的插件显式地声明其 key。

## Umi 插件的机制及其生命周期

Expand All @@ -140,7 +140,7 @@ export default{
- resolveConfig stage: 该阶段 Umi 将整理各个插件中对于 `config schema` 的定义,然后执行插件的 `modifyConfig``modifyDefaultConfig``modifyPaths` 等 hook,进行配置的收集。
- collectionAppData stage: 该阶段 Umi 执行 `modifyAppData` hook,来维护 App 的元数据。( `AppData``umi@4` 新增的 api )
- onCheck stage: 该阶段 Umi 执行 `onCheck` hook。
- onStart stage: 该阶段 Umi 执行 `onStart` hook
- onStart stage: 该阶段 Umi 执行 `onStart` hook
- runCommand stage: 该阶段 Umi 运行当前 cli 要执行的 command,(例如 `umi dev`, 这里就会执行 dev command)Umi 的各种核心功能都在 command 中实现。包括我们的插件调用 api 注册的绝大多数 hook。

以上就是 Umi 的插件机制的整体流程。
Expand All @@ -149,27 +149,27 @@ export default{

`register()` 接收一个 key 和 一个 hook,它维护了一个 `key-hook[]` 的 map,每当调用 `register()` 的时候,就会为 key 额外注册一个 hook。

`register()` 注册的 hooks 供 applyPlugins 使用。 这些 hook 的执行顺序参照 [tapable](https://github.com/webpack/tapable)
`register()` 注册的 hooks 供 applyPlugins 使用。 这些 hook 的执行顺序参照 [tapable](https://github.com/webpack/tapable)

`registerMethod()` 接收一个 key 和 一个 fn,它会在 api 上注册一个方法。如果你没有向 `registerMethod()` 中传入 fn,那么 `registerMethod()` 会在 api 上注册一个"注册器": 它会将 `register()` 传入 key 并柯里化后的结果作为 fn 注册到 api 上。这样就可以通过调用这个"注册器",快捷地为 key 注册 hook 了。
`registerMethod()` 接收一个 key 和 一个 fn,它会在 api 上注册一个方法。如果你没有向 `registerMethod()` 中传入 fn,那么 `registerMethod()` 会在 api 上注册一个注册器: 它会将 `register()` 传入 key 并柯里化后的结果作为 fn 注册到 api 上。这样就可以通过调用这个注册器,快捷地为 key 注册 hook 了。

关于上述 api 的更具体的使用,请参照[插件 API](../api/plugin-api)
关于上述 api 的更具体的使用,请参照[插件 API](../api/plugin-api)

### PluginAPI 的原理
Umi 会为每个插件赋予一个 PluginAPI 对象,这个对象引用了插件本身和 Umi 的 service。

Umi 为 PluginAPI 对象的 get() 方法进行了 proxy, 具体规则如下:
Umi 为 PluginAPI 对象的 `get()` 方法进行了 proxy,具体规则如下:
- pluginMethod: 如果 prop 是 Umi 所维护的 `pluginMethods[]` ( `通过 registerMethod()` 注册的方法 )中的方法,则返回这个方法。
- service props: 如果 prop 是 serviceProps 数组中的属性(这些属性是 Umi 允许插件直接访问的属性),则返回 service 对应的属性。
- static props: 如果 prop 是参数 staticProps 数组中的属性(这些属性是静态变量,诸如一些类型定义和常量),则将其返回。
- 否则返回 api 的属性
- 否则返回 api 的属性

因此,Umi 提供给插件的 api 绝大多数都是依靠 `registerMethod()` 来实现的,你可以直接使用我们的这些 api 快速地在插件中注册 hook。这也是 Umi 将框架和功能进行解耦的体现: Umi 的 service 只提供插件的管理功能,而 api 都依靠插件来提供。

### preset-umi
`umi-core` 提供了一套插件的注册及管理机制。而 Umi 的核心功能都靠 [preset-umi](https://github.com/umijs/umi/tree/master/packages/preset-umi) 来实现。

`preset-umi` 其实就是内置的一个插件集,它提供的插件分为三大类:
- registerMethods 这类插件注册了一些上述提到的"注册器",以供开发者快速地注册 hook,这类方法也占据了 PluginAPI 中的大多数。
- registerMethods 这类插件注册了一些上述提到的注册器,以供开发者快速地注册 hook,这类方法也占据了 PluginAPI 中的大多数。
- features 这类插件为 Umi 提供了一些特性,例如 appData、lowImport、mock 等。
- commands 这类插件注册了各类 command, 提供了 Umi CLI 的各种功能。Umi 能够在终端中正常运行,依靠的就是 command 提供的功能。
Loading

0 comments on commit 0657e5e

Please sign in to comment.