Уже несколько дней пытаюсь решить проблему с тем, что Nest не видит у меня сервис/модуль, что видно по ошибке ниже, пробовал искать решение, даже спросил ChatGPT и он сказал что все реализовано правильно, вот и решил наконец спросить у вас совета, может кто из вас знает, что мне надо изменить, чтобы заработало и что я делаю не так?
Ошибка:
[Nest] 18316 - 24.04.2023, 15:35:59 ERROR [ExceptionHandler] Nest can't resolve dependencies of the MailService (MailerService, ?). Please make sure that the argument dependency at index [1] is available in the AuthModule context.
Potential solutions:
- Is AuthModule a valid NestJS module?
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
@Module({
imports: [ /* the Module containing dependency */ ]
})
Код модуля авторизации:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { HttpModule } from '@nestjs/axios';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { GoogleStrategy } from './strategy/google.strategy';
import { FacebookStrategy } from './strategy/facebook.strategy';
import googleConfig from '../config/google.config';
import facebookConfig from '../config/facebook.config';
import { MailService } from './mail/mail.service';
import { MailModule } from './mail/mail.module';
import { UsersModule } from '../users/users.module';
import { User } from '../users/entities/user.entity';
import { Profile } from '../users/entities/profile.entity';
@Module({
imports: [
HttpModule,
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('jwt.secretKet'),
signOptions: { expiresIn: configService.get('jwt.expirationTime') },
}),
}),
UsersModule,
ConfigModule.forFeature(googleConfig),
ConfigModule.forFeature(facebookConfig),
TypeOrmModule.forFeature([User, Profile]),
MailModule,
],
controllers: [AuthController],
providers: [
AuthService,
GoogleStrategy,
FacebookStrategy,
MailService,
],
exports: [AuthService],
})
export class AuthModule {}
Код службы авторизации:
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../users/user.service';
import { MailService } from './mail/mail.service';
import { compare } from 'bcrypt';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService,
private readonly mailService: MailService,
) {}
async login(user: any) {
const socialUser = await this.userService.findOrCreateSocialUser(user);
await this.mailService.sendMail({
to: user.email,
subject: 'Verify your email',
template: 'email-verification',
context: {
name: user.name,
},
});
return socialUser;
}
}
Код почтового модуля:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MailerModule, MailerService } from '@nestjs-modules/mailer';
import { MailService } from './mail.service';
import * as handlebars from 'handlebars';
import mailConfig from '../../config/mail.config';
@Module({
imports: [
ConfigModule.forFeature(mailConfig),
MailerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
transport: {
host: configService.get('mail.host'),
port: configService.get('mail.port'),
secure: configService.get('mail.secure') === 'true',
auth: {
user: configService.get('mail.user'),
pass: configService.get('mail.password'),
},
},
defaults: {
from: `"${configService.get('APP_NAME')}" <${configService.get(
'mail.user',
)}>`,
},
template: {
dir: './templates',
adapter: new HandlebarsAdapter(), // lub inny adapter szablonów
options: {
strict: true,
},
},
}),
}),
],
controllers: [],
providers: [MailService, MailerService],
exports: [MailService, MailerService],
})
export class MailModule {}
export class HandlebarsAdapter {
compile(mail: any, callback: any, mailerOptions: any) {
const template = handlebars.compile(mail.data.html);
const html = template(mail.data.context);
mail.data.html = html;
callback();
}
}
Код почтового сервиса:
import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';
import { ConfigType } from '@nestjs/config';
import mailConfig from '../../config/mail.config';
@Injectable()
export class MailService {
constructor(
private readonly mailerService: MailerService,
private mailConf: ConfigType<typeof mailConfig>,
) {}
async sendMail(options: {
to: string;
subject: string;
template: string;
context: Record<string, unknown>;
}) {
const { to, subject, template, context } = options;
const mailOptions = {
to,
subject,
template: `./${template}`,
context,
};
await this.mailerService.sendMail(mailOptions);
}
}
Код конфигурации почты:
import { registerAs } from '@nestjs/config';
export default registerAs('mail', () => ({
host: process.env.mail_host,
port: process.env.mail_port,
secure: process.env.mail_secure,
auth: {
user: process.env.mail_user,
pass: process.env.mail_password,
},
}));
Потому что когда я импортировал, например, User to be visible in Auth, у меня все работало нормально, а когда я хочу импортировать из папки, которая находится в текущей папке, я получаю ошибку и мне кажется, что я все сделал верно.






ConfigType<typeof mailConfig> — это тип, а типы стираются компилятором машинописного текста во время компиляции. Чтобы обойти это ограничение, вы должны использовать декоратор параметров @Inject().
Я думаю, что вы должны сделать это:@Inject(mailConfig.KEY) private mailConf: ConfigService<typeof mailConfig>
как показано в документации здесь: https://docs.nestjs.com/techniques/configuration
это потому, что этот провайдер недоступен для модуля
AuthModule. Я только что увидел, что выMailServiceзарегистрированы вAuthModule. Вам это не нужно, так как вы импортировалиMailModule(который регистрирует и экспортируетMailService). Просто уберитеMailServiceизAuthModuleи все будет хорошо. Довольно простой модульный модуль Nestjs. Ознакомьтесь с документами.