只需一个配置让你在项目中优雅的区分多个环境
前言
我们的项目往往要区分多个环境,比如测试环境、预生产环境、生产环境等等,各个环境下接口地址、静态资源地址或者其它都可能会有所不同,比如测试环境的接口地址是xxx.dev.com,而到了生产环境又变成了xxx.pro.com,那么我们如何优雅的去区分不同的环境呢,如果你也有这个疑惑,那么我想这篇文章会带给你答案
注:本文使用的是create-react-app官方脚手架生成的项目
2.node环境变量
我们在开发的时候会写着到这样一块代码
js
复制代码
if (process.env.NODE_ENV==='development'){
console.log('开发环境');
}else if (process.env.NODE_ENV==='production'){
console.log('生产环境');
}
process.env是构建工具在构建的时候帮我们注入的node环境信息,里面的NODE_ENV就是让我们用于区分环境的,但是它只帮我们设置了两种环境,如果再多一种环境,那这种配置就不够用了,就需要我们手动去增加环境
2.1 使用cross-en
npm i cross-env -D 或 yarn add cross-env -D
接下来修改package.json文件
json
复制代码
//package.json
{
"scripts": {
"start:dev": "cross-env REACT_APP_MODE=dev craco start",
"start:pre": "cross-env REACT_APP_MODE=pre craco start",
"start:pro": "cross-env REACT_APP_MODE=pro craco start"
}
}
接下来我们依次实行命令,在项目中打印process.env,会发现里面多了一个变量,这样我们就可以根据这个变量去区分环境,当然这不是最优方案
js
复制代码
if (process.env.REACT_APP_MODE==='dev'){
console.log('测试环境');
}else if (process.env.REACT_APP_MODE==='pre'){
console.log('预生产环境');
}else if(process.env.REACT_APP_MODE==='pro'){
console.log('生产环境');
}
2.2 使用webpack.DefinePlugin
webpack.DefinePlugin也是用来帮我们设置环境变量的,它可以一次性设置多个值,并且使用方法也很easy,使用方式是需要去更改webpack的配置,增加一个plugin
js
复制代码
new webpack.DefinePlugin({
'process.env': JSON.stringify(
{
APP_MODE: '自定义环境变量',
XIXI: '自定义环境变量',
HAHA: '自定义环境变量',
}
)
})
配置好以后我们随意运行上面运行过的其中一个命令,打印process.env,发现里面的变量刚好是我们自己设置的
看到了这里有的同学可能已经想到更好的办法了,那就是在package.json中使用cross-env去设置node环境变量,然后再修改webpack的plugin配置根据cross-env设置变量再去使用webpack.DefinePlugin批量设置更多的值
2.3 联合使用
修改webpack的配置
js
复制代码
new webpack.DefinePlugin({
'process.env': JSON.stringify(
process.env.REACT_APP_MODE === 'dev' ?
{
APP_MODE: '自定义环境变量--dev',
XIXI: '自定义环境变量--dev',
HAHA: '自定义环境变量--dev',
}
: process.env.REACT_APP_MODE === 'pre' ?
{
APP_MODE: '自定义环境变量--pre',
XIXI: '自定义环境变量--pre',
HAHA: '自定义环境变量--pre',
} :
{
APP_MODE: '自定义环境变量--pro',
XIXI: '自定义环境变量--pro',
HAHA: '自定义环境变量--pro',
}
)
})
这样我们我们执行不同的命令就可以去设置不同的环境变量了,然后在项目中区根据不同的环境去书写不同的代码,是不是很easy啊
3.最终版
上面的方法虽然可以满足我们的开发需要,但是还是不够优雅,甚至可以说是有点low,而且还会有一定的维护成本,接下来我们实现一个最终版
npm i dotenv -D 或 yarn add dotenv -D
在根目录下新建文件
ini
复制代码
//.env.dev
React_App_baseURL = http://requestUrl.dev.com
React_App_officeUrl = http://office.dev.com
React_App_title = dev环境的title
ini
复制代码
//.env.pre
React_App_baseURL = http://requestUrl.pre.com
React_App_officeUrl = http://office.pre.com
React_App_title = pre测试环境title
ini
复制代码
//.env.pro
React_App_baseURL = http://requestUrl.pro.com
React_App_officeUrl = http://office.pro.com
React_App_title = pro测试环境title
然后去修改webpack的配置
js
复制代码
const webpack = require('webpack');
//获取当前环境,由cross-env设置的
const REACT_APP_MODE = process.env.REACT_APP_MODE;
//加载对应.env文件的变量
require('dotenv').config({path:`.env.${REACT_APP_MODE}`});
//因为process.env里面的值很多,所以我们定义一个正则,只有是命名以React_App_开头的变量我们才去设置它
const reg = /^React_App_/;
const env = {};
for (const key in process.env) {
//只有key为NODE_ENV或者正则校验通过才去设置
if (key === 'NODE_ENV' || reg.test(key)) {
env[key] = process.env[key];
}
}
//修改对应的plugin
plugins:[
new webpack.DefinePlugin({
'process.env': JSON.stringify(env)
})
]
接下来我们去分别去运行上面的命令,发现设置的变量生效了
4.结尾
区分不同环境是项目中很常见的点,但具体的场景还需看项目情况择选最优方案,这篇文章只是给大家做一个参考,希望能帮到各位
转载自:https://juejin.cn/post/7234336398824194106