人人都会AI编程

17.4 多环境配置:开发 / 测试 / 预发布 / 生产环境隔离

更新时间:2026-07-11

在实际的项目开发流程中,一套代码通常需要部署到多个环境:开发环境(dev)供本地调试,测试环境(test)供 QA 验证,预发布环境(staging)用于上线前的最后确认,生产环境(prod)面向真实用户。不同环境有着不同的 API 地址、资源路径、调试开关、第三方密钥等参数,如果依靠手动修改代码来切换,极易造成配置错乱甚至线上事故。因此,通过工程化手段实现环境隔离是前端工程化的基本要求。

17.4.1 环境变量的核心原理

前端构建工具(Vite / Webpack)在打包时会通过环境变量向代码注入配置。这些变量在构建时被静态替换,因此可以在不修改源码的情况下,让同一个项目针对不同环境生成不同配置的产物。

典型的环境差异配置包括:

  • API 基础地址(BASE_URL)
  • 静态资源公共路径(PUBLIC_PATH)
  • 调试模式开关(DEBUG)
  • 第三方服务密钥(地图 SDK、埋点 ID 等,敏感密钥绝不可出现在前端环境变量中
  • 构建产物版本号、构建时间等

17.4.2 Vite 中的多环境配置

Vite 原生支持 .env 文件来管理环境变量,配合不同的模式(mode)自动加载对应的环境文件。

约定文件命名:

.env                  # 所有环境共享的变量
.env.development      # 开发环境(vite 默认 mode 为 development)
.env.test             # 自定义测试环境
.env.staging          # 自定义预发布环境
.env.production       # 生产环境(vite build 默认 mode 为 production)

加载优先级:
当运行 vite --mode staging 时,加载顺序为:

  1. .env(通用)
  2. .env.staging(覆盖通用变量)
  3. .env.staging.local(本地覆盖,通常加入 .gitignore

后加载的文件中的变量会覆盖先加载的同名变量。

示例 .env.development:

# 开发环境
VITE_API_BASE_URL=http://localhost:3000/api
VITE_APP_TITLE=MyApp(DEV)
VITE_DEBUG=true

示例 .env.production:

# 生产环境
VITE_API_BASE_URL=https://api.example.com
VITE_APP_TITLE=MyApp
VITE_DEBUG=false

注意:Vite 只暴露以 VITE_ 开头的变量给客户端代码,这是为了防止意外将敏感信息(如数据库密码)泄露到前端。在代码中通过 import.meta.env 访问:

const apiBase = import.meta.env.VITE_API_BASE_URL;
const debug = import.meta.env.VITE_DEBUG === 'true'; // 所有变量值均为字符串

TypeScript 类型提示:
src/vite-env.d.ts 中扩展 ImportMetaEnv 接口:

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_BASE_URL: string;
  readonly VITE_APP_TITLE: string;
  readonly VITE_DEBUG: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

17.4.3 自定义模式与构建命令

通过 --mode 参数可以指定任意环境模式,Vite 会自动加载对应的 .env.[mode] 文件:

// package.json 中的脚本
{
  "scripts": {
    "dev": "vite",
    "build:test": "vite build --mode test",
    "build:staging": "vite build --mode staging",
    "build:prod": "vite build --mode production"
  }
}

这样,CI/CD 流水线只需执行对应的构建命令即可生成不同环境的包。

17.4.4 Webpack 中的多环境配置(补充参考)

在 Webpack 项目中,通常使用 dotenvwebpack.DefinePlugin 来注入变量。如果你还在维护基于 CRA 的项目,其环境变量机制与 Vite 类似,但只暴露以 REACT_APP_ 开头的变量。

使用 webpack.DefinePlugin 可以在编译时将变量替换为字面量:

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

// 加载对应环境文件
const envConfig = dotenv.config({ path: `.env.${process.env.NODE_ENV}` }).parsed;

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.API_BASE_URL': JSON.stringify(envConfig.API_BASE_URL)
    })
  ]
};

17.4.5 安全原则与最佳实践

  1. 敏感密钥绝不可进入前端代码

所有环境变量在构建时会被写入源码包,任何前端变量都是公开的。数据库密码、服务端 API 密钥等敏感信息必须留在服务端,前端仅保存服务端对外提供的接口地址。

  1. 将 .env 文件加入 .gitignore

尤其 .env.local.env.*.local 可能包含个人开发配置,不应提交到版本库。团队共享的变量放在 .env.env.development 等文件中并提交,但务必确认其中没有密钥。

  1. 使用 CI/CD 注入构建变量

对于生产环境等敏感配置,在 CI 环境变量面板中设置,运行时注入而非写在代码仓库中。例如,Docker 构建或 GitHub Actions 中可以安全地传递 VITE_API_BASE_URL

  1. 运行时配置的灵活方案

如果希望同一构建包在不同环境生效(不重新构建),可以在公共目录放置一个静态 config.js 文件,在 index.html 中通过 <script> 引入,并将运行时配置挂载到 window 对象上。不过这种方式破坏了构建产物的纯静态性,更适合 ToB 私有部署场景。

  1. 验证环境变量

在应用入口处提前校验必需的环境变量,避免运行到一半才报错:

   if (!import.meta.env.VITE_API_BASE_URL) {
     throw new Error('缺少环境变量 VITE_API_BASE_URL');
   }
   

17.4.6 总结

多环境配置是前端工程化的基础能力。Vite 通过简洁的 .env 文件机制和模式选择,让环境隔离变得轻而易举。核心要点是:

  • 不同环境的配置写成独立文件,版本控制提交通用部分,敏感信息走 CI 注入。
  • 只暴露必要的变量给前端,严格遵循安全边界。
  • 利用构建命令的 --mode 参数在流水线中生成不同环境的部署包。

这套流程确保代码在不断流转的开发、测试、预发布直至上线的过程中,配置准确、安全、可追溯,是保障多环境协作井然有序的关键。