[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Having
/* InvitationsModule
*********************** */
import { Module } from '@nestjs/common';
import { InvitationComposerService, InvitationsService } from './services';
import { DatabaseModule } from '../database';
import { AuthModule } from '../auth';
import { MailModule } from '../mail';
import { invitationModelProvider } from './providers';
@Module({
imports: [
DatabaseModule.forRoot([invitationModelProvider]),
AuthModule,
MailModule,
],
providers: [InvitationsService, InvitationComposerService],
exports: [InvitationsService],
})
export class InvitationsModule {}
/* AuthModule
*********************** */
import { Module } from '@nestjs/common';
import { ExternalAuthModule } from '../external-auth';
import { AuthService, ExternalAuthAdapterService } from './services';
import { AuthController } from './auth.controller';
import { AuthMiddleware } from './auth.middleware';
@Module({
imports: [ExternalAuthModule],
providers: [AuthService, ExternalAuthAdapterService, AuthMiddleware],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
where ExternalAuthModule
and MailModule
have no module imports,
I have this:
which leads to
Error: Nest cannot create the module instance. Often, this is because of a circular dependency between modules. Use forwardRef() to avoid it. (Read more https://docs.nestjs.com/advanced/circular-dependency.) Scope [TestModule -> InvitationsModule -> AuthModule]
It should work
Not sure. We've got nearly 50 modules and all are working fine.
And most of them actually use AuthModule
as you might guess.
Only this one, that I've created recently can't load. Any ideas on what am I doing wrong? :)
Nest version: 5.0.1
Actually, i've got the same is on v4
For Tooling issues:
- Node version: 10.10.0
- Platform: Mac
Others:
I would suggest updating all modules, there are no breaking changes between 5.0.1 and latest version.
@kamilmysliwiec I think, the problem is not there. It is something really weird.
Probably it is not directly related to the NestJS. I'll post it on the TS github.. But maybe somebody here can suggest where to look at...
What I've noticed is that if I debug my code, some ts imports are undefined
..
And what is even more interesting, that in some cases they are undefined, in others - the same imports are defined. 馃槃
let's say I have this:
// accounts/index.ts
export * from './interfaces';
export * from './bindings';
export * from './schemas';
export * from './dto';
export { AccountsModule } from './accounts.module';
export { AccountsService } from './accounts.service';
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database';
import { MailModule } from '../mail';
import { invitationModelProvider } from './providers';
import { AccountsModule } from '../accounts';
console.log(AccountsModule, MailModule);
@Module({
imports: [
DatabaseModule.forRoot([invitationModelProvider]),
AccountsModule,
MailModule,
]
})
export class InvitationsModule {}
it logs
undefined [Function: MailModule]
but if I change it to import { AccountsModule } from '../accounts/accounts.module';
it logs [Function: AccountsModule] [Function: MailModule]
but have similar issues in some AccountsModule
imports.
And I can't see any pattern in the bahaviour. E.g. a test for some module A can be green, but when testing a module B that depends on A, the imported A is undefined.
I'm confused. Not sure where to look at. We didn't change the ts configuration or anything like that. But several days ago it started failing.
Maybe some package dependencies resolved to the later versions and that caused all problems.
Trying to figure out...
You need to wrap the AccountsModule
in the forwardRef
function.
import { Module, forwardRef } from '@nestjs/common';
import { DatabaseModule } from '../database';
import { MailModule } from '../mail';
import { invitationModelProvider } from './providers';
import { AccountsModule } from '../accounts';
@Module({
imports: [
DatabaseModule.forRoot([invitationModelProvider]),
forwardRef(() => AccountsModule), // <-- here
MailModule,
]
})
export class InvitationsModule {}
Circular dependencies are the reason why the imports are undefined
.
if module A
depends on module B
which depends on module A
it'll have a circular dependency.
@marcus-sa
No, there're no circular dependencies.
I know about forwardRef
. It is not the case here.
Please check the prev. comment. The undefined is the ts import, not the NestJS import.
@marcus-sa look,
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database';
import { MailModule } from '../mail';
import { invitationModelProvider } from './providers';
import { AccountsModule } from '../accounts';
console.log(AccountsModule, MailModule);
@Module({
imports: [
DatabaseModule.forRoot([invitationModelProvider]),
AccountsModule,
MailModule,
]
})
export class InvitationsModule {}
See, where the console.log
is?
it has nothing to do with forwardRef
.
It is undefined. Then it goes as undefined to the nest's imports
array.
Then, eventually, Scanner#reflectMetadata()
returns this array with undefined
module (see the screenshot. )
Where am I wrong?
Why did you downvote my prev comment?
@marcus-sa
I've already tried to wrap in forwardRef (just in case if I understand how all the things work terribly wrong) and it ended up with
Cannot destructure property `relatedModules` of 'undefined' or 'null'.
Because the function that was passed to forwardRef
returns undefined
.
Understand?
Maybe you should provide a repository to that we can try to reproduce the error.
For me it seems like the issues are your index.ts
files that exports everything from that specific directory module.
There was a similar issue to this on here, that got fixed by getting rid of one export in some index.ts
that exposes the directory files.
I would suggest updating all modules, there are no breaking changes between 5.0.1 and latest version.
@kamilmysliwiec
tried to update. No difference
Maybe you should provide a repository to that we can try to reproduce the error.
Yep, sure. If I don't find the issue otherwise.
It's the weirdest thing I've ever seen.
I have a common test utils module
// some-path/utils/index.ts
export { createRandomId } from './create-random-id';
export { createUser } from './create-user';
export { createUsers } from './create-users';
export { createAccessToken } from './create-access-token';
export { createDefaultAccessToken } from './create-default-access-token';
export { findAllUsers } from './find-all-users';
export { findOneUser } from './find-one-user';
export { createAccount } from './create-account';
export { inviteUser } from './invite-user';
export { findOneRole } from './find-one-role';
apparently, one of such functions caused this issue.
all find-*
functions look mostly the same
async function findOneInvitation(
fixturesService: MongooseFixturesService,
filters: { _id: string } | { email: string; account: string }
): Promise<Invitation> {
return await fixturesService.findOne(InvitationsBindings.MODEL_NAME, filters);
}
And all works fine until I've added another one.
How is that possible...
Even more interesting, when I just moved the function from the separate file in utils/
dir to the invitation.spec.ts
everything seems to be working fine.
So in the end, nothing has changed... I didn't remove/change the code. I've just moved 2 functions from separate files to the test file body. That's it!
And of course, the imports in the test file changed:
/* <...> */
import {
createAccessToken,
createAccount,
createUser,
// findOneInvitation, <-- was here when I had an exception
// findOneAccount, <-- was here when I had an exception
E2ETestingContainer,
E2ETestingModulesFactory,
findOneRole,
findOneUser,
FixtureLoader,
FixtureLoaderConfig,
JEST_E2E_TIMEOUT,
MongooseFixturesService,
} from '../../testing';
/* <...> */
@kamilmysliwiec
I think we can close the issue if you want.
But if somebody can tell me what the hell is going on here, I'd greatly appreciate that!
For me it seems like the issues are your
index.ts
files that exports everything from that specific directory module.
Why do you think it might be an issue?
I remember in the Angular community it was a common pattern. They called it "barrels".
Seems like a dublicate of #825. I can confirm @alexandr2110pro behavior. I am absolutely clueless why this happens. It only occuree to me inside a Nest application context, which is super strange. I think we should track this issue somewhere and do not close it again. Maybe it is a bug of TypeScript or maybe of Nest. Nonetheless we should track it
I remember in the Angular community it was a common pattern. They called it "barrels".
As far as I know, barrels are no longer recommended due to this issue. It is nothing related to nest itself
and do not close it again
But now it's closed 馃槂
I have changed the issue title to make this thread more descriptive and easier to find by other people. Anyway, I don't think that we have to track this, this error is not related to Nest itself. I would suggest omitting barrel files when it comes to module's providers/module class OR using them very carefully (for example, even if you create a barrel, you shouldn't use it from within the same module itself [only from outside] and when circular dependency may potentially appear).
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I have changed the issue title to make this thread more descriptive and easier to find by other people. Anyway, I don't think that we have to track this, this error is not related to Nest itself. I would suggest omitting barrel files when it comes to module's providers/module class OR using them very carefully (for example, even if you create a barrel, you shouldn't use it from within the same module itself [only from outside] and when circular dependency may potentially appear).