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

Kas*_*tin 11 typescript typeorm nestjs dotenv

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

看来我需要使用TypeOrmModule.forRootAsync.

我正在尝试这样做:

// app.module.ts

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

})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

然后,有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'),
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

最后一项是错误的: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、config/ 的 npm 包配置)生产.yml等)?

看来我正在寻找一个非常标准的东西,hello world,它应该是每个 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...
Run Code Online (Sandbox Code Playgroud)

V.T*_*Tur 16

这是我在 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],
    }),
Run Code Online (Sandbox Code Playgroud)

根文件夹中的 .env

DATABASE_USER=
DATABASE_PASS=
DATABASE_HOST=
DATABASE_NAME=
DATABASE_PORT=
Run Code Online (Sandbox Code Playgroud)


小智 11

在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],
      inject: [ConfigService],
      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'],
        synchronize: true,
      }),
    }),
  ],
})
export class DatabaseModule {}
Run Code Online (Sandbox Code Playgroud)

在 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 {}
Run Code Online (Sandbox Code Playgroud)

这对我有用


Siu*_*cio 5

我也遇到了同样的问题,我只是添加以下内容:

import 'dotenv/config';
Run Code Online (Sandbox Code Playgroud)

我的应用程序模块.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { typeOrmConfig } from '../ormconfig';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot(), TypeOrmModule.forRoot(typeOrmConfig)],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Run Code Online (Sandbox Code Playgroud)

我的 ormconfig 看起来像这样:

import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import 'dotenv/config'; // <- this line is the important

const config: TypeOrmModuleOptions = {
  type: 'postgres',
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT),
  username: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
};
export const typeOrmConfig = config;
Run Code Online (Sandbox Code Playgroud)


Jay*_*iel 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'),
    };
  }
}
Run Code Online (Sandbox Code Playgroud)