Umi 中提供了大量的 默认环境变量,这些变量可以帮助我们管理一些脚手架功能。
在package.json
内修改启动命令,以添加对应环境变量。
示例代码如下:
{/** 省略配置项 */"scripts": {/** 省略配置项 */// 在start命令内添加UMI_ENV环境变量"start": "cross-env REACT_APP_ENV=dev UMI_ENV=dev umi dev","start:dev": "cross-env REACT_APP_ENV=dev UMI_ENV=dev MOCK=none umi dev"/** 省略配置项 */}/** 省略配置项 */}
在开发中经常会有一些需求,根据应用运行的不同环境进行不同的逻辑处理。
比如,dev
环境使用 dev
的对应的 Url,而线上则使用 prod
对应的 Url。 或者,在某些特定的环境需要打开只有在该环境下才会生效的功能。
在 Pro 的脚手架中有这样的一个环境变量 REACT_APP_ENV
,该变量代表当前应用所处环境的具体名称。如 dev、test、pre、prod 等。
如若需要在 config
外的非 node 环境文件中使用该环境变量,则需要在 config
导出默认 defineConfig()
时配置 define{}
。
示例代码如下:
// config/config.tsconst { REACT_APP_ENV } = process.env;export default defineConfig({{/** 省略其他配置 */}define: {REACT_APP_ENV: REACT_APP_ENV || false,}{/** 省略其他配置 */}});
使用该变量示例代码如下:
// src/components/RightContent/index.tsx/** 省略其他代码 */const GlobalHeaderRight: React.FC<{}> = () => {/** 省略其他代码 */return (<Space className={className}><!-- 省略其他代码 --><!-- 在顶部右侧显示对应环境名称 -->{REACT_APP_ENV && (<span><Tag color={ENVTagColor[REACT_APP_ENV]}>{REACT_APP_ENV}</Tag></span>)}</Space>);};
Pro 脚手架默认使用 Umi 作为底层框架,在 Umi 内可通过指定 UMI_ENV
环境变量来区分不同环境的配置文件,UMI_ENV
需要在 package.json
内配置。
示例配置如下:
{{/** 省略... */}"scripts": {"analyze": "cross-env ANALYZE=1 umi build","build": "umi build","build:dev": "cross-env REACT_APP_ENV=dev UMI_ENV=dev umi build","build:test": "cross-env REACT_APP_ENV=test UMI_ENV=test umi build","build:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=pre umi build","build:prod": "cross-env REACT_APP_ENV=prod UMI_ENV=prod umi build","deploy": "npm run site && npm run gh-pages","dev": "npm run start:dev",{/** 省略... */}"start": "cross-env REACT_APP_ENV=dev UMI_ENV=dev umi dev","start:dev": "cross-env REACT_APP_ENV=dev UMI_ENV=dev MOCK=none umi dev","start:no-mock": "cross-env REACT_APP_ENV=dev UMI_ENV=dev MOCK=none umi dev","start:no-ui": "cross-env REACT_APP_ENV=dev UMI_ENV=dev UMI_UI=none umi dev","start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=pre MOCK=none umi dev","start:test": "cross-env REACT_APP_ENV=test UMI_ENV=test MOCK=none umi dev",{/** 省略... */}},{/** 省略... */}}
当 UMI_ENV
为 test
时,则必须在 config 目录下配置 config.test.ts
文件来管理 test
环境下的不同变量,Umi 框架会在 deep merge 后形成最终配置。
示例代码如下:
// config/config.test.ts test环境对应的配置文件import { defineConfig } from 'umi';/*** 导出的多环境变量命名约定:一律大写且采用下划线分割单词* 注意:在添加变量后,需要在src/typing.d.ts内添加该变量的声明,否则在使用变量时IDE会报错。*/export default defineConfig({define: {API_URL: 'https://api-test.xxx.com', // API地址API_SECRET_KEY: 'XXXXXXXXXXXXXXXX', // API调用密钥},});
变量使用示例:
// src/services/user.tsimport { request } from 'umi';export async function query() {// 使用API密钥调用用户接口return request<API.CurrentUser[]>('${API_URL}/api/users', {API_SECRET_KEY,});}
配置文件夹 config 下的结构:
ant-design-pro├── config│ ├── config.dev.ts│ ├── config.test.ts│ ├── config.pre.ts│ ├── config.prod.ts│ ├── config.ts│ ├── proxy.ts│ ├── routes.ts│ ├── defaultSettings.ts...
由于环境变量是直接使用,不会通过 window 对象的方式来使用,在 eslint 和 TypeScript 中都会报错。
eslint 中可以通过增加 globals
的配置来处理报错。代码看起来是这样的
{"globals": {"page": true}}
在 TypeScript 可以在 typings.d.ts
中进行定义:
示例代码如下:
// src/typings.d.ts// ... 代码省略declare const REACT_APP_ENV: 'test' | 'dev' | 'uat' | 'prod' | undefined;// 以下变量声明对应config.[env].ts文件内define的变量declare const API_URL: string;declare const API_SECRET_KEY: string;
config 是 node 环境,所以可以直接用 process.env
来直接拿到环境变量,但是非 node 环境的代码中,使用 process.env
可能只会获得 NODE_ENV
这个约定俗成的变量,别的变量 webpack 并不会自动注入。
关于
process.env
和NODE_ENV
请看这里。
这时候我们就需要使用 define
,他是通过 define-plugin
来实现的这个特性,在 config
中将 node 的环境变量注入 define 配置中。
使用时需要注意的是我们不需要通过 window['key']
的方式来使用它,而是直接使用。更具体的原理可以看一下define-plugin
插件的实现。