NestJS使用.env和@ nestjs / config设置TypeOrm连接

问题描述

我正在尝试找到使用.env文件设置nestJS数据库的最合法方法。那就是我想使用@nestjs/config包来导入.env变量,并在TypeOrmModule中使用它们。

似乎我需要使用TypeOrmModule.forRootAsync

我正在尝试这样做:

// app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,}),TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService,...
  ],})
export class AppModule {}

然后是TypeOrmConfigService

import { Module } from '@nestjs/common';
import { ConfigModule,ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions,TypeOrmOptionsFactory } from '@nestjs/typeorm';

@Module({
  imports: [ConfigModule],})
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  constructor(private configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'MysqL',host: this.configService.get('DATABASE_HOST'),username: this.configService.get('DATABASE_USERNAME'),password: this.configService.get('DATABASE_PASSWORD'),};
  }
}

最后一个不正确:nest can't resolve dependencies of the TypeOrmConfigService (?). Please make sure that the argument at index [0] is available in the TypeOrmCoreModule context.

如何解决? 或者(最优选)在任何地方都有nestJs + TypeOrm + @ nestjs / config + .env(在回购之外,带有DATABASE_PASSWORD)+ config(我的意思是处理config / development.yml,yml,config / production.yml等)?

似乎我在寻找一个非常标准的东西,你好,这应该是每个nestJS项目的开始,但是我发现将@ nestjs / config和TypeOrm结合起来很困难。

已更新。如果将@Module替换为@Injectable,则错误完全相同:

yarn run v1.22.4
$ NODE_ENV=development nodemon
[nodemon] 1.19.0
[nodemon] to restart at any time,enter `rs`
[nodemon] watching: /home/kasheftin/work/pubngn4/nestjs-course-task-management/src/**/*
[nodemon] starting `ts-node -r tsconfig-paths/register src/main.ts`
[nest] 25384   - 09/01/2020,8:07 PM   [nestFactory] Starting nest application...
[nest] 25384   - 09/01/2020,8:07 PM   [InstanceLoader] AppModule dependencies initialized +11ms
[nest] 25384   - 09/01/2020,8:07 PM   [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[nest] 25384   - 09/01/2020,8:07 PM   [InstanceLoader] PassportModule dependencies initialized +0ms
[nest] 25384   - 09/01/2020,8:07 PM   [ExceptionHandler] nest can't resolve dependencies of the TypeOrmConfigService (?). Please make sure that the argument at index [0] is available in the TypeOrmCoreModule context. +1ms
Error: nest can't resolve dependencies of the TypeOrmConfigService (?). Please make sure that the argument at index [0] is available in the TypeOrmCoreModule context.
    at Injector.lookupComponentInExports (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:180:19)
    at processticksAndRejections (internal/process/task_queues.js:97:5)
    at Injector.resolveComponentInstance (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:143:33)
    at resolveParam (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:96:38)
    at async Promise.all (index 0)
    at Injector.resolveConstructorParams (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:112:27)
    at Injector.loadInstance (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:78:9)
    at Injector.loadProvider (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/injector.js:35:9)
    at async Promise.all (index 3)
    at InstanceLoader.createInstancesOfProviders (/home/kasheftin/work/pubngn4/nestjs-course-task-management/node_modules/@nestjs/core/injector/instance-loader.js:41:9)
 1: 0xa2afd0 node::Abort() [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
 2: 0xa9e7a9  [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
 3: 0xc06bab  [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
 4: 0xc08156  [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
 5: 0xc087d6 v8::internal::Builtin_HandleApiCall(int,unsigned long*,v8::internal::Isolate*) [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
 6: 0x13a9f19  [/home/kasheftin/.nvm/versions/node/v14.3.0/bin/node]
Aborted (core dumped)
[nodemon] app crashed - waiting for file changes before starting...

解决方法

这是我在app.module.ts中使用Postgres的工作脚本,但是对于MySQL来说,它非常相似。有时在重建之前需要手动删除dist文件夹-当数据库无法同步时。

import { ConfigModule,ConfigService } from '@nestjs/config';


@Module({
  imports: [
    ConfigModule.forRoot(),TypeOrmModule.forRootAsync({
      imports: [ConfigModule],useFactory: (configService: ConfigService) => ({
        type: 'postgres' as 'postgres',host: configService.get<string>('DATABASE_HOST'),port: parseInt(configService.get<string>('DATABASE_PORT')),username: configService.get<string>('DATABASE_USER'),password: configService.get<string>('DATABASE_PASS'),database: configService.get<string>('DATABASE_NAME'),entities: [__dirname + '/**/*.entity{.ts,.js}'],synchronize: true,}),inject: [ConfigService],

.env在根文件夹中

DATABASE_USER=
DATABASE_PASS=
DATABASE_HOST=
DATABASE_NAME=
DATABASE_PORT=
,

您可以使用“nestjs-easyconfig”,我将其用于多 .env(例如:.env.development、.env.production',它与 nestjs/config 几乎相同。您可以查看我的 {{3} }

,

您的TypeOrmConfigService不应为@Module()。它应该是@Injectable()。其他一切看起来都很好。

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions,TypeOrmOptionsFactory } from '@nestjs/typeorm';

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  constructor(private configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',host: this.configService.get('DATABASE_HOST'),username: this.configService.get('DATABASE_USERNAME'),password: this.configService.get('DATABASE_PASSWORD'),};
  }
}
,

您可以尝试以下操作:

// app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot(),TypeOrmModule.forRoot({
      type: 'mysql',host: process.env.DATABASE_HOST,username: process.env.DATABASE_USERNAME,password: process.env.DATABASE_PASSWORD,...
  ],})
export class AppModule {}
,

创建一个文件(在本例中为database.provider.ts),该文件将导出连接数组。

import { ConfigModule,ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
export const databaseProviders = [
  TypeOrmModule.forRootAsync({
    imports: [ConfigModule],useFactory: (configService: ConfigService) => ({
      type: 'postgres',host: configService.get('PGHOST'),port: +configService.get<number>('PGPORT'),username: configService.get('PGUSER'),password: configService.get('PGPASSWORD'),database: configService.get('PGDATABASE'),entities: ['dist/**/*.entity{.ts,synchronize: false,logging: true,];

然后将其导入您的database.module.ts

import { databaseProviders } from './database.provider';
import { DatabaseService } from './database.service';
import { Module } from '@nestjs/common';
@Module({
  imports: [...databaseProviders],providers: [DatabaseService],exports: [...databaseProviders],})
export class DatabaseModule {}

仅此而已,如果需要,您可以在database.provider.ts中添加多个连接,也不要忘记创建.env并将数据库模块导入根模块中。

,

不确定它是否仍然有用,但是,我认为这是怎么回事。

看到“ Nest无法解决...”的错误意味着您正在尝试使用依赖项注入来注入类,但是Nest在依赖项容器中找不到此依赖项。

为了解决此问题,您需要将ConfigService(解决依赖项失败)添加到app.module.ts提供程序部分。

类似的东西:

@Module({
   imports: [
        ConfigModule.forRoot(),TypeOrmModule.forRoot({
          type: 'mysql',...
   ],providers: [
        ConfigService
   ]
    
})
export class AppModule {}
,

你可以把它吐到另一个模块 typeorm.module.ts

import { ConfigService } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: async (config: ConfigService) => ({
        database: config.get<string>('DATABASE'),username: config.get<string>('USERNAME'),password: config.get<string>('PASSWORD'),host: config.get<string>('HOST'),port: parseInt(config.get('PORT')),autoLoadEntities: true,type: 'postgres',],controllers: [],providers: [],})
export class TypeormConfigModule {}

主 app.module.ts 像这样导入*

import { TypeormConfigModule } from './config/database/typeorm.module';
import { Module } from '@nestjs/common';
import { ConfigModule,ConfigService } from '@nestjs/config';


@Module({
  imports: [
    CaslModule,TypeormConfigModule,ConfigModule.forRoot({
      envFilePath: ['env/dev.env','env/prod.env','env/rom.env'],isGlobal: true,})
export class AppModule {}


** env 是文件夹名,prod.env 是 env 文件,或者你可以直接把它放在 app.module.ts 上面**

另一种在 APP.MODULES.TS 中直接使用 ENV 的方法

@Module({
  imports: [
    CaslModule,TypeOrmModule.forRootAsync({
      useFactory: async (config: ConfigService) => ({
        database: config.get<string>('DATABASE'),]
}),})
export class AppModule {}
,

在 database.module.ts 上

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule,ConfigService } from '@nestjs/config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],useFactory: (configService: ConfigService) => ({
        type: 'mysql',host: configService.get('DATABASE_HOST'),port: configService.get('DATABASE_PORT'),username: configService.get('DATABASE_USERNAME'),password: configService.get('DATABASE_PASSWORD'),database: configService.get('DATABASE_NAME'),entities: ['dist/**/*.entity.js'],})
export class DatabaseModule {}

在 app.module.ts 上

import { DatabaseModule } from './database/database.module';
import { ConfigModule } from '@nestjs/config';
import { Module } from '@nestjs/common';

@Module({
  imports: [
    ConfigModule.forRoot({}),DatabaseModule,})
export class AppModule {}

这对我有用