{T}

微生成器与编码规范

微生成器

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

下面的命令会列出目前所有可用的生成器,可以通过交互式方式来选择你使用的功能,都有详细的提示。

bash
$ umi generate

# 或者
$ umi g

你也可以通过 umi g <generatorName> 的形式来使用对应的生成器

页面生成器

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

基本使用

交互式输入页面名称和文件生成方式:

bash
$umi g page

? What is the name of page? › mypage
? How dou you want page files to be created? › - Use arrow-keys. Return to submit.
❯   mypage/index.{tsx,less}
    mypage.{tsx,less}

直接生成:

bash
$umi g page foo
Write: src/pages/foo.tsx
Write: src/pages/foo.less

以目录方式生成页面,目录下为页面的组件和样式文件:

bash
$umi g page bar --dir
Write: src/pages/bar/index.less
Write: src/pages/bar/index.tsx

嵌套生成页面:

bash
$umi g page far/far/away/kingdom
Write: src/pages/far/far/away/kingdom.tsx
Write: src/pages/far/far/away/kingdom.less

批量生成多个页面:

bash
$umi g page  page1  page2   a/nested/page3

Write: src/pages/page1.tsx
Write: src/pages/page1.less

Write: src/pages/page2.tsx
Write: src/pages/page2.less

Write: src/pages/a/nested/page3.tsx
Write: src/pages/a/nested/page3.less

对页面模板内容进行自定义

如果页面生成器使用的默认模板不符合你的需求,你可以对模板内容进行自定义设置。执行 --eject 命令:

bash
$umi g page --eject

执行命令后,页面生成器会把它的原始模板写入到项目的 /templates/page 目录:

undefined
.
├── package.json
└── templates
    └── page
        ├── index.less.tpl
        └── index.tsx.tpl
使用模板变量

两个模板文件都支持模板语法,你可以像下面这样插入变量:

tsx
import React from 'react';
import './{{{name}}}.less'

const message = '{{{msg}}}'
const count = {{{count}}}

可以自定义参数值:

bash
$umi g page foo --msg "Hello World" --count 10

运行命令后,生成的页面内容如下:

tsx
import React from 'react';
import './foo.less'

const message = 'Hello World'
const count = 10

如果你不需要使用模板变量,可以省略 .tpl 后缀名,将 index.tsx.tpl 简写为 index.tsxindex.less.tpl 简写为 index.less

预设变量

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

参数默认值说明
name-当前文件的名称。如果执行 pnpm umi g page foo,会生成 pages/foo.tsxpages/foo.less 两个文件,其中 name 的值为 "foo"
color-随机生成一个 RGB 颜色
cssExtless样式文件的后缀名

如果想了解更多模板语法的内容,请查看 mustache

dir 模式

在不使用 dir 模式的情况下,如果你的页面模板文件夹只自定义了一个模板文件,缺失的文件会自动选取默认的模板文件。

如果使用 dir 模式,它的生成内容会和你的页面自定义模板文件夹保持一致,只有在页面自定义模板文件夹为空时才使用默认模板。如果你的页面自定义模板文件夹内容如下:

bash
.
├── a.tsx
└── index.tsx.tpl

生成的目录将是:

undefined
.
├── a.tsx
└── index.tsx
回退

如果还想继续使用默认的模板,可以指定 --fallback,此时不再使用用户自定义的模板:

bash
$umi g page foo --fallback

组件生成器

src/components/ 目录下生成项目需要的组件。和页面生成器一样,组件生成器也有多种生成方式

基本使用

交互式生成:

bash
$umi g component

✔ Please input you component Name … foo
Write: src/components/Foo/index.ts
Write: src/components/Foo/component.tsx

直接生成:

bash
$umi g component bar

Write: src/components/Bar/index.ts
Write: src/components/Bar/component.tsx

嵌套生成:

bash
$umi g component group/subgroup/baz

Write: src/components/group/subgroup/Baz/index.ts
Write: src/components/group/subgroup/Baz/component.tsx

批量生成:

bash
$umi g component apple banana orange

Write: src/components/Apple/index.ts
Write: src/components/Apple/component.tsx

Write: src/components/Banana/index.ts
Write: src/components/Banana/component.tsx

Write: src/components/Orange/index.ts
Write: src/components/Orange/component.tsx

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

组件生成器也支持对模板内容自定义。首先,先将原始模板写入到项目的 /templates/component 目录:

bash
$umi g component --eject
使用模板变量
bash
$umi g component foo --msg "Hello World"

自定义组件模板可以省略 .tpl 后缀名。你可以将 index.ts.tpl 简写为 index.tscomponent.tsx.tpl 简写为 component.tsx

组件生成器将生成与你的自定义模板文件夹相一致的内容,你可以根据需要添加更多的自定义模板文件。

预设变量
参数默认值说明
compName-当前组件的名称。如果执行 pnpm umi g component foocompName 的值为 Foo
回退
bash
$umi g component foo --fallback

RouteAPI 生成器

生成 routeAPI 功能的模板文件。

交互式生成:

bash
$umi g api

✔ please input your api name: … starwar/people
Write: api/starwar/people.ts

直接生成:

bash
$umi g api films

Write: api/films.ts

嵌套生成器:

bash
$umi g api planets/[id]

Write: api/planets/[id].ts

批量生成:

bash
$umi g api spaceships vehicles species

Write: api/spaceships.ts
Write: api/vehicles.ts
Write: api/species.ts

Mock 生成器

生成 Mock 功能的模板文件

交互式生成:

bash
$umi g mock

✔ please input your mock file name … auth
Write: mock/auth.ts

直接生成:

bash
$umi g mock acl

Write: mock/acl.ts

嵌套生成:

bash
$umi g mock users/profile

Write: mock/users/profile.ts

Prettier 配置生成器

为项目生成 prettier 配置,命令执行后,umi 会生成推荐的 prettier 配置和安装相应的依赖

bash
$umi g prettier

info  - Write package.json
info  - Write .prettierrc
info  - Write .prettierignore

Jest 配置生成器

为项目生成 jest 配置,命令执行后,umi 会生成 Jest 配置和安装相应的依赖。根据需要选择是否要使用 @testing-library/react 做 UI 测试

bash
$umi g jest

✔ Will you use @testing-library/react for UI testing?! … yes
info  - Write package.json
info  - Write jest.config.ts

Tailwind CSS 配置生成器

为项目开启 Tailwind CSS 配置,命令执行后,umi 会生成 Tailwind CSS 和安装相应的的依赖

bash
$umi g tailwindcss

info  - Write package.json
set config:tailwindcss on /Users/umi/playground/.umirc.ts
set config:plugins on /Users/umi/playground/.umirc.ts

info  - Update .umirc.ts
info  - Write tailwind.config.js
info  - Write tailwind.css

DvaJS 配置生成器

为项目开启 Dva 配置,命令执行后,umi 会生成 Dva

bash
$umi g dva

set config:dva on /Users/umi/umi-playground/.umirc.ts
set config:plugins on /Users/umi/umi-playground/.umirc.ts

info  - Update config file
info  - Write example model

Precommit 配置生成器

为项目生成 precommit 配置,命令执行后,umi 会为我们添加 husky 和 Git commit message 格式校验行为,在每次 Git commit 前会将 Git 暂存区的代码默认格式化

注意:如果是初始化出来的 @umijs/max 项目,通常不需要该生成器,因为已经配置好 husky 了

bash
$umi g precommit

info  - Update package.json for devDependencies
info  - Update package.json for scripts
info  - Write .lintstagedrc
info  - Create .husky
info  - Write commit-msg
info  - Write pre-commit

编码规范

通常会在项目中使用 ESLint、Stylelint 来协助我们把控编码质量,为了实现低成本、高性能、更稳定地接入上述工具,Umi 提供了开箱即用的 Lint 能力,包含以下特性:

  1. 推荐配置:提供 ESLint 及 Stylelint 推荐配置,可以直接继承使用
  2. 统一的 CLI:提供 umi lint CLI,集成式调用 ESLint 和 Stylelint
  3. 规则稳定:始终确保规则的稳定性,不会出现上游配置更新导致存量项目 lint 失败的情况

其中,ESLint 配置具备如下特点:

  1. 仅质量相关:我们从数百条规则中筛选出数十条与编码质量相关的规则进行白名单开启,回归 Lint 本质,且不会与 Prettier 的规则冲突
  2. 性能优先:部分 TypeScript 的规则实用性低但项目全量编译的成本却很高,我们对这些规则进行禁用以提升性能
  3. 内置常用插件:包含 react、react-hooks、@typescript/eslint、jest,满足日常所需

另外,Stylelint 配置还内置 CSS-in-JS 支持,可以检测出 JS 文件中的样式表语法错误。

使用方式

安装

为了节省安装体积,目前仅在 Umi Max 中内置了 Lint 模块,使用 max lint 来执行 lint 过程。如果你使用的是 Umi,需要先安装 @umijs/lint

bash
$ npm i @umijs/lint -D

# or
$ pnpm add @umijs/lint -D

然后安装 ESLint 及 Stylelint:

bash
$ npm i eslint stylelint -D

# or
$ pnpm add eslint stylelint -D

启用配置

.eslintrc.js.stylelintrc.js 里继承 Umi 提供的配置:

js
// .eslintrc.js
module.exports = {

  // Umi 项目
  extends: require.resolve('umi/eslint'),

  // Umi Max 项目
  extends: require.resolve('@umijs/max/eslint'),
}

// .stylelintrc.js
module.exports = {

  // Umi 项目
  extends: require.resolve('umi/stylelint'),

  // Umi Max 项目
  extends: require.resolve('@umijs/max/stylelint'),
}

在配置文件创建完毕后,我们其实已经可以通过 eslintstylelint 命令来执行 lint 了,但我们仍然推荐使用 umi lint 命令,以获得更便捷的体验

CLI

umi lint 命令的用法如下:

bash
$ umi lint [glob] [--fix] [--eslint-only] [--stylelint-only] [--cssinjs]

参数说明:

bash
[glob]: 可选,指定要 lint 的文件,默认为 `{src,test}/**/*.{js,jsx,ts,tsx,css,less}`
  --quiet: 可选,禁用 `warn` 规则的报告,仅输出 `error`
  --fix: 可选,自动修复 lint 错误
  --eslint-only: 可选,仅执行 ESLint
  --stylelint-only: 可选,仅执行 Stylelint
  --cssinjs: 可选,为 Stylelint 启用 CSS-in-JS 支持

通常来说,直接执行 umi lint 应该就能满足大部分情况

与 Git 工作流结合

我们也推荐使用 lint-stagedHusky,将 umi lint 与 Git 工作流结合使用,以便在提交代码时自动 lint 本次变更的代码。

lint-staged

lint-staged 用来驱动 umi lint 命令,每次仅将变更的内容交给 umi lint 进行检查

bash
$ npm i lint-staged -D

# or
$ pnpm add lint-staged -D

package.json 中配置 lint-staged:

diff
{
+   "lint-staged": {
+     "*.{js,jsx,ts,tsx,css,less}": [
+       "umi lint"
+     ]
+   }
}

此时如果执行 git add sample.js 后,再执行 npx lint-staged,就能实现仅检查 sample.js 本次的变更了

Husky

Husky 用来绑定 Git Hooks、在指定时机(例如 pre-commit)执行我们想要的命令,安装方式请参考 Husky 文档:https://typicode.github.io/husky/#/?id=automatic-recommended

初始化完成后,需要手动修改 .husky/pre-commit 文件的内容:

diff
#!/bin/sh

. "$(dirname "$0")/_/husky.sh"

- npm test
+ npx lint-staged

至此大功告成,每次执行 git commit 命令的时候,umi lint 就能自动对本次变更的代码进行检查,在确保编码质量的同时也能确保执行效率

Prettier

在启用 umi lint 的基础上,我们也建议与 Prettier 一同使用,以确保团队的代码风格是基本一致的

可参考 Prettier 文档将其配置到 lint-staged 中:https://prettier.io/docs/en/install.html#git-hooks

附录

  1. Umi 内置的 ESLint 规则列表:https://github.com/umijs/umi/blob/master/packages/lint/src/config/eslint/rules/recommended.ts
  2. Umi 内置的 Stylelint 配置:https://github.com/umijs/umi/blob/master/packages/lint/src/config/stylelint/index.ts