Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for DynamicModule in NestFactory.create #671

Closed
ybeauchamph opened this issue May 12, 2018 · 15 comments
Closed

Support for DynamicModule in NestFactory.create #671

ybeauchamph opened this issue May 12, 2018 · 15 comments

Comments

@ybeauchamph
Copy link

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

DynamicModule are not supported by NestFactory create method.

Expected behavior

Support DynamicModule in NestFactory.create

What is the motivation / use case for changing the behavior?

I want to pass a configuration object to my application module and provide it there. I load it in the bootstrap method to get the port from the configuration.

Environment


Nest version: 5.0.0-rc.4

@adrien2p
Copy link

Could you share your code please ?

@ybeauchamph
Copy link
Author

@adrien2p Well, this is related to nestjs/typeorm#24. There is an example there without the config part. Provider only seems to work, but nested dynamic module throw an exception when trying to inject services from them. I looked a bit and the dependency injection wrapper had undefined entries.

@adrien2p
Copy link

Humm i see :)

@j-maas
Copy link
Contributor

j-maas commented Jul 6, 2018

I have this issue as well and played around with it for what will make the following error appear:

[Nest] 5877   - 2018-7-6 16:55:02   [ExceptionHandler] Cannot destructure property `relatedModules` of 'undefined' or 'null'.
TypeError: Cannot destructure property `relatedModules` of 'undefined' or 'null'.
    at flatten (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:161:49)
    at Array.map (<anonymous>)
    at Injector.flatMap (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:169:54)
    at Injector.lookupComponentInRelatedModules (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:136:42)
    at Injector.lookupComponentInExports (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:127:44)
    at scanInExports (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:123:42)
    at Injector.lookupComponent (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:124:68)
    at Injector.resolveComponentInstance (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:113:44)
    at Injector.resolveSingleParam (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:102:27)
    at Promise.all.args.map (/home/y0hy0h/WebstormProjects/nest-typeorm/node_modules/@nestjs/core/injector/injector.js:80:45)
 1: node::Abort() [/home/y0hy0h/.nvm/versions/node/v8.11.1/bin/node]
 2: 0x11e8359 [/home/y0hy0h/.nvm/versions/node/v8.11.1/bin/node]
 3: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/home/y0hy0h/.nvm/versions/node/v8.11.1/bin/node]
 4: 0xb7a9ac [/home/y0hy0h/.nvm/versions/node/v8.11.1/bin/node]
 5: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/home/y0hy0h/.nvm/versions/node/v8.11.1/bin/node]
 6: 0x152434f042fd
[nodemon] app crashed - waiting for file changes before starting...
Aborted (core dumped)

Repro

I've created a repro repo based on the CLI scaffold.

To see the error, just run yarn start:dev.

Basic Setup

What is needed for this error to occur is a dependency between modules, as well as passing a dynamic module to NestFactory.create().

So I created the DependentModule with a service that depends on the LibraryService. Additionally, I loaded DependentModule dynamically inside AppModule.dynamic(), which generates the dynamic module that is finally passed to NestFactory.create().

Observation

First I thought that the import in DependentModule is causing the error. However, it is enough to specify the dependency in the constructor of DependentService (I've added a TODO comment to help you find it). If you (un)comment that import, you control whether the app crashes. (Note that when commented out, the dependency is missing and the app will crash later, namely when the route is invoked.)

Of course, you can also make this work by removing the dynamic module and importing DependentModule statically.

@adrien2p
Copy link

adrien2p commented Jul 6, 2018

Hey !
First, you should import the LibraryModule into your AppModule

@Module({
  providers: [
    AppService,
  ],
  controllers: [
    AppController,
  ],
})
export class AppModule {
  static dynamic(): DynamicModule {
    return {
      module: AppModule,
      imports: [
        LibraryModule,
        DependentModule,
      ],
    };
  }
}

@j-maas
Copy link
Contributor

j-maas commented Jul 6, 2018

@adrien2p It's imported directly in DependentModule. I can make this setup work by simply commenting out one line.

@adrien2p
Copy link

adrien2p commented Jul 6, 2018

Yes, if you comment this line that works because you don't use any thing else from the LibraryModule. But, you have to register all your modules into the main module before to be able to use it anywhere else

@adrien2p
Copy link

adrien2p commented Jul 6, 2018

your issue is not related to this one Support for DynamicModule in NestFactory.create

@j-maas
Copy link
Contributor

j-maas commented Jul 6, 2018

@adrien2p The only thing I have changed in this branch is that instead of using a dynamic module in NestFactory.create(), I declare the imports statically as usual. And the statically imported works fine, even without the change you proposed.

So as far as I can see, my issue is that NestFactory.create() is not working properly with dynamic modules. Did I miss something? 🤔

@adrien2p
Copy link

adrien2p commented Jul 6, 2018

humm, Yes you right i didn't notice that ^^

@adrien2p
Copy link

adrien2p commented Jul 6, 2018

Okay, i think that i know where the problem come from

The method scanner#scanForModules get the related module from the metadata and then call recursively the method on all imported modules. The fact is that the dynamicModule AppModule doesn't have any metadata key when it is dynamic @kamilmysliwiec did you notice that ?
but if both modules are dynamic, that works ...

@BrunnerLivio
Copy link
Member

BrunnerLivio commented Jul 10, 2018

I'm getting the same error when I upgraded from Nest 4.x.x to 5.x.x. Whats the state of this? Is this going to be fixed or is there another way? Angular Universal also does not support dynamic modules while bootstrapping but it provides a way to add providers while bootstrapping:

app.engine('html', ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
        { provide: SOME_TOKEN, useValue: process.env.THING_YOU_CARE_ABOUT },
    ]
}));

With Nest I could imagine something like this:

await NestFactory.create(AppModule, { 
    providers: [
        { provide: SOME_TOKEN, useValue: process.env.THING_YOU_CARE_ABOUT },
    ]
});

Do not care whether dynamic modules are supported or the angular universal approach (prefer dynamic module though).

Because of this error I am not able to upgrade to 5.x.x which is really unfortunate...

@kamilmysliwiec
Copy link
Member

That is not yet supported.

@kamilmysliwiec
Copy link
Member

5.2.0 is here!

@lock
Copy link

lock bot commented Sep 24, 2019

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.

@lock lock bot locked as resolved and limited conversation to collaborators Sep 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants