fix(ivy): in ngcc, handle inline exports in commonjs code (#32129)
One of the compiler's tasks is to enumerate the exports of a given ES module. This can happen for example to resolve `foo.bar` where `foo` is a namespace import: ```typescript import * as foo from './foo'; @NgModule({ directives: [foo.DIRECTIVES], }) ``` In this case, the compiler must enumerate the exports of `foo.ts` in order to evaluate the expression `foo.DIRECTIVES`. When this operation occurs under ngcc, it must deal with the different module formats and types of exports that occur. In commonjs code, a problem arises when certain exports are downleveled. ```typescript export const DIRECTIVES = [ FooDir, BarDir, ]; ``` can be downleveled to: ```javascript exports.DIRECTIVES = [ FooDir, BarDir, ``` Previously, ngtsc and ngcc expected that any export would have an associated `ts.Declaration` node. `export class`, `export function`, etc. all retain `ts.Declaration`s even when downleveled. But the `export const` construct above does not. Therefore, ngcc would not detect `DIRECTIVES` as an export of `foo.ts`, and the evaluation of `foo.DIRECTIVES` would therefore fail. To solve this problem, the core concept of an exported `Declaration` according to the `ReflectionHost` API is split into a `ConcreteDeclaration` which has a `ts.Declaration`, and an `InlineDeclaration` which instead has a `ts.Expression`. Differentiating between these allows ngcc to return an `InlineDeclaration` for `DIRECTIVES` and correctly keep track of this export. PR Close #32129
This commit is contained in:

committed by
Andrew Kushnir

parent
69ce1c2d41
commit
02bab8cf90
@ -9,7 +9,7 @@ import * as ts from 'typescript';
|
||||
|
||||
import {ReferencesRegistry} from '../../../src/ngtsc/annotations';
|
||||
import {Reference} from '../../../src/ngtsc/imports';
|
||||
import {ClassDeclaration, Declaration} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, ConcreteDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {ModuleWithProvidersFunction, NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {hasNameIdentifier, isDefined} from '../utils';
|
||||
|
||||
@ -23,7 +23,7 @@ export interface ModuleWithProvidersInfo {
|
||||
/**
|
||||
* The NgModule class declaration (in the .d.ts file) to add as a type parameter.
|
||||
*/
|
||||
ngModule: Declaration<ClassDeclaration>;
|
||||
ngModule: ConcreteDeclaration<ClassDeclaration>;
|
||||
}
|
||||
|
||||
export type ModuleWithProvidersAnalyses = Map<ts.SourceFile, ModuleWithProvidersInfo[]>;
|
||||
|
Reference in New Issue
Block a user