fix(@ngtools/webpack): remove setClassDebugInfo calls

Angular v17 adds another dev-mode-only function that needs to be removed called `ɵsetClassDebugInfo`. These changes update the Webpack plugin to account for it.
This commit is contained in:
Kristiyan Kostadinov 2023-10-31 11:06:21 +01:00 committed by Alan Agius
parent 260267934a
commit 7a41e8f792
5 changed files with 66 additions and 17 deletions

View File

@ -35,6 +35,8 @@ export interface AngularWebpackPluginOptions {
// (undocumented)
emitNgModuleScope: boolean;
// (undocumented)
emitSetClassDebugInfo?: boolean;
// (undocumented)
fileReplacements: Record<string, string>;
// (undocumented)
inlineStyleFileExtension?: string;

View File

@ -49,6 +49,7 @@ export interface AngularWebpackPluginOptions {
directTemplateLoading: boolean;
emitClassMetadata: boolean;
emitNgModuleScope: boolean;
emitSetClassDebugInfo?: boolean;
jitMode: boolean;
inlineStyleFileExtension?: string;
}

View File

@ -14,7 +14,11 @@ import { replaceResources } from '../transformers/replace_resources';
export function createAotTransformers(
builder: ts.BuilderProgram,
options: { emitClassMetadata?: boolean; emitNgModuleScope?: boolean },
options: {
emitClassMetadata?: boolean;
emitNgModuleScope?: boolean;
emitSetClassDebugInfo?: boolean;
},
imageDomains: Set<string>,
): ts.CustomTransformers {
const getTypeChecker = () => builder.getProgram().getTypeChecker();
@ -25,10 +29,16 @@ export function createAotTransformers(
const removeClassMetadata = !options.emitClassMetadata;
const removeNgModuleScope = !options.emitNgModuleScope;
if (removeClassMetadata || removeNgModuleScope) {
const removeSetClassDebugInfo = !options.emitSetClassDebugInfo;
if (removeClassMetadata || removeNgModuleScope || removeSetClassDebugInfo) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
transformers.before!.push(
removeIvyJitSupportCalls(removeClassMetadata, removeNgModuleScope, getTypeChecker),
removeIvyJitSupportCalls(
removeClassMetadata,
removeNgModuleScope,
removeSetClassDebugInfo,
getTypeChecker,
),
);
}

View File

@ -12,6 +12,7 @@ import { elideImports } from './elide_imports';
export function removeIvyJitSupportCalls(
classMetadata: boolean,
ngModuleScope: boolean,
debugInfo: boolean,
getTypeChecker: () => ts.TypeChecker,
): ts.TransformerFactory<ts.SourceFile> {
return (context: ts.TransformationContext) => {
@ -43,6 +44,16 @@ export function removeIvyJitSupportCalls(
return undefined;
}
}
if (
debugInfo &&
ts.isBinaryExpression(innerExpression) &&
isIvyPrivateCallExpression(innerExpression.right, 'ɵsetClassDebugInfo')
) {
removedNodes.push(innerExpression);
return undefined;
}
}
return ts.visitEachChild(node, visitNode, context);

View File

@ -177,6 +177,16 @@ const inputAsyncArrowFn = tags.stripIndent`
}); })();
`;
const inputDebugInfo = tags.stripIndent`
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class TestCmp {
}
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
TestCmp.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestCmp, selectors: [["test-cmp"]], decls: 0, vars: 0, template: function TestCmp_Template(rf, ctx) { }, encapsulation: 2 });
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestCmp, { className: "TestCmp" }); })();
`;
describe('@ngtools/webpack transformers', () => {
describe('remove-ivy-dev-calls', () => {
it('should allow removing only set class metadata with pure annotation', () => {
@ -194,7 +204,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(input, (getTypeChecker) =>
removeIvyJitSupportCalls(true, false, getTypeChecker),
removeIvyJitSupportCalls(true, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -215,7 +225,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputNoPure, (getTypeChecker) =>
removeIvyJitSupportCalls(true, false, getTypeChecker),
removeIvyJitSupportCalls(true, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -248,7 +258,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(input, (getTypeChecker) =>
removeIvyJitSupportCalls(false, true, getTypeChecker),
removeIvyJitSupportCalls(false, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -281,7 +291,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputNoPure, (getTypeChecker) =>
removeIvyJitSupportCalls(false, true, getTypeChecker),
removeIvyJitSupportCalls(false, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -299,7 +309,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(input, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -317,7 +327,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputNoPure, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -325,7 +335,7 @@ describe('@ngtools/webpack transformers', () => {
it('should allow removing neither set class metadata nor ng module scope with pure annotation', () => {
const result = transform(input, (getTypeChecker) =>
removeIvyJitSupportCalls(false, false, getTypeChecker),
removeIvyJitSupportCalls(false, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${input}`);
@ -333,7 +343,7 @@ describe('@ngtools/webpack transformers', () => {
it('should allow removing neither set class metadata nor ng module scope', () => {
const result = transform(inputNoPure, (getTypeChecker) =>
removeIvyJitSupportCalls(false, false, getTypeChecker),
removeIvyJitSupportCalls(false, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${inputNoPure}`);
@ -364,7 +374,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(imports + input, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -395,7 +405,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(imports + inputNoPure, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -413,7 +423,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputArrowFnWithBody, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -431,7 +441,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputArrowFnWithImplicitReturn, (getTypeChecker) =>
removeIvyJitSupportCalls(true, true, getTypeChecker),
removeIvyJitSupportCalls(true, true, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -446,7 +456,7 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputAsync, (getTypeChecker) =>
removeIvyJitSupportCalls(true, false, getTypeChecker),
removeIvyJitSupportCalls(true, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
@ -461,7 +471,22 @@ describe('@ngtools/webpack transformers', () => {
`;
const result = transform(inputAsyncArrowFn, (getTypeChecker) =>
removeIvyJitSupportCalls(true, false, getTypeChecker),
removeIvyJitSupportCalls(true, false, false, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
});
it('should remove setClassDebugInfo calls', () => {
const output = tags.stripIndent`
import * as i0 from "@angular/core";
export class TestCmp { }
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
TestCmp.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestCmp, selectors: [["test-cmp"]], decls: 0, vars: 0, template: function TestCmp_Template(rf, ctx) { }, encapsulation: 2 });
`;
const result = transform(inputDebugInfo, (getTypeChecker) =>
removeIvyJitSupportCalls(true, false, true, getTypeChecker),
);
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);