diff --git a/packages/core/injector/lazy-module-loader/lazy-module-loader.ts b/packages/core/injector/lazy-module-loader/lazy-module-loader.ts index df145e05ef4..fd911a5f239 100644 --- a/packages/core/injector/lazy-module-loader/lazy-module-loader.ts +++ b/packages/core/injector/lazy-module-loader/lazy-module-loader.ts @@ -28,6 +28,9 @@ export class LazyModuleLoader { const moduleClassOrDynamicDefinition = await loaderFn(); const moduleInstances = await this.dependenciesScanner.scanForModules( moduleClassOrDynamicDefinition, + [], + [], + true, ); if (moduleInstances.length === 0) { // The module has been loaded already. In this case, we must diff --git a/packages/core/scanner.ts b/packages/core/scanner.ts index 620ea613904..4196ec8ef4b 100644 --- a/packages/core/scanner.ts +++ b/packages/core/scanner.ts @@ -83,55 +83,56 @@ export class DependenciesScanner { } public async scanForModules( - moduleDefinition: + moduleDef: | ForwardReference | Type | DynamicModule | Promise, scope: Type[] = [], ctxRegistry: (ForwardReference | DynamicModule | Type)[] = [], + bindGlobal = false, ): Promise { - const moduleInstance = await this.insertModule(moduleDefinition, scope); - moduleDefinition = - moduleDefinition instanceof Promise - ? await moduleDefinition - : moduleDefinition; - ctxRegistry.push(moduleDefinition); - - if (this.isForwardReference(moduleDefinition)) { - moduleDefinition = (moduleDefinition as ForwardReference).forwardRef(); + const moduleInstance = await this.insertModule(moduleDef, scope); + + if (bindGlobal) { + this.container.bindGlobalsToImports(moduleInstance); } + + ctxRegistry.push(await moduleDef); + + if (this.isForwardReference(await moduleDef)) { + moduleDef = (moduleDef as ForwardReference).forwardRef(); + } + const modules = !this.isDynamicModule( - moduleDefinition as Type | DynamicModule, + moduleDef as Type | DynamicModule, ) - ? this.reflectMetadata( - MODULE_METADATA.IMPORTS, - moduleDefinition as Type, - ) + ? this.reflectMetadata(MODULE_METADATA.IMPORTS, moduleDef as Type) : [ ...this.reflectMetadata( MODULE_METADATA.IMPORTS, - (moduleDefinition as DynamicModule).module, + (moduleDef as DynamicModule).module, ), - ...((moduleDefinition as DynamicModule).imports || []), + ...((moduleDef as DynamicModule).imports || []), ]; let registeredModuleRefs = []; for (const [index, innerModule] of modules.entries()) { // In case of a circular dependency (ES module system), JavaScript will resolve the type to `undefined`. if (innerModule === undefined) { - throw new UndefinedModuleException(moduleDefinition, index, scope); + throw new UndefinedModuleException(moduleDef, index, scope); } if (!innerModule) { - throw new InvalidModuleException(moduleDefinition, index, scope); + throw new InvalidModuleException(moduleDef, index, scope); } if (ctxRegistry.includes(innerModule)) { continue; } const moduleRefs = await this.scanForModules( innerModule, - [].concat(scope, moduleDefinition), + [].concat(scope, moduleDef), ctxRegistry, + bindGlobal, ); registeredModuleRefs = registeredModuleRefs.concat(moduleRefs); } diff --git a/packages/core/test/injector/lazy-module-loader/lazy-module-loader.spec.ts b/packages/core/test/injector/lazy-module-loader/lazy-module-loader.spec.ts index 4f2645272cd..7405b2c0cc6 100644 --- a/packages/core/test/injector/lazy-module-loader/lazy-module-loader.spec.ts +++ b/packages/core/test/injector/lazy-module-loader/lazy-module-loader.spec.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Global, Module } from '@nestjs/common'; import { expect } from 'chai'; import { LazyModuleLoader, @@ -24,6 +24,18 @@ describe('LazyModuleLoader', () => { warn() {} } + @Global() + @Module({ + providers: [ + { + provide: 'GLOBAL', + useValue: 'GLOBAL', + }, + ], + exports: ['GLOBAL'], + }) + class SomeGlobalModule {} + beforeEach(() => { const nestContainer = new NestContainer(); const graphInspector = new GraphInspector(nestContainer); @@ -32,6 +44,7 @@ describe('LazyModuleLoader', () => { new MetadataScanner(), graphInspector, ); + dependenciesScanner.scan(SomeGlobalModule); const injector = new Injector(); instanceLoader = new InstanceLoader( @@ -41,6 +54,7 @@ describe('LazyModuleLoader', () => { new NoopLogger(), ); modulesContainer = nestContainer.getModules(); + lazyModuleLoader = new LazyModuleLoader( dependenciesScanner, instanceLoader, @@ -51,6 +65,18 @@ describe('LazyModuleLoader', () => { describe('load', () => { const bProvider = { provide: 'B', useValue: 'B' }; + @Module({ + providers: [ + { + provide: 'C', + useFactory: (message: string) => message, + inject: ['GLOBAL'], + }, + ], + exports: ['C'], + }) + class ModuleC {} + @Module({ providers: [bProvider], exports: [bProvider] }) class ModuleB {} @@ -76,5 +102,11 @@ describe('LazyModuleLoader', () => { expect(moduleRef).to.equal(moduleRef2); }); }); + describe('when global modules are defined', () => { + it('should providers of global modules are injected', async () => { + const moduleRef = await lazyModuleLoader.load(() => ModuleC); + expect(moduleRef.get('C')).to.be.string('GLOBAL'); + }); + }); }); });