nest配置及环境变量

配置

配置问题:

  1. 直接使用.env文件,则会出现大量的process.env.xx的写法,且只能单独一个个获取,无法直接获取对象。

配置方案:

  1. 使用useClass

环境变量的配置在.env里面配置后,需要引入到config/envs内部的不同文件中再做一次配置,最后使用configSerivce注入来获取配置信息

  • 可以将环境变量验证和转换为深层对象模式

config.module.ts

  {
    provide: 'ConfigServiceUseClass',
    useClass:
      process.env.NODE_ENV === 'development'
        ? DevelopmentConfigService
        : ProductionConfigService,
  },

DevelopmentConfigService(ProductionConfigService类同)

import { Injectable } from '@nestjs/common';

@Injectable()
export class DevelopmentConfigService {
  getConfig() {
    return 'development'; // 伪代码,这里应该返回环境变量转换的深层对象。
  }
}

控制器中使用

  @Inject('ConfigServiceUseClass')
  private ConfigServiceUseClass:
    | DevelopmentConfigService
    | ProductionConfigService,
  
  @Get()
  getConfig() {
    return this.ConfigServiceUseClass.getConfig();
  }
  1. 动态模块方式。
  • 使用dotenv来做引入解析。
  • 动态配置
  • 可以配置development.env.env文件
  • 变量默认是单值,获取不方便
  • 可以在引入环境变量后,将环境变量验证和转换为深层对象模式

config.module.ts

// 动态模块
export class ConfigModule {
  static register(options: OptionsInterface): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: CONFIG_OPTIONS,
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}

contant.ts

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
export const DATA_SOURCE = 'DATA_SOURCE';
export const PHOTO_REPOSITORY = 'PHOTO_REPOSITORY';

app.module.ts

// 注入配置
ConfigModule.register({ folder: './envs' }),

config.service.ts

import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';
import * as fs from 'fs';
import * as dotenv from 'dotenv';
import { resolve } from 'path';
import { CONFIG_OPTIONS } from '../constants';
import { OptionsInterface } from './interfaces';
@Injectable()
export class ConfigService {
  private readonly evnConfig: EnvConfig;
  constructor(@Inject(CONFIG_OPTIONS) private options: OptionsInterface) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    // const envFile = resolve(__dirname, '../../', this.options.folder, filePath); // 普通模块路径
    // const envFile = resolve(__dirname, '../', this.options.folder, filePath); // webpack模式路径
    // const envFile = resolve(process.cwd(), this.options.folder, filePath); // webpack
    const envFile = resolve(this.options.folder, filePath); // webpack
    this.evnConfig = dotenv.parse(fs.readFileSync(envFile));
    // 重组envConfig为深层对象模式。
  }
  get(key: string): string {
    console.log('this.evnConfig', this.evnConfig);
    return this.evnConfig[key];
  }
}

envs/development.env
envs/production.env

NODE_ENV=development
...

控制器中使用

  private configService: ConfigService,

  @Get()
  getEnvConfig(@Query('key') key: string) {
    return this.configService.get(key);
  }
  1. 使用自带的@nestjs/config,设置一个.env文件,在config/envs内分别设置不同环境的js文件来做验证和配置。然后在configuration.ts中进行环境配置项的合并。(目前使用的方法
  • 不需要写其他服务方法,最便捷。

安装nestjs自带的配置模块

npm i @nestjs/config

引入环境变量并转换为深层对象模式

envs/
default.ts
develoment.ts
production.ts

import { env } from 'process';
export const config = {
  db: {
    type: env.DB_TYPE || 'mysql',
    host: env.DB_HOTST || 'localhost',
    port: env.DB_PORT || 3306,
    username: env.DB_USER || '',
    passwrod: env.DB_PASSWROD || '',
    database: env.DB_NAME || '',
    logging: false,
    synchronize: false,
    autoLoadEntities: true,
  },
  service: {
    port: env.PORT || 7000,
    portDoc: env.PORTDOC || 9000,
  },
};

configuration.ts

import { mergeAll } from 'ramda';
import type { Config, Production, Default } from './configuration.interface';
export const configuration = async (): Promise<Config> => {
  const { config } = <{ config: Default }>(
    await import(`${__dirname}/envs/default`)
  );
  const { config: environment } = <{ config: Production }>(
    await import(`${__dirname}/envs/${process.env.NODE_ENV || 'development'}`)
  );

  return mergeAll([config, environment]);
};

configuration.interface.ts

import type { config as base } from './envs/default';
import type { config as production } from './envs/production';
export type Default = typeof base;
export type Production = typeof production;
export type Config = Default & Production;
export type ObjectType = Record<string, unknown>;

app.module.ts

ConfigModule.forRoot({
  isGlobal: true,
  load: [configuration], // 直接加载
  expandVariables: true, // 扩展变量,使用变量比如: API_URL=locahost:${PORT}
}),

优化点:

  • 可以使用joi包来对环境变量做校验。

增减环境配置

  1. env增减
  2. 各个环境配置文件增减
  3. 接口文件增减
  4. 作校验

目前的操作思路比较清晰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值