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

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

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

  • 1、安装依赖包

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

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

    PREFIX=api/v1
    PORT=4000
    
  • 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();
    
  • 5、这种方式使用简单,只要安装两个依赖包就可以,但是不足之处在于不能区分开发环境和生产环境的配置,都统一写在.env文件中,每次要使用的时候还要process.env.xx的方式来使用,下面会介绍如何区分开发环境和生产环境使用不同的配置文件,方便环境中变量的管理

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

  • 1、安装依赖包,官网地址
    npm install @nestjs/config
    
  • 2、在app.module.ts中使用
    @Module({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          envFilePath: ['.env'],
        }),
      ],
      controllers: [AppController],
      providers: [AppService, Logger],
    })
    export class AppModule {}
    
  • 3、在需要获取配置的地方使用ConfigService提供一个get方法来获取
    console.log(this.configService.get('PORT'), '当前的端口');
    
  • 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 {}
    
  • 2、根据官网上的介绍是前面的优先级比后面的优先级高,简单的理解就是在获取的时候会先查找envFilePath数组的第一项,里面有就直接返回当前的,如果没有就会查找第二个,根据这个原理我们可以重新来编排下envFilePath数组项
  • 3、安装依赖包来配置设置当前环境,上面使用process.env.NODE_ENV已经不能判断当前是什么环境
    npm install cross-env
    
  • 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",
    }
    ...
    
  • 5、重新定义获取当前环境的变量,注意不能定义在main.ts中,必须定义在app.module.ts文件中
    export const IS_DEV = process.env.RUNNING_ENV !== 'prod';
    
  • 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 {}
    
    import { AppModule, IS_DEV } from './app.module';
    
    const PORT = process.env.PORT || 8080;
    const PREFIX = process.env.PREFIX || '/';
    
    console.log(`Port: ${PORT}`, IS_DEV);
    
  • 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
    
  • 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;
    };
    
  • 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 {}
    
    
  • 6、修改main.ts文件,之前直接从process.env.的方式获取不到配置项目了,要改为方法的调用方式
    import { getConfig, IS_DEV } from './utils';
    
    const config = getConfig();
    const PORT = config.PORT || 8080;
    const PREFIX = config.PREFIX || '/';
    ... 省去100行代码
    
  • 7、在别的地方要获取配置文件和之前一样的使用this.configService.get('PORT')的方式来获取
  • 8、本小节代码见,代码地址
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
NestJS 中,我们可以使用 `dotenv` 模块来加载环境变量文件,以便在不同的环境中使用不同的配置。在 `env.ts` 文件中,我们可以定义不同环境的配置,如下所示: ```typescript import { ConfigModuleOptions } from '@nestjs/config'; const env = process.env.NODE_ENV; const development: ConfigModuleOptions = { envFilePath: '.env.development', }; const production: ConfigModuleOptions = { envFilePath: '.env.production', }; const test: ConfigModuleOptions = { envFilePath: '.env.test', }; const config = { development, production, test, }; export default config[env]; ``` 在上面的代码中,我们首先通过 `process.env.NODE_ENV` 获取当前环境,然后根据不同的环境返回对应的配置。例如,当 `NODE_ENV` 等于 `development` 时,我们使用 `.env.development` 文件中的配置;当 `NODE_ENV` 等于 `production` 时,我们使用 `.env.production` 文件中的配置;当 `NODE_ENV` 等于 `test` 时,我们使用 `.env.test` 文件中的配置。 我们可以在 `main.ts` 文件中通过 `ConfigModule` 模块加载环境变量文件,如下所示: ```typescript import { NestFactory } from '@nestjs/core'; import { ConfigModule } from '@nestjs/config'; import { AppModule } from './app.module'; import config from './env'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); await app.listen(3000); } async function start() { const app = await NestFactory.create(AppModule); app.enableCors(); await app.listen(3000); } async function startWithConfig() { const app = await NestFactory.create(AppModule); app.enableCors(); app.useConfiguredEnvironment(config); // 加载环境变量配置 await app.listen(3000); } start(); // 直接启动应用 // 或者 startWithConfig(); // 加载环境变量配置后启动应用 ``` 上面的代码中,我们定义了三个启动应用的函数 `bootstrap`、`start` 和 `startWithConfig`。其中,`bootstrap` 和 `start` 函数直接启动应用,而 `startWithConfig` 函数先加载环境变量配置,再启动应用。在 `startWithConfig` 函数中,我们通过 `app.useConfiguredEnvironment(config)` 方法加载环境变量配置,该方法会将 `config` 对象中的配置合并到当前的环境变量中。 最后,我们可以在项目根目录下创建 `.env.development`、`.env.production` 和 `.env.test` 等文件,分别存放不同环境下的配置,例如: ``` # .env.development PORT=3000 DB_HOST=localhost DB_PORT=5432 DB_USER=root DB_PASSWORD=123456 DB_NAME=development_db ``` ``` # .env.production PORT=3000 DB_HOST=production_db_host DB_PORT=5432 DB_USER=production_db_user DB_PASSWORD=production_db_password DB_NAME=production_db ``` ``` # .env.test PORT=3000 DB_HOST=test_db_host DB_PORT=5432 DB_USER=test_db_user DB_PASSWORD=test_db_password DB_NAME=test_db ``` 这样,我们就可以在不同的环境中使用不同的配置了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水痕01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值