Enterprise React Development with UmiJS

By Douglas Alves Venancio
    What do you get with a Packt Subscription?

  • Instant access to this title and 7,500+ eBooks & Videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Free Chapter
    Chapter 1: Environment Setup and Introduction to UmiJS
About this book

UmiJS is the Ant Group's underlying frontend development framework, an open source project for developing enterprise-class frontend applications. In this book, you'll get hands-on with single-page application development using UmiJS. By following practical step-by-step examples, you'll develop essential skills to build and publish your apps and create a modern user experience with responsive interfaces.

This book will help you learn the essential features of UmiJS and how to set up and build a project from scratch using React, Less, and TypeScript. You'll study Ant Design, a framework based on solid design concepts that provides a series of React components to accelerate interface development. Along the way, you'll see how to make requests and develop the frontend using simulated data while ensuring that your app has a high level of security and feedback. You'll also discover ways to improve your code quality and readability using formatting tools.

By the end of the book, you'll have learned how to use UmiJS to design user interfaces, as well as compile, test, and package your app locally, and deliver your app by deploying it to online services.

Publication date:
May 2022
Publisher
Packt
Pages
198
ISBN
9781803238968

 

Chapter 1: Environment Setup and Introduction to UmiJS

UmiJS is Ant Financial's underlying frontend framework and an open source project for developing enterprise-class frontend applications. It's a robust framework you can combine with Ant Design to provide everything you need to build a modern user experience.

In this chapter, you will learn how to install and configure a project using UmiJS and Visual Studio Code (VSCode). You'll also understand the folder structure and main files of UmiJS. Then, you'll learn how to set fast navigation between pages using umi history and finally discover Umi UI, a visual option to interact with UmiJS and add components to your project.

We'll cover the following main topics:

  • Setting up our environment and configuring UmiJS
  • Understanding the UmiJS folder structure and its main files
  • Exploring the Umi CLI and adding pages
  • Understanding routing and navigation in UmiJS
  • Using Umi UI

By the end of this chapter, you'll have learned everything you need to get started with developing your project and you will also know about the fundamental behavior of an UmiJS project and its configurations.

 

Technical requirements

To complete this chapter's exercises, you just need a computer with any OS (I recommend Ubuntu 20.04 or higher).

You can find the complete project in the Chapter01 folder in the GitHub repository available at the following link:

https://github.com/PacktPublishing/Enterprise-React-Development-with-UmiJs

 

Setting up our environment and configuring UmiJS

In this section, we'll install and configure VSCode, the EditorConfig extension, and the Prettier extension, and create our first UmiJS project.

Let's begin by installing a source code editor. You can use any editor that supports JavaScript and TypeScript, but I will use VSCode extensively in this book. It's a free editor with an integrated terminal and internal Git control that natively supports JavaScript, TypeScript, Node.js, and many extensions for other languages.

VSCode is available as a Snap package, and you can install it on Ubuntu by running the following command:

$ sudo snap install code –classic

For Mac users, you can install it using Homebrew on macOS by running the following command:

$ brew install --cask visual-studio-code

If you are using Chocolatey on Windows, you can run the following command:

> choco install vscode

Alternatively, you can download the installer available at https://code.visualstudio.com/.

Important Note

You can find instructions on installing Homebrew on macOS at https://brew.sh/ and installing Chocolatey on Windows at https://chocolatey.org/install. If you are a Windows user, you can install Ubuntu in Windows Subsystem for Linux (WSL) and set up your project using common Linux commands. You can read more about WSL at https://docs.microsoft.com/en-us/windows/wsl/install.

Next, we need to install the dependencies required to develop with UmiJS. First, let's install Node.js by typing and running the following commands in the terminal:

$ sudo apt update
$ sudo apt install nodejs -y

The first command updates the mirrors, and the second command installs Node.js with the -y flag, which skips user confirmation to install.

You can install Node.js using Homebrew on macOS by running the following command:

$ brew install node

If you are using Chocolatey on Windows, you can run the following command:

> choco install nodejs

Alternatively, you can download the installer available at https://nodejs.org/en/.

Node.js has a default package manager named npm, but we will extensively use Yarn instead of npm in this book, so I recommend installing it. You can do that by running the following command in the terminal:

$ npm install -g yarn

This command will install Yarn globally in your system.

With that, we are ready to get started with UmiJS. But first, let's understand UmiJS a bit more and what kinds of problems it can solve.

Introduction to UmiJS and creating your first project

UmiJS is a framework for developing enterprise-class frontend applications. This means Umi provides a set of tools for solving everyday problems faced when building large business applications that need to deliver a modern user experience and must be easy to maintain and modify.

With Umi, you can quickly develop an application with internationalization, permissions, and beautiful interfaces taking advantage of Umi's deep integration with Ant Design.

Another significant advantage of Umi is that there are a variety of published plugins you can add to your project as you need. You can also extend it by developing your own plugins to meet specific solutions.

Now that you know more about Umi, let's create your first project by following these steps:

  1. Create a new folder for the project and open it in the terminal:
    $ mkdir umi-app; cd umi-app
  2. Create a new project using the umi-app template:
    $ yarn create @umijs/umi-app
  3. Install the project dependencies by running the following command:
    $ yarn
  4. Start the project by running the following command:
    $ yarn start

We now have a project set up! You can open it by typing http://localhost:8000 in the browser and see the result.

Let's do the final configurations to simplify our work by adding code formatting.

Installing the EditorConfig and Prettier extensions

One of the tools UmiJS provides by default in the umi-app template is EditorConfig, a file format that editors read to define the code style across IDEs and text editors. You'll learn more about code style in Chapter 5, Code Style and Formatting Tools. Some editors and IDEs offer native support to EditorConfig, while in other cases, such as VSCode, you need to install a plugin, so let's install it by following these steps:

  1. Open VSCode and press Ctrl + P. This shortcut will open the following field at the top:
Figure 1.1 – VSCode quick open

Figure 1.1 – VSCode quick open

  1. Type the following command and press Enter to install the official extension for EditorConfig support:
    ext install EditorConfig.EditorConfig 

The umi-app template comes preinstalled with Prettier, which is preconfigured for formatting the code. You can use it by running the yarn prettier command. Still, a better option is to let VSCode format it for you when you save changes or paste code blocks.

For that, we need to install the Prettier extension and configure it as the default code formatter. To install and configure the Prettier extension, follow these steps:

  1. Press Ctrl + P and type the following command, then press Enter to install the official extension for Prettier support:
    ext install esbenp.prettier-vscode
  2. Next, press Ctrl + , to open the VSCode preferences, and in the search field, type formatter and press Enter.
  3. Under Editor: Default Formatter, select Prettier - Code formatter.
  4. Check the Editor: Format On Paste and Editor: Format On Save options, as shown in the following screenshot:
Figure 1.2 – VSCode editor configuration

Figure 1.2 – VSCode editor configuration

In this section, we learned how to configure our environment, learned more about UmiJS, and created our first project. Now, let's take a closer look at the project structure.

 

Understanding the UmiJS folder structure and its main files

In this section, you will understand the UmiJS folder structure, and you will add some essential configurations to files and folders.

The project we create based on the umi-app template generates a set of folders with responsibilities for different parts of the project. Let's see what each one does:

  • mock: In this folder, we store our simulated endpoints definitions to generate a mock API that we can interact with while developing the frontend.
  • src: This is the source folder where all our components are located.
  • src/.umi: This folder is automatically generated by UmiJS every time the project is compiled and contains its internal configurations.
  • src/pages: The React components responsible for rendering the pages in response to configured routes are located in this folder.

These are the folders included with the umi-app template, but there are other essential folders in a UmiJS project, so let's add them.

The first folder we'll add is config.

Adding config and locales folders

In the root folder of our project, we have a file named .umirc.ts. This file contains the configuration for Umi and its plugins. When your project is compact, it's a good choice, but as it grows and becomes complex, the configuration file can become hard to maintain. To avoid that, we can break down our configuration into different parts located in the config folder. Let's do this now by opening your project in VSCode and following these steps:

  1. In the root directory of your project, create a new folder named config.

You can do that by clicking on the icon in the upper-right corner above the folders list.

Figure 1.3 – VSCode new folder icon

Figure 1.3 – VSCode new folder icon

  1. Move the .umirc.ts file to the config folder and rename it config.ts.

You can rename a file by selecting it and pressing F2.

  1. In the config folder, create a new file named routes.ts. In this file, we'll configure the application's routes.

You can do that by clicking on the icon in the top-right corner, above the folders list.

Figure 1.4 – VSCode new file icon

Figure 1.4 – VSCode new file icon

  1. Paste this code into the routes.ts file and save:
    export default [
      {
        path: '/',
        component: '@/pages/index',
      },
    ];

This code defines the root path ('/') to render the component index located in the pages folder.

  1. Now we can import the routes.ts file into config.ts and add this line to the config.ts file:
    import routes from './routes';

We can then rewrite the route section to use it as follows:

import { defineConfig } from 'umi';
import routes from './routes';
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes,
  fastRefresh: {},
});

Umi also supports internationalization (also known as i18n) through the locale plugin. You'll learn more about this and other helpful Umi plugins in later chapters. To enable internationalization, create a folder named locales in the src folder and add the following configuration to the config.ts file under the config folder:

config.ts

import { defineConfig } from 'umi';
import routes from './routes';
export default defineConfig({
  locale: {
    default: 'en-US',
    antd: true,
    baseNavigator: true,
    baseSeparator: '-',
  },
  nodeModulesTransform: {
    type: 'none',
  },
  routes,
  fastRefresh: {},
});

The locale configuration properties are as follows:

  • default: The default application language.
  • antd: Enable Ant Design components internationalization.
  • baseNavigator: Enable browser language detection.
  • baseSeparator: The separator used in multi-language files localized under the src/locales folder.

Now we can support internationalization by adding multi-language files in the locales folder. For example, to support the English language, we need to add a file named en-US.js.

Now, we'll add the app.tsx file to set configurations at runtime.

Runtime configuration

Umi uses a file named app.tsx to expand your application's configurations at runtime. This file is useful to configure the initial state using the initial-state plugin and the layout using the layout plugin. The app.tsx file needs to be located in the src folder.

Add a file named app.tsx to the src folder following the steps demonstrated previously.

At this point, our project structure should look like this:

Figure 1.5 – Project structure after last modifications

Figure 1.5 – Project structure after last modifications

You'll better understand all these features following the exercises in the upcoming chapters.

Now that you understand the Umi project structure and have added the missing folders and files, let's learn about some useful commands in the Umi command-line interface (CLI).

 

Exploring the Umi CLI and adding pages

In this section, we'll explore the Umi CLI for automating tasks and use the generate command to add some pages to your project.

Umi provides a CLI with commands to build, debug, list configurations, and so on. You can use them to automate tasks. Some of these commands are already configured in the umi-app template as scripts in the package.json file: yarn start will execute umi dev, yarn build will execute umi build, and so on.

These are the main commands available:

  • umi dev: Compiles the application and starts a development server for debugging.
  • umi build: Compiles the application bundle in the dist folder.
  • umi webpack: This shows the webpack configuration file generated by Umi.
  • umi plugin list: Lists all Umi plugins in use.
  • umi generate page: Creates a new page template.

    Important Note

    For more commands, refer to the documentation available at https://umijs.org/docs/cli.

Let's add some pages using the generate page Umi CLI command. Follow these steps:

  1. First, delete the files under the src/pages folder, then add two pages by running these commands:
    $ yarn umi g page /Home/index ––typescript ––less
    $ yarn umi g page /Login/index ––typescript ––less

These commands generate two components under the pages folder, Login and Home, with TypeScript and Less support.

  1. To access these pages, we need to define routes, so modify your routes.ts file to define the created components for new routes:

routes.ts

export default [
  {
    path: '/',
    component: '@/pages/Login',
  },
  {
    path: '/home',
    component: '@/pages/Home',
  },
];
  1. To check the result, start the project by running yarn start, then navigate to http://localhost:8000/; you should see the login page.
  2. Navigate to http://localhost:8000/home; you should now see the home page.

Now that we have pages set up, we can learn more about Umi routing and navigation using umi history.

 

Understanding routing and navigation in UmiJS

In this section, you'll understand the Umi routing system and options for configuring routes. You will also learn how to access route parameters and query strings and about navigating between pages.

A Umi project is a single-page application. This means that the entire application remains on the first page served to the browser (index.html), and all other pages we see when accessing different addresses are components rendered on this same page. Umi does the job of parsing the route and rendering the correct component; we just need to define which component to render when the route matches a specific path. As you may have noticed, we already did that. But there are other configuration options. For example, we can set subroutes to define a standard layout for various pages:

routes.ts

export default [
  {
    path: '/',
    component: '@/layouts/Header',
    routes: [
      { path: '/login', component: '@/pages/Login' },
      { path: '/home', component: '@/pages/Home' },
    ],
  },
];

The preceding example defines that all routes under '/' will have a default header, which is a component located in the src/layouts folder.

The header component should look like this:

import React from 'react';
import styles from './index.less';
export default function (props: { children: React.ReactChild }) {
  return (
    <div className={styles.layout}>
      <header className={styles.header}>
        <h1>Umi App</h1>
      </header>
      {props.children}
    </div>
  );
}

props.children will receive the components when you access a defined route.

Another option we have is to redirect routes. Consider the following example:

routes.ts

export default [
  {
    path: '/',
    redirect: '/app/login',
  },
  {
    path: '/app',
    component: '@/layouts/Header',
    routes: [
      { path: '/app/login', component: '@/pages/Login' },
      { path: '/app/home', component: '@/pages/Home' },
    ],
  },
];

With this configuration, when you access http://localhost:8000/, Umi will immediately redirect the page to http://localhost:8000/app/login.

We can also define whether a path should be exact or not:

{
   exact: false,
   path: '/app/login',
   component: '@/pages/Login',
}

This configuration defines that you can access this page in any path under /app/login, such as http://localhost:8000/app/login/user. By default, all paths are exact.

You now understand how the routing system works and the different configuration options we have for routing. Now, you will learn how to access path and query string parameters and about conventional routing and navigating between pages.

Understanding path parameters and query strings

Sometimes we need to identify a resource in the route path. Imagine we have a page in our project that only displays product information. When accessing this page, we need to specify what product to get information from. We can do that by identifying the product ID in the route path:

{
  path: '/product/:id',
  component: '@/pages/Product',
},

If the parameter is not mandatory to access the page, you must add the ? character, like this: /product/:id?.

To access the product ID, we can use the useParams hook provided by Umi:

import { useParams } from 'umi';
export default function Page() {
  const { id } = useParams<{ id: string }>();

You can also receive query string parameters after the route. Query string parameters are key-value pairs in the ? character sequence in a URL, such as this example: /app/home?code=eyJhbGci. Here, code contains the value eyJhbGci.

We don't have a specific hook to access query string parameter values, but we can easily do that using umi history:

import { history } from 'umi';
export default function Page() {
  const { query } = history.location;
  const { code } = query as { code: string };

Now, let's see how you can define parameters when working with conventional routing.

Conventional routing

UmiJS offers an automatic route configuration based on your project structure under the pages folder. UmiJS will rely on that if it can't find route definitions in the config.ts or .umirc.ts files.

If you want to configure a route parameter, you can name the file enclosed in [], like this: [id].tsx. If this parameter is not mandatory to access the page, you must add the $ character, like this: [id$].tsx.

Figure 1.6 – Optional route parameter in conventional routing

Figure 1.6 – Optional route parameter in conventional routing

Next, you will see how to navigate between pages.

Navigating between pages

When we need to set navigation between pages, usually, we use the DOM history object and anchor tag. In UmiJS, we have similar options to navigate: umi history and the Link component.

You can create hyperlinks between pages using the Link component, as in the following example:

import { Link } from 'umi';
export default function Page() {
  return (
    <div>
      <Link to="/app/home">Go Home</Link>
    </div>
  );
}

You can also set navigation between pages using the push() umi history command, as in the following example:

import { history } from 'umi';
export default function Page() {
  const goHome = () => {
    history.push('/app/home');
  };
  return (
    <div>
      <button onClick={goHome}></button>
    </div>
  );
}

In addition to the push() command, umi history has the goBack() command to revert one page in the history stack and goForward() to advance one page.

We have covered all the essential aspects of the Umi routing system, the different options to configure routes, access path and query string parameters, and navigation between pages.

Before finishing this chapter, I will introduce an exciting feature Umi provides if you prefer to interact with the project visually.

 

Using Umi UI

Umi UI is a visual extension of Umi to interact with the project. You can run commands to install dependencies, verify and test code, build the project, and add components through a graphical user interface.

Before using Umi UI, we need to add the @umijs/preset-ui package. You can do that by running the following command:

$ yarn add @umijs/preset-ui -D 

Now, when you start the project, you should see the following console log:

Figure 1.7 – Umi UI starting log

Figure 1.7 – Umi UI starting log

Navigate to http://localhost:8000, and you will notice that the UmiJS logo appears in a bubble in the bottom-right corner. Clicking on this bubble will open Umi UI (you can also access Umi UI at http://localhost:3000).

Figure 1.8 – Umi UI bubble in the bottom-right corner

Figure 1.8 – Umi UI bubble in the bottom-right corner

Let's see what we can do using Umi UI, beginning with tasks:

  • BUILD: This option will create the application bundle in the dist folder. You can also click on ENVS to select compilation options, such as CSS compression.
  • LINT: This option will execute linters in your project. You need to configure the lint script to use this option.
  • TEST: This option will test the project. You need to write tests first.
  • INSTALL: This option will install all project dependencies.

The following screenshot shows the Umi UI Task tab:

Figure 1.9 – Umi UI Task tab

Figure 1.9 – Umi UI Task tab

Next, let's add Ant Design components to our project.

Adding Ant Design components

Ant Design is a design system created by Ant Financial's user experience design team to meet the high demands of enterprise application development and fast changes in these applications. They also created a React UI library of components for building interfaces.

In the Assets tab, we can add Ant Design components to our pages as blocks:

Figure 1.10 – Umi UI Preview Demo button

Figure 1.10 – Umi UI Preview Demo button

Tip

The Umi UI Assets tab is almost entirely in Chinese at the moment. Still, you can always refer to the Ant Design documentation by clicking on Preview Demo and changing the website language to English.

Let's add a login form to experiment with this feature:

  1. Navigate to http://localhost:8000 and open the Umi UI Assets tab.
  2. Click on Add in the form-login box component.
Figure 1.11 – form-login box component Add button

Figure 1.11 – form-login box component Add button

  1. Select the second area by clicking on + Add to here.
Figure 1.12 – Selecting where to add the component

Figure 1.12 – Selecting where to add the component

  1. Now, in the Variable Name field, type LoginForm, make sure the package manager client selected is yarn, and click on OK.
Figure 1.13 – Add Block options

Figure 1.13 – Add Block options

Wait until the block is added and we are done. Umi UI will reload the page, and the component is already there!

If you want, you can add some styles to the login page, as follows:

  1. Add this code to the Login page's index.less file:
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  2. Add the container CSS class to the login component:
    import React from 'react';
    import styles from './index.less';
    import LoginForm from './LoginForm';
    export default function Page() {
      return (
        <div className={styles.container}>
          <h1 className={styles.title}>
            Welcome! Access your account.</h1>
          <LoginForm />
        </div>
      );
    }

The result should look like this:

Figure 1.14 – Login page with login form block

Figure 1.14 – Login page with login form block

And that's it! Now you know how to use Umi UI to interact with your project. If you like this option, I recommend experimenting with it by adding more components and styling them to get you used to it.

 

Summary

In this chapter, you learned how to configure VSCode to work with UmiJS. You learned how to set up a project and organize the UmiJS folder structure. You also learned how to use the Umi CLI to automate tasks and quickly add pages and templates to your project.

You learned that an UmiJS project is a single-page application and about various configurations to define routes in your project. You learned how to access path parameters and query string parameters. You also learned how UmiJS could automatically configure routes based on the folder convention. You learned about navigation using umi history and the link component.

Finally, you learned how to install and use Umi UI to interact with your project. You then learned how to execute tasks using Umi UI and add Ant Design components as blocks in your project.

In the next chapter, you will learn more about Ant Design in a Umi project and how to use it to develop interfaces.

About the Author
  • Douglas Alves Venancio

    Douglas has a background in systems analysis and development, his passion is to help customers and the community solve problems. Over the past few years, he has mainly worked with digital products and innovation, delivering the best user experience with modern web applications.

    Browse publications by this author
Enterprise React Development with UmiJS
Unlock this book and the full library FREE for 7 days
Start now