Keywords: Create React App | Environment Variables | NODE_ENV | Build Configuration | React Development
Abstract: This article provides an in-depth exploration of various methods for configuring environment variables in Create React App projects across different environments. By analyzing the automatic setting mechanism of process.env.NODE_ENV, it details best practices for managing configurations like API endpoints using environment-specific files (.env.development, .env.production) and conditional logic. The article also covers security considerations for environment variables, build-time injection characteristics, and how to extend environment management capabilities using the env-cmd tool.
The Importance of Environment Variables in React Applications
In modern frontend development, environment variable management is a crucial aspect of building configurable applications. Create React App, as a popular React project scaffolding tool, provides a comprehensive environment variable handling mechanism that enables developers to easily configure different parameters for various environments.
Automatic NODE_ENV Setting Mechanism
Create React App automatically sets the process.env.NODE_ENV environment variable, providing the foundation for environment-specific configurations. When executing npm start, NODE_ENV is set to 'development'; when running npm run build, it is automatically set to 'production'. This automated environment detection mechanism eliminates the need for manual environment variable configuration.
Implementation of Conditional Environment Variable Configuration
Based on the automatic setting of NODE_ENV, developers can implement intelligent environment variable configurations. The following code example demonstrates how to dynamically select API endpoints based on the environment:
const apiUrl = process.env.NODE_ENV === 'production'
? process.env.REACT_APP_PROD_API_URL
: process.env.REACT_APP_DEV_API_URL;
The advantage of this approach lies in its simplicity and intuitiveness. The development environment uses REACT_APP_DEV_API_URL, while the production environment automatically switches to REACT_APP_PROD_API_URL. For production environment URLs that remain constant, further simplification is possible:
const apiUrl = process.env.NODE_ENV === 'production'
? 'https://api.example.com'
: process.env.REACT_APP_DEV_API_URL;
Usage of Environment-Specific Configuration Files
In addition to conditional checks in code, Create React App supports environment-specific configuration files. Creating .env.development and .env.production files allows for clearer separation of environment configurations:
# .env.development
REACT_APP_API_URL=http://localhost:5555
# .env.production
REACT_APP_API_URL=https://api.example.com
The priority rules of this method ensure correct configuration loading: npm start prioritizes loading .env.development.local, .env.local, .env.development, and finally .env; while npm run build loads in the order of .env.production.local, .env.local, .env.production, and .env.
Security Considerations for Environment Variables
It must be emphasized that environment variables in Create React App are embedded into the final bundle at build time. This means that any variables starting with REACT_APP_ become part of the client-accessible code. Therefore, sensitive information such as API keys, database passwords, etc., should never be stored in environment variables.
The following is an example of unsafe practice:
# Dangerous! Do not do this
REACT_APP_SECRET_KEY=your_private_key_here
Environment Variable Naming Conventions
Create React App mandates that custom environment variables must start with REACT_APP_, a design that effectively prevents accidental exposure of sensitive information from system environment variables. Only the built-in variables NODE_ENV and PUBLIC_URL are exceptions to this rule.
Handling Environment Variable Changes
When environment variables are modified, the development server must be restarted for the changes to take effect. This is because environment variables are read and cached when the server starts. For production environment builds, each environment variable change requires re-executing npm run build to generate a new bundle.
Advanced Environment Management Tools
For complex projects requiring management of multiple environments (such as staging, UAT, etc.), the env-cmd tool can be used to extend environment management capabilities:
npm install --save-dev env-cmd
Then configure in package.json:
"scripts": {
"build:stage": "env-cmd -f ./.stage.env npm run build",
"build:prod": "env-cmd -f ./.prod.env npm run build"
}
Dependency-Free Alternative Solutions
If introducing additional dependencies is undesirable, shell commands can be used to achieve similar functionality:
"scripts": {
"build": "sh -ac '. ./.env.${REACT_APP_ENV}; react-scripts build'",
"build:staging": "REACT_APP_ENV=staging npm run build",
"build:production": "REACT_APP_ENV=production npm run build"
}
Using Environment Variables in HTML
In addition to JavaScript code, environment variables can also be used in public/index.html:
<title>%REACT_APP_WEBSITE_NAME%</title>
During the build process, these placeholders are replaced with the corresponding environment variable values.
Build-Time Characteristics of Environment Variables
It is important to understand that environment variables are hard-coded into the application at build time, not dynamically read at runtime. This means that if dynamic configuration changes at runtime are needed, alternative solutions must be adopted, such as fetching configurations via API or using server-side rendering.
Optimization of Conditional Code
Conditional code based on NODE_ENV is optimized during production builds:
if (process.env.NODE_ENV !== 'production') {
// Development environment specific code
debugLogger.enable();
}
During production builds, such conditional checks are removed, thereby reducing bundle size.
Best Practices Summary
In actual projects, it is recommended to combine the use of environment-specific configuration files with conditional logic in code. For most scenarios, using .env.development and .env.production files in conjunction with process.env.NODE_ENV conditional checks is the optimal choice. For more complex environment requirements, consider using env-cmd or similar tools.
Regardless of the method chosen, always remember the security limitations of environment variables and establish clear team collaboration standards to ensure all developers have a consistent understanding of environment variable usage.