返回

Umi3 教程:搭建和最佳实践指南

前端

Umi3 简介

Umi3 是一个用于构建复杂的前端应用程序的React框架,它集成了路由、状态管理、国际化、测试和部署等开箱即用的功能,使开发人员能够专注于构建应用程序本身的业务逻辑。Umi3具有以下特点:

  • 开箱即用: Umi3 提供了开箱即用的项目模板和配置,无需繁琐的配置,便可快速搭建出一个完整的React项目。
  • 高性能: Umi3 采用 code splitting 和按需加载等技术,可以提高应用程序的性能,并支持服务器端渲染(SSR)和静态站点生成(SSG),以实现更好的用户体验。
  • 灵活性: Umi3 提供了丰富的插件生态,使开发人员能够轻松地集成其他工具和库,以满足不同的项目需求。
  • 社区支持: Umi3 拥有活跃的社区,提供丰富的文档和技术支持,使开发人员能够快速入门并解决开发过程中遇到的问题。

Umi3 搭建

1. 安装 Umi3

npm install umi -g

2. 创建项目

umi new <project-name>

3. 运行项目

cd <project-name>
umi start

Umi3 项目结构

Umi3 采用了模块化的项目结构,使代码更加易于管理和维护。项目结构如下:

|- node_modules/  # 包依赖
|- package.json   # 包管理文件
|- src/  # 源代码
|   |- index.js  # 项目入口
|   |- app.js  # 应用根组件
|   |- components/  # 组件文件夹
|   |- pages/  # 路由文件夹
|   |- models/  # 模型文件夹
|   |- services/  # 服务文件夹
|   |- utils/  # 工具文件夹
|   |- config/  # 配置文件
|- .gitignore  # Git 忽略文件
|- .eslintrc.js  # ESLint 配置文件
|- package-lock.json  # 包锁定文件

Umi3 路由

Umi3 采用基于约定式路由的模式,使路由配置更加简单和易读。您可以在 src/pages 文件夹下创建路由文件,并导出路由组件。路由文件以 .jsx.tsx 结尾,并与组件名保持一致。

// src/pages/index.jsx
import { Button } from 'antd';

const IndexPage = () => {
  return (
    <div>
      <Button type="primary">Hello Umi3!</Button>
    </div>
  );
};

export default IndexPage;

Umi3 样式

Umi3 提供了开箱即用的 CSS 预处理器支持,您可以选择使用 Less、Sass 或 Stylus 等预处理器来编写样式代码。在 src/styles 文件夹下创建样式文件,并导入到组件中。

// src/styles/index.less
.button-primary {
  color: #fff;
  background-color: #1890ff;
  border-color: #1890ff;
}

// src/pages/index.jsx
import './index.less';

const IndexPage = () => {
  return (
    <div>
      <Button type="primary" className="button-primary">Hello Umi3!</Button>
    </div>
  );
};

export default IndexPage;

Umi3 状态管理

Umi3 集成了 Redux、MobX 等多种状态管理库,使您可以轻松地管理应用程序状态。在 src/models 文件夹下创建模型文件,并导出模型对象。模型对象包含状态、reducer 和 effects。

// src/models/counter.js
import { defineModel } from 'dva';

const CounterModel = defineModel({
  namespace: 'counter',
  state: {
    count: 0,
  },
  reducers: {
    increment(state) {
      return {
        ...state,
        count: state.count + 1,
      };
    },
    decrement(state) {
      return {
        ...state,
        count: state.count - 1,
      };
    },
  },
  effects: {
    async incrementAsync(action, { call, put }) {
      await new Promise((resolve) => {
        setTimeout(() => {
          resolve();
        }, 1000);
      });
      put({
        type: 'increment',
      });
    },
  },
});

export default CounterModel;

在组件中,可以使用 useModel 钩子来访问和修改模型状态。

// src/pages/index.jsx
import { useModel } from 'dva';

const IndexPage = () => {
  const counterModel = useModel('counter');

  return (
    <div>
      <h1>Count: {counterModel.state.count}</h1>
      <Button type="primary" onClick={() => counterModel.increment()}>+</Button>
      <Button type="primary" onClick={() => counterModel.decrement()}>-</Button>
      <Button type="primary" onClick={() => counterModel.incrementAsync()}>Increment Async</Button>
    </div>
  );
};

export default IndexPage;

Umi3 国际化

Umi3 提供了国际化支持,使您可以轻松地将应用程序翻译成多种语言。在 src/locales 文件夹下创建语言文件,并导出语言对象。语言对象包含语言代码和翻译文本。

// src/locales/en-US.js
export default {
  'counter.count': 'Count',
  'counter.increment': 'Increment',
  'counter.decrement': 'Decrement',
  'counter.incrementAsync': 'Increment Async',
};

在组件中,可以使用 useIntl 钩子来访问翻译文本。

// src/pages/index.jsx
import { useIntl } from 'react-intl';

const IndexPage = () => {
  const intl = useIntl();

  return (
    <div>
      <h1>{intl.formatMessage({ id: 'counter.count' })}</h1>
      <Button type="primary" onClick={() => intl.formatMessage({ id: 'counter.increment' })}>+</Button>
      <Button type="primary" onClick={() => intl.formatMessage({ id: 'counter.decrement' })}>-</Button>
      <Button type="primary" onClick={() => intl.formatMessage({ id: 'counter.incrementAsync' })}>Increment Async</Button>
    </div>
  );
};

export default IndexPage;

Umi3 测试

Umi3 提供了开箱即用的测试支持,您可以使用 Jest 和 Enzyme 等工具来编写测试代码。在 src/tests 文件夹下创建测试文件,并导出测试组件。测试组件以 .test.jsx.test.tsx 结尾,并与组件名保持一致。

// src/tests/index.test.jsx
import { render, fireEvent } from '@testing-library/react';
import IndexPage from '../pages/index';

describe('IndexPage', () => {
  it('should render correctly', () => {
    const { container } = render(<IndexPage />);
    expect(container).toMatchSnapshot();
  });

  it('should increment the count when the increment button is clicked', () => {
    const { getByText } = render(<IndexPage />);
    const incrementButton = getByText('Increment');
    fireEvent.click(incrementButton);
    expect(getByText('Count: 1')).toBeInTheDocument();
  });
});

Umi3 部署

Umi3 提供了多种部署选项,您可以选择使用 GitHub Pages、Netlify 或 Vercel 等平台来部署您的应用程序。

1. GitHub Pages

umi build
cd build
git init
git add .