feat(compiler): mark @NgModules in provider lists for identification at runtime (#22005)
All of the providers in a module get compiled into a module definition in the factory file. Some of these providers are for the actual module types, as those are available for injection in Angular. For tree-shakeable tokens, the runtime needs to be able to distinguish which modules are present in an injector. This change adds a NodeFlag which tags those module providers for later identification. PR Close #22005
This commit is contained in:

committed by
Miško Hevery

parent
647b8595d0
commit
2d5e7d1b52
@ -321,11 +321,11 @@ export class NgModuleProviderAnalyzer {
|
||||
const ngModuleProvider = {token: {identifier: ngModuleType}, useClass: ngModuleType};
|
||||
_resolveProviders(
|
||||
[ngModuleProvider], ProviderAstType.PublicService, true, sourceSpan, this._errors,
|
||||
this._allProviders);
|
||||
this._allProviders, true);
|
||||
});
|
||||
_resolveProviders(
|
||||
ngModule.transitiveModule.providers.map(entry => entry.provider).concat(extraProviders),
|
||||
ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders);
|
||||
ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders, false);
|
||||
}
|
||||
|
||||
parse(): ProviderAst[] {
|
||||
@ -448,7 +448,7 @@ function _transformProviderAst(
|
||||
{eager, providers}: {eager: boolean, providers: CompileProviderMetadata[]}): ProviderAst {
|
||||
return new ProviderAst(
|
||||
provider.token, provider.multiProvider, provider.eager || eager, providers,
|
||||
provider.providerType, provider.lifecycleHooks, provider.sourceSpan);
|
||||
provider.providerType, provider.lifecycleHooks, provider.sourceSpan, provider.isModule);
|
||||
}
|
||||
|
||||
function _resolveProvidersFromDirectives(
|
||||
@ -461,7 +461,7 @@ function _resolveProvidersFromDirectives(
|
||||
_resolveProviders(
|
||||
[dirProvider],
|
||||
directive.isComponent ? ProviderAstType.Component : ProviderAstType.Directive, true,
|
||||
sourceSpan, targetErrors, providersByToken);
|
||||
sourceSpan, targetErrors, providersByToken, false);
|
||||
});
|
||||
|
||||
// Note: directives need to be able to overwrite providers of a component!
|
||||
@ -470,10 +470,10 @@ function _resolveProvidersFromDirectives(
|
||||
directivesWithComponentFirst.forEach((directive) => {
|
||||
_resolveProviders(
|
||||
directive.providers, ProviderAstType.PublicService, false, sourceSpan, targetErrors,
|
||||
providersByToken);
|
||||
providersByToken, false);
|
||||
_resolveProviders(
|
||||
directive.viewProviders, ProviderAstType.PrivateService, false, sourceSpan, targetErrors,
|
||||
providersByToken);
|
||||
providersByToken, false);
|
||||
});
|
||||
return providersByToken;
|
||||
}
|
||||
@ -481,7 +481,7 @@ function _resolveProvidersFromDirectives(
|
||||
function _resolveProviders(
|
||||
providers: CompileProviderMetadata[], providerType: ProviderAstType, eager: boolean,
|
||||
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
|
||||
targetProvidersByToken: Map<any, ProviderAst>) {
|
||||
targetProvidersByToken: Map<any, ProviderAst>, isModule: boolean) {
|
||||
providers.forEach((provider) => {
|
||||
let resolvedProvider = targetProvidersByToken.get(tokenReference(provider.token));
|
||||
if (resolvedProvider != null && !!resolvedProvider.multiProvider !== !!provider.multi) {
|
||||
@ -497,7 +497,7 @@ function _resolveProviders(
|
||||
const isUseValue = !(provider.useClass || provider.useExisting || provider.useFactory);
|
||||
resolvedProvider = new ProviderAst(
|
||||
provider.token, !!provider.multi, eager || isUseValue, [provider], providerType,
|
||||
lifecycleHooks, sourceSpan);
|
||||
lifecycleHooks, sourceSpan, isModule);
|
||||
targetProvidersByToken.set(tokenReference(provider.token), resolvedProvider);
|
||||
} else {
|
||||
if (!provider.multi) {
|
||||
|
Reference in New Issue
Block a user