Skip to content

Dotenv 可以解析 .env 文件,config 可以解析 json 和 yaml。 在 nestjs 中可以使用 cross-env 在启动时设置环境变量:

json
"start:dev": "cross-env NODE_ENV=production nest build --webpack --webpackPath webpack-hmr.config.js --watch",

然后根据不同的环境变量指定不同的 env 文件路径:

ts
import { Module } from '@nestjs/common';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ConfigModule } from '@nestjs/config';

const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;

@Module({
  imports: [ConfigModule.forRoot({
    isGlobal: true,
    envFilePath: envFilePath
  }), UserModule],
  controllers: [],
  providers: [],
})
export class AppModule { }

公共的环境配置可以写在根目录的 .env 文件中,其他文件可以另行指定为 .env.development 的形式。

公共环境配置加载

ts
import { Module } from '@nestjs/common';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ConfigModule } from '@nestjs/config';
import * as dotenv from 'dotenv';

const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;

@Module({
  imports: [ConfigModule.forRoot({
    isGlobal: true,
    envFilePath: envFilePath,
    load: [() => dotenv.config({ path: '.env'})]
  }), UserModule],
  controllers: [],
  providers: [],
})
export class AppModule { }

用一个 load 数组接受 dotenv.config 返回的:

ts
export interface DotenvParseOutput {
  [name: string]: string;
}

load 要求的箭头函数 export type ConfigObject = Record<string, any>; 与该类型兼容。

YAML 数据拼接

  • 默认配置(default.yaml):存放通用配置,如数据库主机、日志级别等。
  • 环境特定配置(development.yaml、production.yaml):覆盖特定环境下的配置,如端口号、数据库用户名等。 当应用启动后,合并所需配置,统一访问。
ts
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';
import { merge } from 'lodash';

const config_filePath = join(__dirname, '../config/config.yaml');
const production_filePath = join(__dirname, '../config/productionConfig.yml');

const config = yaml.load(fs.readFileSync(config_filePath, 'utf8')) as Record<string, any>;
const productionConfig = yaml.load(fs.readFileSync(production_filePath, 'utf8')) as Record<string, any>;

export function loadConfig() {
  console.log(merge(config, productionConfig))
  return merge(config, productionConfig);
}

Config 库处理 JSON 配置

配置验证

ts
@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [mock],
      validationSchema: Joi.object({
        internalConfig: Joi.object({
          app: Joi.number().required()
        })
      }),
    }),
    UserModule,
  ],
  controllers: [],
  providers: [],
})