1. Introduction
Our projects often differentiate between multiple environments, such as test environment, pre-production environment, production environment, etc. In each environment, the interface address, static resource address, or other addresses may be different. For example, the interface address in the test environment is XXX.dev.com, and in the production environment it is XXX.pro.com. So how do we elegantly distinguish between different environments? If you have this question, I think this article will give you the answer
Note: This article uses the create-React-app official scaffolding generation project
2. Node environment variables
We write a piece of code like this when we’re developing
if (process.env.NODE_ENV==='development') {console.log('Development Environment');
}else if (process.env.NODE_ENV==='production') {console.log('Production environment');
}
Copy the code
Process. env is the node environment that the build tool injected for us at build time. NODE_ENV is used to differentiate the environment, but it only sets two environments for us
2.1 use cross – env
Cross-env is used to set the Node environment variables for us, using the so easy method, we need to install it before using it
NPM I cross-env -d or YARN add cross-env -d
Next modify the package.json file
//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"}}Copy the code
If we print process.env in the project, we will see that there is an extra variable in it, so that we can differentiate the environment based on this variable, which is not optimal
if (process.env.REACT_APP_MODE==='dev') {console.log('Test environment');
}else if (process.env.REACT_APP_MODE==='pre') {console.log('Pre-production environment');
}else if(process.env.REACT_APP_MODE==='pro') {console.log('Production environment');
}
Copy the code
2.2 use webpack DefinePlugin
Webpack. DefinePlugin is also used to help us set environment variables. It can set multiple values at once and it is easy to use by changing the configuration of Webpack and adding a plugin
new webpack.DefinePlugin({
'process.env': JSON.stringify(
{
APP_MODE: 'Custom environment variables'.XIXI: 'Custom environment variables'.HAHA: 'Custom environment variables',})})Copy the code
Once configured, we run one of the above commands at will, print process.env, and find that the variables in it happen to be our own
Some of you may have already figured out a better way to set the Node environment variable in package.json using cross-env. Then modify the Plugin configuration of Webpack according to the cross-env Settings variable and batch set more values using webpack.definePlugin
2.3 Combined Use
Modify the webPack configuration
new webpack.DefinePlugin({
'process.env': JSON.stringify(
process.env.REACT_APP_MODE === 'dev' ?
{
APP_MODE: 'Custom environment variable --dev'.XIXI: 'Custom environment variable --dev'.HAHA: 'Custom environment variable --dev',
}
: process.env.REACT_APP_MODE === 'pre' ?
{
APP_MODE: 'Custom environment variable --pre'.XIXI: 'Custom environment variable --pre'.HAHA: 'Custom environment variable --pre',}, {APP_MODE: 'Custom environment variables --pro'.XIXI: 'Custom environment variables --pro'.HAHA: 'Custom environment variables --pro',})})Copy the code
So we can execute different commands to set different environment variables, and then in the project area according to the different environment to write different code, is not very easy ah
3. The final version
The above method, while satisfying our development needs, is still not elegant, even a little low, and there will be some maintenance costs, let’s implement a final version
We’ll start with a plug-in called Dotenv, which loads variables in environment variables from the. Env file into process.env
NPM I dotenv-d or YARN add dotenv-d
Create a new file in the root directory
//.env.dev React_App_baseURL = http://requestUrl.dev.com React_App_officeUrl = http://office.dev.com React_App_title = Title of the dev environmentCopy the code
//.env.pre React_App_baseURL = http://requestUrl.pre.com React_App_officeUrl = http://office.pre.com React_App_title = Pre Test environment TitleCopy the code
//.env.pro React_App_baseURL = http://requestUrl.pro.com React_App_officeUrl = http://office.pro.com React_App_title = Pro Test environment TitleCopy the code
Then go modify the webPack configuration
const webpack = require('webpack');
// Get the current environment, set by cross-env
const REACT_APP_MODE = process.env.REACT_APP_MODE;
// Load variables corresponding to the. Env file
require('dotenv').config({path:`.env.${REACT_APP_MODE}`});
// Since process.env has a lot of values, we define a re, and only set it for variables whose names start with React_App_
const reg = /^React_App_/;
const env = {};
for (const key in process.env) {
// Set this parameter only when the key is NODE_ENV or the re check is passed
if (key === 'NODE_ENV'|| reg.test(key)) { env[key] = process.env[key]; }}// Modify the corresponding plugin
plugins: [new webpack.DefinePlugin({
'process.env': JSON.stringify(env)
})
]
Copy the code
Then we run the above commands separately and find that the set variables are in effect
4. At the end
Distinguishing between different environments is a common point in a project, but the specific scenario depends on the project situation to choose the best scheme, this article is just a reference for you, I hope to help you
Finally, git repository address is attached to you. If you are interested, you can clone it and learn more about it