Handling Environment Variables in Applications
Environment variables are critical for setting configuration parameters that adapt as environments switch between development, testing, and production. Managing these variables in a robust, scalable way ensures smooth development, deployment, and maintenance. It benefits both developers working on the code and DevOps engineers building CI/CD pipelines.
Here, I propose an approach to minimize code duplication and maintenance effort while adhering to the principles of Don't Repeat Yourself (DRY) and Keep It Simple, Stupid (KISS). Additionally, I’ll outline alternative strategies with their pros and cons.
Proposed Approach: Prefix-Based Variable Management
- Define Environment Variables with Suffixes (_DEV, _PROD):
VITE_API_URL_DEV=http://localhost:3000/v1
VITE_BRAND_NAME_DEV=TablesXi
VITE_API_URL_PROD=https://api.prod.com/v1
VITE_BRAND_NAME_PROD=TablesXi
VITE_MODE=dev
- Define Keys Object:
export const ENV_VARS = {
VITE_API_URL: "VITE_API_URL",
VITE_BRAND_NAME: "VITE_BRAND_NAME",
};
- Create a Utility Function:
const environmentMode = import.meta.env.VITE_MODE;
export const getEnvVar = (key) => {
const mode = environmentMode === "dev" ? "_DEV" : "_PROD";
return import.meta.env[`${key}${mode}`];
};
- Usage Example:
const apiUrl = getEnvVar(ENV_VARS.VITE_API_URL);
Advantages:
- Centralized management of environment logic.
- Minimal code duplication.
- Easy to extend for new variables.
Disadvantages:
- Slightly more verbose when adding new environment variables.
Alternative Approaches
1. Environment-Specific Configuration Files
- Create separate files for each environment (e.g.,
config.dev.js
,config.prod.js
, or from the .env files, prod.env, dev.env). - Dynamically import based on the environment.
const config = environmentMode === "dev" ? require("./config.dev") : require("./config.prod");
export default config;
Pros:
- Clear separation of environment-specific logic.
- Easier to manage complex configurations.
Cons:
- Requires additional maintenance for each environment.
- Difficult to track changes across multiple files.
2. Centralized Switch/Conditional Logic
- Use a single configuration file with
if
orswitch
statements.
const config = {
apiUrl: environmentMode === "dev" ? "http://localhost:3000/v1" : "https://api.prod.com/v1",
};
Pros:
- Single source of truth.
- No need for prefixes or suffixes.
Cons:
- Violates DRY when handling many variables.
- Difficult to scale.
Key Considerations
- Scalability: The solution should accommodate growing application needs with minimal rework.
- Maintainability: Avoid repetitive patterns and scattered logic.
- Developer Experience: Ensure ease of use for developers and DevOps engineers.
By adopting the prefix-based approach or carefully considering alternatives, you can achieve a clean, maintainable environment variable management strategy.
If you have suggestions or other approaches, feel free to share in the comments!
Best regards,
Ahmed
Top comments (0)