React 项目配置多环境打包

在实际项目开发中,前端 er 经常会面对多个环境的接口:开发环境、测试环境、生产环境,因此项目中网络请求的 baseUrl也须要跟随这些环境来变化。前端

可是,咱们通常会使用像 create-react-app或者 umi这样的脚手架来作项目的初始化,这些脚手架将 webpack 的配置黑盒化了,如何在不执行 eject 操做的前提下优雅地配置多个项目环境呢?react

在项目中最好不要一遇到问题就一键执行 eject 操做, eject 操做是不可逆的,执行以后会把全部细节都暴露在咱们面前,让项目目录变得很庞大。webpack

create-react-app 配置多环境接口

其实查看 create-react-app 的官方文档能够发现,create-react-app 默认是支持多个环境配置文件的:git

  • .env:默认。
  • .env.local:本地覆盖。 除 test 以外的全部环境都加载此文件
  • .env.development, .env.test, .env.production:设置特定环境。
  • .env.development.local, .env.test.local, .env.production.local:设置特定环境的本地覆盖。

左侧的文件比右侧的文件具备更高的优先级:github

  • npm start: .env.development.local, .env.development, .env.local, .env
  • npm run build: .env.production.local, .env.production, .env.local, .env
  • npm test: .env.test.local, .env.test, .env (注意没有 .env.local )

例如咱们部门目前开发流程中只有开发环境和测试环境两种接口(其中,本地开发和测试共用一个环境),web

因此,我须要将测试环境下打包时使用的接口地址指定为 env.development中的接口地址,我分别写了两份配置文件 .env.development 以及 env.production,可是根据以上create-react-app 的官方文档,在执行 build 命令时,默认是加载 .env.production 文件中的变量,因此我在测试服务器上执行 npm run build 命令时就会使得接口地址被指定为生产环境的接口地址,这显然不是我想要的。npm

怎么办呢?json

官方文档也给了咱们答案——可使用 dotenv 来作环境变量的管理(dotenv 可将环境变量从 .env 文件加载到 process.env中。)bash

由于咱们要在命令行中使用,因此咱们须要使用 dotenv-cli服务器

话很少说,让咱们开始吧~

写好各个环境的配置文件

首先,咱们能够写好每一个环境下的配置文件。

# .env.development
REACT_APP_BASE_URL='http://development.xxx.xxx' 
复制代码
# env.production
REACT_APP_BASE_URL='http://production.xxx.xxx' 
复制代码

修改 package.json 中的 scripts来指定环境

"scripts": {
    "start": "react-app-rewired start",
    "build:dev": "dotenv -e .env.development react-app-rewired build",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  }
复制代码

这样,当我须要在测试服务器上打包前端代码时,我就能够执行npm run build:dev来指定使用 .env.development中的环境变量了~

umi 配置多环境接口

有了以上的经验咱们就能够知道,其实多环境配置,不外乎就是将各个环境的配置文件分开,并使用额外的手段来在打包时指定对应环境的配置文件。

写好各个环境的配置文件

查看 UMI 文档 可知,环境变量被放在 config/config.js下的 define 这个配置中,

若是你使用 TypeScript 开发,那么配置文件是 config/config.ts。

因此一样的,咱们能够将原来的 config/config.ts 作个分身,写两份配置文件,分别是 config/config.dev.tsconfig/config.prod.ts

修改 package.json 中的 scripts 来指定环境

查看 umi生成的模版项目中的package.json 能够发现: umi 默认是使用 cross-env来为 umi 打包指定配置文件。因此咱们将package.json 中的 scripts 改写以下:

"scripts": {
  "start": "react-app-rewired start",
  "build-dev": "cross-env UMI_ENV=dev umi dev",
	"build-test": "cross-env UMI_ENV=test umi build",
	"build-prod": "cross-env UMI_ENV=prod umi build",
}
复制代码

Tips:将配置和代码分开存储

由于各个环境的部署版本之间,配置文件的差别程度可能很大,可是代码基本是不变的。

固然,上面所说的配置文件不包括内部应用程序的配置(例如,你可能将路由写成了配置文件)。

判断一个应用是否正确地将配置排除在代码以外,一个简单的方法是看该应用的基准代码是否能够马上开源,而不用担忧会暴露任何敏感的信息。

——《The Twelve-Factor App》

反面教材

一个比较典型的反面教材就是在代码中再写一份相似 getBaseUrl.js这样的文件来作环境判断:

// getBaseUrl.js
const TEST_DOMAIN = process.env.REACT_APP_BASE_URL
const PRODUCTION_DOMAIN = process.env.REACT_APP_PRODUCTION_BASE_URL
let domain = TEST_DOMAIN
switch (process.env.NODE_ENV) {
  case 'development':
    domain = TEST_DOMAIN
    break
  case 'production':
    domain = PRODUCTION_DOMAIN
    break
  default:
    domain = TEST_DOMAIN
    break
}
export default domain
复制代码

上面的变量是 .env 文件里面写好的变量:

# .env
REACT_APP_DEVELOPMENT_BASE_URL='http://xxxxxx' # 开发环境/测试环境的接口地址
REACT_APP_PRODUCTION_BASE_URL='http://xxxxxx'  # 生产环境的接口地址
复制代码

其实我本身在刚开始用 React 写项目的时候就是这么干的😅,这样至关于将配置写在了代码里面,不只可维护性比较差,并且别人看你代码的时候,可读性也比较差。

参考文件

相关文章
相关标签/搜索