An Intro to UmiJS
Tags: javascript, webdev
Published: 2022-05-15 02:27:30




## Why Umi?

Frontend development has been distinguished from backend for quite a while now. Many frameworks and plugins have been developed for frontend developemnt. Sometimes it's difficult to initialise a project because there are too many tools to choose from. To achieve this, [_UmiJS_](https://umijs.org/) came to live.

## Before everything else -

In order to use Umi (a frontend framework), you need to have [_NodeJS_](https://nodejs.org/en/) installed.

If you happened to be in China, you can install _cnpm_ or _tyarn_ for faster and safer package management:

```bash
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
# OR
$ npm i yarn tyarn -g
```

Then, you can use `cnpm`/`tyarn` to install your dependencies.

## Umi Initialisation: Global

You can install umi globally:

```bash
$ tyarn global add umi
# OR
$ cnpm install umi -g
```

Then, you can use 'umi generator' to fast start some pages:

- [generator command](https://umijs.org/zh-CN/docs/cli#umi-generate)

  ```bash
  $ umi g page index
  ```

  This will first generate a `pages` folder under current directory inside which a `index.js` file and a `index,css` file will be created automatically. Each `js` file in `pages` directory will be interpreted as a route. Normally, this command is run at the root directory of the project.

- umi dev

  ```bash
  $ umi dev
  ```

  This will start serving the pages on port 8000+.

## Umi Initialisation: Scaffold

You can also initialise umi project with umi scaffold in a project folder

### 1. make a new directory

```bash
$ mkdir antd-testing
$ cd antd-testing
```

### 2. install umi

```bash
$ tyarn create @umijs/umi-app
```

Now the initialisation process has been complete, following up the configuration of the project.

### 3. Install Dependencies & Start

```bash
$ tyarn
```

Then:

```bash
$ tyarn start
```

**PS**: you can use 'Ant Design' default layout by installing [`pro-layout`](https://www.npmjs.com/package/@ant-design/pro-layout) by running:

```bash
$ tyarn add @ant-design/pro-layout
# or
$ cnpm i @ant-design/pro-layout --save
```

Then, edit `.umirc.ts` file:

```ts
import { defineConfig } from 'umi'

export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  layout: {}, // add this line
  routes: [{ path: '/', component: '@/pages/index' }],
})
```

## Run script

Now you can run the following commands to start the server.

```bash
$ umi dev
# OR
$ cnpm run dev
# OR
$ tyarn start
```

## [Routing](https://umijs.org/zh-CN/docs/routing)

### [Conventional Routing (File Routing) - 约定式路由](https://umijs.org/zh-CN/docs/convention-routing)

The folder structure, i.e. files under `src/pages`, represents the default routing.

- [Dynamic Routing](https://umijs.org/zh-CN/docs/convention-routing#%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1): by convention, folder named `[post]` will become a variable in the routes like so `/index/:post`
- [Nested Routing](https://umijs.org/zh-CN/docs/convention-routing#%E5%B5%8C%E5%A5%97%E8%B7%AF%E7%94%B1): by convention, if `_layout.tsx` exists in a sub-folder of `pages` folder, `_layout.tsx` becomes the parent component of all the other components within the same folder
- [Overall layout](https://umijs.org/zh-CN/docs/convention-routing#%E5%85%A8%E5%B1%80-layout): by convention, **_`index.tsx` file in `src/layouts` folder_** is the parent component of all the components in **_`src/pages` folder_**
- [404 Routing](https://umijs.org/zh-CN/docs/convention-routing#404-%E8%B7%AF%E7%94%B1): by convention, `404.tsx` in `pages` folder is the component renders 404 page
- [Extra Routing Attribute](https://umijs.org/zh-CN/docs/convention-routing#%E6%89%A9%E5%B1%95%E8%B7%AF%E7%94%B1%E5%B1%9E%E6%80%A7): before exporting a component, add this line `HomePage.title = 'Home Page'`, now you can access an extra routing attribute `title`

### Configured Routing - 配置式路由

If you are not satisfied with this routing method, configure your `config/config.js`/`.umirc.ts` file to appoint the routes yourself (i.e. _configured routing (配置式路由)_ as opposed to the default _conventional routing (约定式路由)_):

```js
export default {
  routes: [
    {
      exact: true,
      path: '/',
      component: '@pages/FirstPage', // relative path from `src` folder
      routes: [
        { path: '/list', component: 'List' },
        { path: '/listing', redirect: '/list' }, // redirecting to other routes
        { path: '/admin', component: 'Admin' },
      ],
    },
  ],
}
```

**NOTES**: `@` represents `./src` -- referring to the relative path; it is the same as `..` as in `../Firstpage`

### history: to navigate

In Umi, there are two ways to direct user from one page to another: `<Link to="/link_url">Somewhere</Link>` component and `history.push('/link_url')`:

```js
import { history } from 'umi'

// simply redirecting
history.push('/list')

// redirecting with variables
history.push('/list?a=b')
history.push({
  pathname: '/list',
  query: {
    a: 'b',
  },
})

// go back
history.goBack()
```

## Build

```bash
$ cnpm run build
```

Run this code to build the `dist` folder. Do not forget to install `serve` globally.

```bash
$ cnpm install serve -g
```

Then you can serve the dist folder directly on port 5000:

```bash
$ serve ./dist
```

## plugins

To check the list of plugins in an umi project:

```bash
$ umi plugin list

# showing the keys
$ umi plugin list --key
```

Once you know the `key` of a `plugin`, you can config the plugin in your config file:

```js
export default {
  mock: false,
  // OR
  mock: { exclude: ['./foo'] },
}
```

## [Mock data](https://umijs.org/zh-CN/docs/mock)

Mock data lives in `/mock` folder. A tipical mockup `api.ts` file looks like this:

```ts
export default {
  // 支持值为 Object 和 Array
  'GET /api/users': { users: [1, 2] },
  // GET 可忽略
  '/api/users/1': { id: 1 },
  // 支持自定义函数，API 参考 express@4
  'POST /api/users/create': (req, res) => {
    // 添加跨域请求头
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.end('ok')
  },
}
```

Now, if you visit `/api/users`, `{ users: [1, 2] }` will be returned. `GET` key word can be omitted.

### [Mock.js](http://mockjs.com/)

You can use mock.js to auto-generate some mockup data, visit the website for more info.

## [Environment Variables](https://umijs.org/zh-CN/docs/env-variables)

## [DynamicImport](https://umijs.org/zh-CN/docs/load-on-demand)