如何在NestJS中为开发与生产环境配置不同的环境变量文件
1. 创建与组织多环境配置文件
直接在项目根目录下按 .env.{环境名} 的规则创建配置文件,同时建议保留一个 .env.example 作为模板,方便团队成员快速配置本地环境:
.env.development:存放开发环境专属配置,比如本地数据库地址、调试端口、日志级别等.env.production:存放生产环境配置,包含线上数据库连接信息、API密钥、生产端口等.env.example:仅保留配置项的key,不填写敏感值,作为示例提交到代码仓库
示例文件内容:.env.development:
DB_HOST=localhost DB_PORT=5432 DB_USER=dev_user DB_PASS=dev_pass PORT=3000 LOG_LEVEL=debug
.env.production:
DB_HOST=prod-db.example.com DB_PORT=5432 DB_USER=prod_user DB_PASS=prod_secure_pass PORT=8080 LOG_LEVEL=info
最后记得把 .env.development、.env.production 加入 .gitignore,防止敏感信息泄露到代码仓库。
2. 基于NODE_ENV加载对应配置
原生方式(不依赖框架库)
先安装基础依赖:
npm install dotenv dotenv-expand --save
在项目入口文件 src/main.ts 最顶部添加加载逻辑,根据 NODE_ENV 自动匹配对应配置文件:
import * as dotenv from 'dotenv'; import * as dotenvExpand from 'dotenv-expand'; const env = process.env.NODE_ENV || 'development'; const envConfig = dotenv.config({ path: `.env.${env}` }); dotenvExpand.expand(envConfig); // 后续NestJS启动逻辑 import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(process.env.PORT || 3000); } bootstrap();
然后在 package.json 中配置启动命令,指定对应的 NODE_ENV:
{ "scripts": { "start:dev": "NODE_ENV=development nest start --watch", "start:prod": "NODE_ENV=production node dist/main" } }
跨平台兼容
Windows系统下设置环境变量需要用 set NODE_ENV=development,可以用 cross-env 库实现跨平台兼容:
npm install cross-env --save-dev
修改启动命令:
{ "scripts": { "start:dev": "cross-env NODE_ENV=development nest start --watch", "start:prod": "cross-env NODE_ENV=production node dist/main" } }
3. 推荐简化流程的库:@nestjs/config
NestJS官方提供的 @nestjs/config 模块集成了 dotenv,提供贴合NestJS生态的配置管理方案,支持全局配置、配置验证、自定义配置文件等功能。
安装依赖
npm install @nestjs/config dotenv --save
基本配置
在 AppModule 中导入 ConfigModule,根据 NODE_ENV 加载对应环境文件:
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ envFilePath: `.env.${process.env.NODE_ENV || 'development'}`, isGlobal: true, // 全局生效,无需在其他模块重复导入 cache: true, // 缓存配置,提升性能 }), ], }) export class AppModule {}
使用配置
通过 ConfigService 注入获取环境变量:
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; @Injectable() export class DatabaseService { constructor(private configService: ConfigService) {} getDbConfig() { return { host: this.configService.get<string>('DB_HOST'), port: this.configService.get<number>('DB_PORT'), username: this.configService.get<string>('DB_USER'), password: this.configService.get<string>('DB_PASS'), }; } }
进阶:配置验证
用 Joi 库对配置项进行格式验证,避免非法配置:
npm install @hapi/joi --save
修改 ConfigModule 配置:
import * as Joi from '@hapi/joi'; ConfigModule.forRoot({ envFilePath: `.env.${process.env.NODE_ENV || 'development'}`, isGlobal: true, validationSchema: Joi.object({ NODE_ENV: Joi.string().valid('development', 'production', 'test').default('development'), DB_HOST: Joi.string().required(), DB_PORT: Joi.number().default(5432), PORT: Joi.number().default(3000), }), })
自定义配置文件
如果需要复杂配置逻辑,可创建单独配置文件目录,比如 src/config/development.ts、src/config/production.ts:
// src/config/development.ts export default () => ({ database: { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10) || 5432, }, port: parseInt(process.env.PORT, 10) || 3000, });
在 ConfigModule 中加载对应文件:
import developmentConfig from './config/development'; import productionConfig from './config/production'; ConfigModule.forRoot({ isGlobal: true, load: [process.env.NODE_ENV === 'production' ? productionConfig : developmentConfig], })
内容的提问来源于stack exchange,提问作者abuzain

