不使用未维护的dotenv库,按构建环境加载Rust环境变量的规范方法
不依赖旧版dotenv的Rust多环境变量加载方案
下面是几种规范且维护活跃的实现方式,完全不需要依赖已停止维护的dotenv v0版本:
1. 用Rust原生构建脚本(build.rs)实现构建时注入
这是最贴近官方规范的方式,无需额外第三方库:
- 按环境创建配置文件,比如
.env.dev、.env.uat、.env.live,格式采用KEY=VALUE的键值对 - 在项目根目录创建
build.rs脚本,逻辑如下:- 读取构建时指定的环境标识(比如通过
BUILD_ENV环境变量传递,执行BUILD_ENV=dev cargo build) - 根据标识选择对应的.env文件,解析其中的键值对
- 通过
println!("cargo:rustc-env=KEY=VALUE")将变量注入到编译环境
- 读取构建时指定的环境标识(比如通过
- 业务代码中直接用
env!("KEY")获取构建时注入的变量值
示例build.rs代码:
use std::fs; use std::env; fn main() { // 获取构建环境标识,默认dev let env = env::var("BUILD_ENV").unwrap_or_else(|_| "dev".to_string()); let env_file = format!(".env.{}", env); // 读取并解析环境文件 let content = fs::read_to_string(env_file).expect("Failed to read env file"); for line in content.lines() { let line = line.trim(); if line.is_empty() || line.starts_with('#') { continue; } if let Some((key, value)) = line.split_once('=') { println!("cargo:rustc-env={}={}", key.trim(), value.trim()); } } }
2. 使用活跃维护的config crate实现多环境配置
config crate是当前Rust生态中维护良好的配置管理库,支持多环境分层、配置文件合并、环境变量覆盖等功能:
- 在
Cargo.toml中添加依赖:config = "0.13"(版本以最新稳定版为准) - 按环境创建配置文件,比如
config/dev.toml、config/uat.toml、config/live.toml,支持TOML/YAML/JSON等格式 - 代码中根据环境变量加载对应环境的配置:
示例代码:
use config::{Config, Environment, File}; use std::env; #[derive(Debug, serde::Deserialize)] struct AppConfig { database_url: String, api_key: String, } fn load_config() -> AppConfig { // 获取环境标识,默认dev let env = env::var("APP_ENV").unwrap_or_else(|_| "dev".to_string()); let config = Config::builder() // 可选:加载基础通用配置 .add_source(File::with_name("config/base.toml").required(false)) // 加载对应环境的专属配置 .add_source(File::with_name(&format!("config/{}.toml", env)).required(true)) // 允许系统环境变量覆盖配置(前缀APP_,比如APP_DATABASE_URL会覆盖database_url) .add_source(Environment::with_prefix("APP")) .build() .expect("Failed to build config"); config.try_deserialize().expect("Failed to deserialize config") }
构建时指定环境变量即可:APP_ENV=uat cargo run
3. 结合构建特性(features)+ 系统环境变量
如果完全不想依赖第三方库,也可以通过Cargo的构建特性区分环境,配合系统环境变量加载:
- 在
Cargo.toml中定义特性:[features] default = ["dev"] dev = [] uat = [] live = [] - 代码中根据特性判断环境,读取对应系统环境变量:
fn get_database_url() -> String { #[cfg(feature = "dev")] let var_name = "DEV_DATABASE_URL"; #[cfg(feature = "uat")] let var_name = "UAT_DATABASE_URL"; #[cfg(feature = "live")] let var_name = "LIVE_DATABASE_URL"; std::env::var(var_name).expect("Database URL not set") }
构建时启用对应特性:cargo build --features uat,同时确保对应的系统环境变量已配置
内容的提问来源于stack exchange,提问作者Rob Lyndon
相关产品推荐
相关产品推荐

