fix(ivy): don't generate code for blank NgModule fields (#28387)
Currently `compileNgModule` generates an empty array for optional fields that are omitted from an `NgModule` declaration (e.g. `bootstrap`, `exports`). This isn't necessary, because `defineNgModule` has some code to default these fields to empty arrays at runtime if they aren't defined. The following changes will only output code if there are values for the particular field. PR Close #28387
This commit is contained in:
parent
29513296fb
commit
ebac5dba38
|
@ -275,7 +275,7 @@ describe('ngtsc behavioral tests', () => {
|
||||||
expect(jsContents)
|
expect(jsContents)
|
||||||
.toContain(
|
.toContain(
|
||||||
'i0.ɵdefineNgModule({ type: TestModule, bootstrap: [TestCmp], ' +
|
'i0.ɵdefineNgModule({ type: TestModule, bootstrap: [TestCmp], ' +
|
||||||
'declarations: [TestCmp], imports: [], exports: [] })');
|
'declarations: [TestCmp] })');
|
||||||
|
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents)
|
expect(dtsContents)
|
||||||
|
@ -373,7 +373,7 @@ describe('ngtsc behavioral tests', () => {
|
||||||
env.tsconfig();
|
env.tsconfig();
|
||||||
env.write('test.ts', `
|
env.write('test.ts', `
|
||||||
import {Component, NgModule} from '@angular/core';
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
export class Dep {}
|
export class Dep {}
|
||||||
|
|
||||||
export class Token {
|
export class Token {
|
||||||
|
@ -1562,11 +1562,11 @@ describe('ngtsc behavioral tests', () => {
|
||||||
env.tsconfig();
|
env.tsconfig();
|
||||||
env.write('node_modules/external/index.d.ts', `
|
env.write('node_modules/external/index.d.ts', `
|
||||||
import {ɵDirectiveDefWithMeta, ɵNgModuleDefWithMeta} from '@angular/core';
|
import {ɵDirectiveDefWithMeta, ɵNgModuleDefWithMeta} from '@angular/core';
|
||||||
|
|
||||||
export declare class ExternalDir {
|
export declare class ExternalDir {
|
||||||
static ngDirectiveDef: ɵDirectiveDefWithMeta<ExternalDir, '[test]', never, never, never, never>;
|
static ngDirectiveDef: ɵDirectiveDefWithMeta<ExternalDir, '[test]', never, never, never, never>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare class ExternalModule {
|
export declare class ExternalModule {
|
||||||
static ngModuleDef: ɵNgModuleDefWithMeta<ExternalModule, [typeof ExternalDir], never, [typeof ExternalDir]>;
|
static ngModuleDef: ɵNgModuleDefWithMeta<ExternalModule, [typeof ExternalDir], never, [typeof ExternalDir]>;
|
||||||
}
|
}
|
||||||
|
@ -1574,12 +1574,12 @@ describe('ngtsc behavioral tests', () => {
|
||||||
env.write('test.ts', `
|
env.write('test.ts', `
|
||||||
import {Component, Directive, NgModule} from '@angular/core';
|
import {Component, Directive, NgModule} from '@angular/core';
|
||||||
import {ExternalModule} from 'external';
|
import {ExternalModule} from 'external';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: '<div test></div>',
|
template: '<div test></div>',
|
||||||
})
|
})
|
||||||
class Cmp {}
|
class Cmp {}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Cmp],
|
declarations: [Cmp],
|
||||||
// Multiple imports of the same module used to result in duplicate directive references
|
// Multiple imports of the same module used to result in duplicate directive references
|
||||||
|
|
|
@ -64,14 +64,34 @@ export interface R3NgModuleMetadata {
|
||||||
*/
|
*/
|
||||||
export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef {
|
export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef {
|
||||||
const {type: moduleType, bootstrap, declarations, imports, exports} = meta;
|
const {type: moduleType, bootstrap, declarations, imports, exports} = meta;
|
||||||
const expression = o.importExpr(R3.defineNgModule).callFn([mapToMapExpression({
|
const definitionMap = {
|
||||||
type: moduleType,
|
type: moduleType
|
||||||
bootstrap: o.literalArr(bootstrap.map(ref => ref.value)),
|
} as{
|
||||||
declarations: o.literalArr(declarations.map(ref => ref.value)),
|
type: o.Expression,
|
||||||
imports: o.literalArr(imports.map(ref => ref.value)),
|
bootstrap: o.LiteralArrayExpr,
|
||||||
exports: o.literalArr(exports.map(ref => ref.value)),
|
declarations: o.LiteralArrayExpr,
|
||||||
})]);
|
imports: o.LiteralArrayExpr,
|
||||||
|
exports: o.LiteralArrayExpr
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only generate the keys in the metadata if the arrays have values.
|
||||||
|
if (bootstrap.length) {
|
||||||
|
definitionMap.bootstrap = o.literalArr(bootstrap.map(ref => ref.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declarations.length) {
|
||||||
|
definitionMap.declarations = o.literalArr(declarations.map(ref => ref.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imports.length) {
|
||||||
|
definitionMap.imports = o.literalArr(imports.map(ref => ref.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exports.length) {
|
||||||
|
definitionMap.exports = o.literalArr(exports.map(ref => ref.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const expression = o.importExpr(R3.defineNgModule).callFn([mapToMapExpression(definitionMap)]);
|
||||||
const type = new o.ExpressionType(o.importExpr(R3.NgModuleDefWithMeta, [
|
const type = new o.ExpressionType(o.importExpr(R3.NgModuleDefWithMeta, [
|
||||||
new o.ExpressionType(moduleType), tupleTypeOf(declarations), tupleTypeOf(imports),
|
new o.ExpressionType(moduleType), tupleTypeOf(declarations), tupleTypeOf(imports),
|
||||||
tupleTypeOf(exports)
|
tupleTypeOf(exports)
|
||||||
|
|
Loading…
Reference in New Issue