一,环境准备

  • node -v 大于10.3及以上
  • yarn 1.22.15

二,项目安装

  1. 新建文件夹,在该文件夹下打开终端,或者使用vscode在文件夹下打开终端
  2. 执行 yarn create @umijs/umi-app 创建项目
  3. 安装依赖 yran
  4. 启动项目 yarn start

三,如何使用

  1. 配置项目eslint

umi 维护了一个 prettier,eslint,stylelint 的配置文件合集 umi-fabric

我们使用该配置 安装umi-fabric yarn add @umijs/fabric -D

在项目根目录新建.eslintrc.js .stylelintrc.js .prettierrc.js 分别对应加上代码

//.eslintrc.js 配置
module.exports = {
  extends: [require.resolve('@umijs/fabric/dist/eslint')],
  // in antd-design-pro
  globals: {
    ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
    page: true,
  },
  rules: {
    // your rules
    'prefer-const': 0,
  },
};
//.prettierrc.js
const fabric = require('@umijs/fabric')
module.exports = {
  ...fabric.prettier,
  semi: false,
}
//.stylelintrc.js
const fabric = require('@umijs/fabric')
module.exports = {
  ...fabric.stylelint,
}

根目录新建eslint忽略文件 .eslintignore

.eslintrc.js
node_modules

在package.json 里面的lint-staged 新增 "eslint --fix"

  "lint-staged": {
    "*.{js,jsx,less,md,json}": [
      "prettier --write"
    ],
    "*.ts?(x)": [
      "prettier --parser=typescript --write",
      "eslint --fix"
    ]
  },

最后要在vscode中安装插件eslint,prettier,stylelint , 尝试在任意tsx文件下修改

会提示 变量a 定义未使用

  1. 配置项目全局css

在项目src下新建 global.css文件

umi 中约定 src/global.css **为全局样式,如果存在此文件,会被自动引入到入口文件最前面。

在该文件下配置网站常用到的css或者reset css属性

  1. 配置文件

umi 在 .umirc.ts 或 config/config.ts 中配置项目和插件

使用config配置项的话必须删除项目根目录下的.umirc.ts, 不然以.umirc.ts中的配置项为最优配置(也就表示则 config下的任何配置都会无效)

后面部分我们会按照config的配置方式进行,所以删掉.umirc.ts文件

项目根目录新建config文件夹,目录中新建config.ts文件

把删掉的.umirc.ts文件的内容复制到config.ts中

import { defineConfig } from 'umi'
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  mfsu: {}, //热启动提升
  //路由
  routes: [{page:'/',component: '@/pages/index'}],
  fastRefresh: {},
  hash: true,//文件名哈希值 避免浏览器缓存
})
  1. 运行环境配置

可以通过环境变量 UMI_ENV 区分不同环境来指定配置。

这里我们使用第三方工具 cross-env来配置环境变量

安装 yarn add cross-env --dev

在package.json中修改script各个运行环境的配置

"start": "cross-env UMI_ENV=dev umi dev",
"build": "cross-env UMI_ENV=dev umi build",
"build:prod": "cross-env UMI_ENV=prod umi build",

在config中加入相对应环境的文件

config.dev.ts, config.prod.ts

//开发环境配置 config.dev.ts
import { defineConfig } from 'umi'
export default defineConfig({
  // CurrentEnvironment 变量代表当前的环境,后面根据不同的环境配置不同的请求地址会用到
  define: {
    CurrentEnvironment: 'dev',
  },
})

//生产环境配置 config.prod.ts
import { defineConfig } from 'umi'
export default defineConfig({
  define: {
    CurrentEnvironment: 'prod',
  },
})

然后我们需要在根目录中的typings.d.ts 添加

declare const CurrentEnvironment: 'dev' | 'prod';

分别表示 当执行 yarn start 时 使用的是 config.dev.ts 配置文件中的配置项

当执行 yarn build:prod 时 使用的是 config.prod.ts 配置文件中的配置项

如果我们不想麻烦,可以直接删掉UMI_ENV=xxx 代码, 默认使用config.ts中的配置

  1. 自定义环境变量配置

有时候开发中,我们需要通过自定义的变量,去控制 在开发时和发布生产时的接口地址切换,或者版本控制等,

可以通过自定义环境变量方式 去控制

其实他跟上面的环境配置差不多,需要我们在package.json中script加入我们定义的变量

如: REACT_APP_ENV

"scripts": {
    "start": "cross-env REACT_APP_ENV=reactDev umi dev",
    "build": "cross-env REACT_APP_ENV=reactProd umi build",
    "build:prod": "cross-env UMI_ENV=prod umi build",
    "postinstall": "umi generate tmp",
    "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'"
  },

在config.ts中添加defind配置

define: {
  //定义全局值 需要在package.json中script配置 REACT_APP_ENV 如
  //"start": "cross-env REACT_APP_ENV=reactDev UMI_ENV=dev umi dev",
  //还需要在typings.d.ts 中添加 declare const REACT_APP_ENV: string
  REACT_APP_ENV: process.env.REACT_APP_ENV,
},

还需要在typings.d.ts 中添加 declare const REACT_APP_ENV: string

在需要使用到的地方 可以直接通过REACT_APP_ENV 方式获取

四,Umi中的路由使用

根据Umi文档介绍,umi的路由生成方式有两种,分别是'配置路由'和'约定式路由',用过vue的都知道,vue很多基本都是使用配置路由(除使用nuxt外)

4.1 约定式路由

  1. 基础配置

约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。

白话的意思就是,你要根据umi事先约定好的约束去生成文件, umi就会为你自动生成路由

如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages 目录拿到路由配置。

生成路由中文档提及需要注意的地方及规则:

  • 以 . 或 _ 开头的文件或目录
  • 以 d.ts 结尾的类型定义文件
  • 以 test.ts、spec.ts、e2e.ts 结尾的测试文件(适用于 .js、.jsx 和 .tsx 文件)
  • components 和 component 目录
  • utils 和 util 目录
  • 不是 .js、.jsx、.ts 或 .tsx 文件
  • 文件内容不包含 JSX 元素
  1. 动态路由

约定 [] (中括号)包裹的文件或文件夹为动态路由。

src/pages/users/[id].tsx 会成为 /users/:id

src/pages/users/[id]/settings.tsx 会成为 /users/:id/settings

//比如一下文件结构
└── pages
  └── [post]
    ├── index.tsx
    └── comments.tsx
  └── users
    └── [id].tsx
  └── index.tsx
//会生成对应配置路由
[
  { exact: true, path: '/', component: '@/pages/index' },
  { exact: true, path: '/users/:id', component: '@/pages/users/[id]' },
  { exact: true, path: '/:post/', component: '@/pages/[post]/index' },
  {
    exact: true,
    path: '/:post/comments',
    component: '@/pages/[post]/comments',
  },
];
  1. 动态可选路由

约定 [ $] 包裹的文件或文件夹为动态可选路由。

比如:

src/pages/users/[id$].tsx 会成为 /users/:id?

src/pages/users/[id$]/settings.tsx 会成为 /users/:id?/settings

  1. 嵌套路由

Umi 里约定目录下有 _layout.tsx 时会生成嵌套路由,以 _layout.tsx 为该目录的 layout。layout 文件需要返回一个 React 组件,并通过 props.children 渲染子组件。

比如以下目录结构,

└── pages
  └── users
      ├── _layout.tsx
      ├── index.tsx
      └── list.tsx
//会生成对应嵌套路由
[
  { exact: false, path: '/users', component: '@/pages/users/_layout',
    routes: [
      { exact: true, path: '/users', component: '@/pages/users/index' },
      { exact: true, path: '/users/list', component: '@/pages/users/list' },
    ]
  }
]
  1. 全局Layout

umi约定src/layouts/index.tsx 为全局路由. 返回一个React组件 并通过 props.children渲染子组件

//如当前文件目录结构
└── src
  ├── layouts
  │   └── index.tsx
  └── pages
      ├── index.tsx
      └── users.tsx
//会生成对应路由
[
  { exact: false, path: '/', component: '@/layouts/index',
    routes: [
      { exact: true, path: '/', component: '@/pages/index' },
      { exact: true, path: '/users', component: '@/pages/users' },
    ],
  },
]

这个时候我们可以修改layouts中的index.tsx文件

import { NavLink } from 'umi'
export default (props) => {
  return (
    <div style={{ padding: 20 }}>
      <h2>秀儿网</h2>
      <ul>
        <li>
          <NavLink to="/">首页</NavLink>
        </li>
        <li>
          <NavLink to="/users">用户中心</NavLink>
        </li>
      </ul>
      {props.children}
    </div>
  )
}

更多可以查看umijs文档 约定式路由

4.2 配置路由

配置路由可以按照自己的风格,去定义自己的路由方式

回到config.ts配置文件,这个时候我们新起一个routes.ts文件 来单独处理我们的路由配置

export default [
  { exact: true, path: '/', component: '@/pages/index' },
  { exact: true, path: '/my', component: '@/pages/my' },
  {
    component: '@/pages/video',
    path: '/video',
    routes: [
      {
        path: '/video',
        title: '视频教程',
        routes: [
           { path: '/video', component: '@/pages/video/vue', title: 'vue视频' },
          { path: '/video/react', component: '@/pages/video/react', title: 'react视频' },
          { path: '/video/jq', component: '@/pages/video/jq', title: 'jq视频' },
        ],
      },
    ],
  },
]

在config.ts中引入

import { defineConfig } from 'umi'
import routes from './routes'
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  mfsu: {}, //热启动提升
  define: {
    REACT_APP_ENV: process.env.REACT_APP_ENV,
  },
  //路由
  routes: routes,
  fastRefresh: {},
  hash: true,//文件名哈希值 避免浏览器缓存
})

生成对应文件

在pages/video/index.tsx中配置嵌套路由出口

import { NavLink } from 'umi'
export default (props: any  ) => {
  return (
    <div style={{ padding: 20 }}>
      <h2>视频教程</h2>
      <ul>
        <li>
          <NavLink to="/video">vue视频</NavLink>
        </li>
        <li>
          <NavLink to="/video/react">react视频</NavLink>
        </li>
        <li>
          <NavLink to="/video/jq">jq视频</NavLink>
        </li>
      </ul>
      {props.children}
    </div>
  )
}

效果


yuobey
1 声望0 粉丝