阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 多环境变量配置管理

多环境变量配置管理

作者:陈川 阅读数:20627人阅读 分类: 构建工具

多环境变量配置管理的必要性

现代前端项目通常需要在不同环境中运行,比如开发环境、测试环境、预发布环境和生产环境。每个环境可能需要不同的API地址、功能开关、日志级别等配置。硬编码这些变量会导致代码难以维护,也增加了部署出错的概率。通过环境变量配置管理,可以实现一套代码在不同环境中的灵活适配。

Webpack环境变量基础配置

Webpack提供了DefinePlugin插件来定义全局常量,这是实现环境变量管理的基础方式。在webpack.config.js中:

const webpack = require('webpack');

module.exports = {
  // ...其他配置
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development'),
      'API_URL': JSON.stringify('https://dev.api.example.com')
    })
  ]
}

使用时可以直接在代码中访问这些变量:

console.log(process.env.NODE_ENV); // 输出 'development'
fetch(`${API_URL}/users`).then(...)

多环境配置文件方案

更专业的做法是为每个环境创建单独的配置文件。典型的目录结构如下:

config/
  ├── dev.env.js
  ├── test.env.js
  ├── stage.env.js
  ├── prod.env.js
  └── index.js

示例dev.env.js内容:

module.exports = {
  NODE_ENV: '"development"',
  API_URL: '"https://dev.api.example.com"',
  DEBUG_MODE: true,
  AUTH_ENABLED: false
}

config/index.js作为统一入口:

const env = process.env.NODE_ENV || 'development'
module.exports = require(`./${env}.env.js`)

使用dotenv管理敏感变量

对于包含敏感信息的变量,可以使用dotenv-webpack插件:

npm install dotenv-webpack --save-dev

在项目根目录创建.env文件:

API_KEY=your_api_key_here
DB_PASSWORD=secure_password

webpack配置:

const Dotenv = require('dotenv-webpack');

module.exports = {
  plugins: [
    new Dotenv({
      path: './.env', // 默认路径
      safe: true // 加载.env.example检查必需变量
    })
  ]
}

环境变量注入策略

根据构建环境动态注入变量:

// webpack.config.js
const envConfig = require('./config')

module.exports = (env) => {
  return {
    // ...其他配置
    plugins: [
      new webpack.DefinePlugin({
        'process.env': envConfig[env.NODE_ENV]
      })
    ]
  }
}

构建命令示例:

{
  "scripts": {
    "build:dev": "webpack --env.NODE_ENV=development",
    "build:prod": "webpack --env.NODE_ENV=production"
  }
}

类型安全的环境变量

在TypeScript项目中,可以定义环境变量类型:

// src/types/env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    readonly NODE_ENV: 'development' | 'production' | 'test';
    readonly API_URL: string;
    readonly GA_TRACKING_ID?: string;
  }
}

使用示例:

const apiUrl: string = process.env.API_URL;
if (process.env.NODE_ENV === 'development') {
  console.log('开发模式');
}

环境特定代码的优化

通过环境变量实现条件编译:

if (process.env.NODE_ENV === 'production') {
  // 生产环境特定代码
  enableAnalytics();
  disableDebugLogs();
} else {
  // 开发环境代码
  mockAPIResponses();
}

Webpack的TerserPlugin可以基于环境变量移除死代码:

optimization: {
  minimizer: [
    new TerserPlugin({
      terserOptions: {
        compress: {
          dead_code: true,
          global_defs: {
            'process.env.NODE_ENV': 'production'
          }
        }
      }
    })
  ]
}

跨平台环境变量处理

处理不同操作系统环境变量差异:

// 统一处理布尔值
function parseBool(value) {
  if (typeof value === 'boolean') return value;
  if (typeof value === 'string') {
    return value.toLowerCase() === 'true';
  }
  return false;
}

// 使用示例
const shouldLog = parseBool(process.env.ENABLE_LOGGING);

运行时环境变量注入

对于需要部署后修改变量的场景,可以使用public目录下的config.js:

// public/config.js
window.__env__ = {
  API_URL: 'https://runtime.api.example.com',
  FEATURE_FLAGS: {
    newDashboard: true
  }
};

HTML中引入:

<script src="%PUBLIC_URL%/config.js"></script>

代码中访问:

const apiUrl = window.__env__.API_URL || process.env.API_URL;

环境变量验证

添加验证确保必需变量存在:

// config/validator.js
function validateEnv(env) {
  const requiredVars = ['API_URL', 'AUTH_DOMAIN'];
  const missingVars = requiredVars.filter(varName => !env[varName]);
  
  if (missingVars.length > 0) {
    throw new Error(`缺少必需环境变量: ${missingVars.join(', ')}`);
  }
}

module.exports = validateEnv;

在webpack配置中使用:

const validateEnv = require('./config/validator');
const envConfig = require('./config');

validateEnv(envConfig[env.NODE_ENV]);

环境变量加密方案

对敏感变量进行加密:

// config/encrypt.js
const crypto = require('crypto');

function encrypt(text, key) {
  const cipher = crypto.createCipher('aes-256-cbc', key);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

function decrypt(encrypted, key) {
  const decipher = crypto.createDecipher('aes-256-cbc', key);
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

module.exports = { encrypt, decrypt };

使用示例:

const { encrypt, decrypt } = require('./config/encrypt');
const encrypted = encrypt(process.env.DB_PASSWORD, 'secret-key');
const decrypted = decrypt(encrypted, 'secret-key');

环境变量与功能开关

实现功能开关:

// src/features.js
export const features = {
  newCheckout: process.env.FEATURE_NEW_CHECKOUT === 'true',
  darkMode: process.env.FEATURE_DARK_MODE === 'true',
  experimentalAPI: process.env.FEATURE_EXPERIMENTAL_API === 'true'
};

// 使用示例
if (features.newCheckout) {
  renderNewCheckout();
} else {
  renderLegacyCheckout();
}

环境变量命名规范

推荐命名约定:

// 基础配置
APP_NAME
API_BASE_URL

// 功能开关
FEATURE_[功能名]_ENABLED

// 第三方服务
AWS_S3_BUCKET
GOOGLE_ANALYTICS_ID

// 安全相关
AUTH0_CLIENT_ID
ENCRYPTION_KEY

环境变量文档化

使用JSDoc生成文档:

/**
 * @env {string} API_BASE_URL - 基础API地址
 * @env {boolean} FEATURE_NEW_UI - 是否启用新UI
 * @env {number} MAX_API_RETRIES - API最大重试次数
 * @env {string} SENTRY_DSN - Sentry错误跟踪DSN
 */

环境变量与测试配置

测试环境特殊处理:

// jest.config.js
module.exports = {
  globals: {
    'process.env': {
      NODE_ENV: 'test',
      API_URL: 'http://localhost:3000/mock-api',
      TEST_USER: 'jest@example.com'
    }
  }
};

环境变量调试技巧

调试环境变量加载:

// 打印所有环境变量
console.log('Loaded environment variables:', {
  ...process.env,
  // 过滤敏感信息
  API_KEY: process.env.API_KEY ? '***' : undefined
});

// 检查变量来源
console.log('NODE_ENV from:', process.env.NODE_ENV);

环境变量与Docker集成

Dockerfile示例:

FROM node:16

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

COPY . .
RUN npm install && npm run build

CMD ["node", "server.js"]

构建命令:

docker build --build-arg NODE_ENV=development -t my-app:dev .

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌