• Nestjs开发环境和生产环境的配置


    这篇是Nest微服务训练营基础篇一小节,训练营大概会有100多篇关于Nest实操的文字,本小节讲述开发过程中环境变量的区分,更多精彩文章关注我,有需要可以加我微信:332904234,备注好来源

    一、简单的使用.env文件来实现配置文件

    • 1、安装依赖包

      npm install dotenv
      npm install @types/dotenv -D
      
      • 1
      • 2
    • 2、根目录下创建一个.env的文件,如果是线上项目将.env加入到.gitignore中,如果是自己学习阶段无所谓

    • 3、在.env文件中写入端口号及项目前缀

      PREFIX=api/v1
      PORT=4000
      
      • 1
      • 2
    • 4、在main.ts中使用

      import 'dotenv/config'; // 这行是关键代码
      import { Logger } from '@nestjs/common';
      import { NestFactory } from '@nestjs/core';
      import { AppModule } from './app.module';
      
      export const IS_DEV = process.env.NODE_ENV !== 'production';
      const PORT = process.env.PORT || 8080;
      const PREFIX = process.env.PREFIX || '/';
      
      async function bootstrap() {
        const logger: Logger = new Logger('main.ts');
        const app = await NestFactory.create(AppModule, {
          // 开启日志级别打印
          logger: IS_DEV ? ['log', 'debug', 'error', 'warn'] : ['error', 'warn'],
        });
        await app.listen(PORT, () => {
          logger.log(`服务已经启动,接口请访问:http://wwww.localhost:${PORT}/${PREFIX}`);
        });
      }
      bootstrap();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 5、这种方式使用简单,只要安装两个依赖包就可以,但是不足之处在于不能区分开发环境和生产环境的配置,都统一写在.env文件中,每次要使用的时候还要process.env.xx的方式来使用,下面会介绍如何区分开发环境和生产环境使用不同的配置文件,方便环境中变量的管理

    二、使用config的依赖包来方便获取配置文件中的配置

    • 1、安装依赖包,官网地址
      npm install @nestjs/config
      
      • 1
    • 2、在app.module.ts中使用
      @Module({
        imports: [
          ConfigModule.forRoot({
            isGlobal: true,
            envFilePath: ['.env'],
          }),
        ],
        controllers: [AppController],
        providers: [AppService, Logger],
      })
      export class AppModule {}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 3、在需要获取配置的地方使用ConfigService提供一个get方法来获取
      console.log(this.configService.get('PORT'), '当前的端口');
      
      • 1
    • 4、说明下如果使用了@nestjs/config这个包,在main.ts文件首部可以不用引入import 'dotenv/config'

    三、使用.env的方式来区分环境

    • 1、在项目根目录下分别创建.env.env.dev.env.prod文件并且在ConfigModule中加载
      @Module({
        imports: [
          ConfigModule.forRoot({
            isGlobal: true,
            envFilePath: ['.env.dev', '.env', '.env.prod'],
          }),
        ],
        controllers: [AppController],
        providers: [AppService, Logger],
      })
      export class AppModule {}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 2、根据官网上的介绍是前面的优先级比后面的优先级高,简单的理解就是在获取的时候会先查找envFilePath数组的第一项,里面有就直接返回当前的,如果没有就会查找第二个,根据这个原理我们可以重新来编排下envFilePath数组项
    • 3、安装依赖包来配置设置当前环境,上面使用process.env.NODE_ENV已经不能判断当前是什么环境
      npm install cross-env
      
      • 1
    • 4、手动配置启动环境的配置,修改package.json文件启动命令
      ...
      "scripts": {
        "prebuild": "rimraf dist",
        "build": "nest build",
        "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
        "start": "cross-env RUNNING_ENV=dev nest start",
        "start:dev": "cross-env RUNNING_ENV=dev nest start --watch",
        "start:debug": "nest start --debug --watch",
        "start:prod": "cross-env RUNNING_ENV=prod node dist/main",
      }
      ...
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 5、重新定义获取当前环境的变量,注意不能定义在main.ts中,必须定义在app.module.ts文件中
      export const IS_DEV = process.env.RUNNING_ENV !== 'prod';
      
      • 1
    • 6、根据环境来切换配置
      import { Logger, Module } from '@nestjs/common';
      import { ConfigModule } from '@nestjs/config';
      import { AppController } from './app.controller';
      import { AppService } from './app.service';
      let envFilePath = ['.env'];
      export const IS_DEV = process.env.RUNNING_ENV !== 'prod';
      
      if (IS_DEV) {
        envFilePath.unshift('.env.dev');
      } else {
        envFilePath.unshift('.env.prod');
      }
      @Module({
        imports: [
          ConfigModule.forRoot({
            isGlobal: true,
            envFilePath,
          }),
        ],
        controllers: [AppController],
        providers: [AppService, Logger],
      })
      export class AppModule {}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      import { AppModule, IS_DEV } from './app.module';
      
      const PORT = process.env.PORT || 8080;
      const PREFIX = process.env.PREFIX || '/';
      
      console.log(`Port: ${PORT}`, IS_DEV);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 7、尝试从.env.dev文件中删除PORT的时候控制台会打印出.env的端口,如果加上会打印出.env.dev的端口
    • 8、关于.env.env.dev.env.prod几个文件说明
      • .env文件存放一些通用的配置,在开发环境和生产环境都保持一样的
      • .env.dev文件存放开发环境的配置
      • .env.prod文件存放生产部署需要的配置
    • 9、关于使用.env来配置不同环境的代码参考,代码地址

    四、使用yml文件来做配置文件

    • 1、官网上也有介绍,官网参考地址
    • 2、安装依赖包
      npm install yaml
      
      • 1
    • 3、在根目录下创建application.dev.ymlapplication.prod.yml两个文件来区分配置开发环境和生产环境,并且添加值.gitignore文件中
    • 4、创建一个文件用来读取配置utils/config.ts
      import { parse } from 'yaml';
      import * as path from 'path';
      import * as fs from 'fs';
      
      // 获取项目运行环境
      export const getEnv = () => {
        return process.env.RUNNING_ENV;
      };
      
      export const IS_DEV = getEnv() === 'dev';
      // 读取项目配置
      export const getConfig = () => {
        const environment = getEnv();
        console.log(environment, '当前运行的环境');
        const yamlPath = path.join(process.cwd(), `./application.${environment}.yml`);
        const file = fs.readFileSync(yamlPath, 'utf8');
        const config = parse(file);
        return config;
      };
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 5、修改app.module.ts文件的配置
      import { Logger, Module } from '@nestjs/common';
      import { ConfigModule } from '@nestjs/config';
      import { AppController } from './app.controller';
      import { AppService } from './app.service';
      import { getConfig } from './utils';
      
      @Module({
        imports: [
          ConfigModule.forRoot({
            ignoreEnvFile: false, // 忽视默认读取.env的文件配置
            isGlobal: true, // 全局注入
            load: [getConfig], // 加载配置文件
          }),
        ],
        controllers: [AppController],
        providers: [AppService, Logger],
      })
      export class AppModule {}
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 6、修改main.ts文件,之前直接从process.env.的方式获取不到配置项目了,要改为方法的调用方式
      import { getConfig, IS_DEV } from './utils';
      
      const config = getConfig();
      const PORT = config.PORT || 8080;
      const PREFIX = config.PREFIX || '/';
      ... 省去100行代码
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 7、在别的地方要获取配置文件和之前一样的使用this.configService.get('PORT')的方式来获取
    • 8、本小节代码见,代码地址
  • 相关阅读:
    [附源码]Python计算机毕业设计Django葡萄酒销售管理系统论文
    熊市下PLATO如何通过Elephant Swap,获得溢价收益?
    【云原生】Kubernetes介绍
    Simulink求解器综合介绍
    Nacos使用教程(三)——nacos注册中心(2)
    【algorithm】算法学习----堆
    Matlab写入nc文件遇到‘Start+count exceeds dimension bound (NC_EEDGE)‘问题的解决办法
    shell入门第四课循环结构
    多目标水母搜索算法(Multi-Objective Jellyfish Search algorithm,MOJS)求解微电网优化--提供MATLAB代码
    Synchronized面试题
  • 原文地址:https://blog.csdn.net/kuangshp128/article/details/126336663