Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 812355c

Browse filesBrowse files
JoostKjosephperrott
authored andcommitted
perf(core): do not recurse into modules that have already been registered (#39514)
When registering an NgModule based on its id, all transitively imported NgModules are also registered. This commit introduces a visited set to avoid traversing into NgModules that are reachable from multiple import paths multiple times. Fixes #39487 PR Close #39514
1 parent 71d0063 commit 812355c
Copy full SHA for 812355c

File tree

Expand file treeCollapse file tree

2 files changed

+24
-16
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+24
-16
lines changed
Open diff view settings
Collapse file

‎packages/core/src/linker/ng_module_factory_registration.ts‎

Copy file name to clipboardExpand all lines: packages/core/src/linker/ng_module_factory_registration.ts
+22-14Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99

1010
import {Type} from '../interface/type';
11-
import {autoRegisterModuleById} from '../render3/definition';
11+
import {autoRegisterModuleById, getNgModuleDef} from '../render3/definition';
1212
import {NgModuleType} from '../render3/ng_module_ref';
13+
import {maybeUnwrapFn} from '../render3/util/misc_utils';
1314
import {stringify} from '../util/stringify';
1415

1516
import {NgModuleFactory} from './ng_module_factory';
@@ -39,20 +40,27 @@ function assertSameOrNotExisting(id: string, type: Type<any>|null, incoming: Typ
3940
}
4041
}
4142

42-
export function registerNgModuleType(ngModuleType: NgModuleType) {
43-
if (ngModuleType.ɵmod.id !== null) {
44-
const id = ngModuleType.ɵmod.id;
45-
const existing = modules.get(id) as NgModuleType | null;
46-
assertSameOrNotExisting(id, existing, ngModuleType);
47-
modules.set(id, ngModuleType);
48-
}
43+
export function registerNgModuleType(ngModuleType: NgModuleType): void {
44+
const visited = new Set<NgModuleType>();
45+
recurse(ngModuleType);
46+
function recurse(ngModuleType: NgModuleType): void {
47+
// The imports array of an NgModule must refer to other NgModules,
48+
// so an error is thrown if no module definition is available.
49+
const def = getNgModuleDef(ngModuleType, /* throwNotFound */ true);
50+
const id = def.id;
51+
if (id !== null) {
52+
const existing = modules.get(id) as NgModuleType | null;
53+
assertSameOrNotExisting(id, existing, ngModuleType);
54+
modules.set(id, ngModuleType);
55+
}
4956

50-
let imports = ngModuleType.ɵmod.imports;
51-
if (imports instanceof Function) {
52-
imports = imports();
53-
}
54-
if (imports) {
55-
imports.forEach(i => registerNgModuleType(i as NgModuleType));
57+
const imports = maybeUnwrapFn(def.imports) as NgModuleType[];
58+
for (const i of imports) {
59+
if (!visited.has(i)) {
60+
visited.add(i);
61+
recurse(i);
62+
}
63+
}
5664
}
5765
}
5866

Collapse file

‎packages/core/test/render3/providers_spec.ts‎

Copy file name to clipboardExpand all lines: packages/core/test/render3/providers_spec.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component as _Component, ComponentFactoryResolver, ElementRef, Injectable as _Injectable, InjectFlags, InjectionToken, InjectorType, Provider, RendererFactory2, Type, ViewContainerRef, ɵNgModuleDef as NgModuleDef, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵinject} from '../../src/core';
9+
import {Component as _Component, ComponentFactoryResolver, ElementRef, Injectable as _Injectable, InjectFlags, InjectionToken, InjectorType, Provider, RendererFactory2, Type, ViewContainerRef, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵinject} from '../../src/core';
1010
import {forwardRef} from '../../src/di/forward_ref';
1111
import {createInjector} from '../../src/di/r3_injector';
1212
import {injectComponentFactoryResolver, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdirectiveInject, ɵɵelement, ɵɵelementEnd, ɵɵelementStart, ɵɵgetInheritedFactory, ɵɵProvidersFeature, ɵɵtext, ɵɵtextInterpolate1} from '../../src/render3/index';
@@ -1092,7 +1092,7 @@ describe('providers', () => {
10921092
{provide: String, useValue: 'From module injector'}
10931093
]
10941094
});
1095-
static ɵmod: NgModuleDef<any> = {bootstrap: []} as any;
1095+
static ɵmod = ɵɵdefineNgModule({type: MyAppModule});
10961096
}
10971097
const myAppModuleFactory = new NgModuleFactory(MyAppModule);
10981098
const ngModuleRef = myAppModuleFactory.create(null);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.