diff --git a/packages/angular_devkit/build_optimizer/src/build-optimizer/build-optimizer_spec.ts b/packages/angular_devkit/build_optimizer/src/build-optimizer/build-optimizer_spec.ts index 412fecb0225c..e8e90f6256ea 100644 --- a/packages/angular_devkit/build_optimizer/src/build-optimizer/build-optimizer_spec.ts +++ b/packages/angular_devkit/build_optimizer/src/build-optimizer/build-optimizer_spec.ts @@ -100,7 +100,7 @@ describe('build-optimizer', () => { expect(boOutput.emitSkipped).toEqual(false); }); - it(`doesn't add pure comments to tslib helpers`, () => { + it('should not add pure comments to tslib helpers', () => { const input = tags.stripIndent` class LanguageState { } @@ -138,6 +138,44 @@ describe('build-optimizer', () => { expect(boOutput.emitSkipped).toEqual(false); }); + it('should not add pure comments to tslib helpers with $ and number suffix', () => { + const input = tags.stripIndent` + class LanguageState { + } + + LanguageState.ctorParameters = () => [ + { type: TranslateService }, + { type: undefined, decorators: [{ type: Inject, args: [LANGUAGE_CONFIG,] }] } + ]; + + __decorate$1([ + Action(CheckLanguage), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object]), + __metadata("design:returntype", void 0) + ], LanguageState.prototype, "checkLanguage", null); + `; + + const output = tags.oneLine` + let LanguageState = /*@__PURE__*/ (() => { + class LanguageState { + } + + __decorate$1([ + Action(CheckLanguage), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object]), + __metadata("design:returntype", void 0) + ], LanguageState.prototype, "checkLanguage", null); + return LanguageState; + })(); + `; + + const boOutput = buildOptimizer({ content: input, isSideEffectFree: true }); + expect(tags.oneLine`${boOutput.content}`).toEqual(output); + expect(boOutput.emitSkipped).toEqual(false); + }); + it('should not wrap classes which had all static properties dropped in IIFE', () => { const classDeclaration = tags.oneLine` import { Injectable } from '@angular/core'; diff --git a/packages/angular_devkit/build_optimizer/src/helpers/ast-utils.ts b/packages/angular_devkit/build_optimizer/src/helpers/ast-utils.ts index 296b5d145ba5..d035dda72612 100644 --- a/packages/angular_devkit/build_optimizer/src/helpers/ast-utils.ts +++ b/packages/angular_devkit/build_optimizer/src/helpers/ast-utils.ts @@ -50,3 +50,23 @@ export function hasPureComment(node: ts.Node): boolean { export function isHelperName(name: string): boolean { return tslibHelpers.has(name); } + +/** + * In FESM's when not using `importHelpers` there might be multiple in the same file. + @example + ``` + var __decorate$1 = ''; + var __decorate$2 = ''; + ``` + * @returns Helper name without the '$' and number suffix or `undefined` if it's not a helper. + */ +export function getCleanHelperName(name: string): string | undefined { + const parts = name.split('$'); + const cleanName = parts[0]; + + if (parts.length > 2 || (parts.length === 2 && isNaN(+parts[1]))) { + return undefined; + } + + return isHelperName(cleanName) ? cleanName : undefined; +} diff --git a/packages/angular_devkit/build_optimizer/src/transforms/import-tslib.ts b/packages/angular_devkit/build_optimizer/src/transforms/import-tslib.ts index 27a43e80b5c9..8cb23c73a568 100644 --- a/packages/angular_devkit/build_optimizer/src/transforms/import-tslib.ts +++ b/packages/angular_devkit/build_optimizer/src/transforms/import-tslib.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import * as ts from 'typescript'; -import { isHelperName } from '../helpers/ast-utils'; +import { getCleanHelperName } from '../helpers/ast-utils'; /** * @deprecated From 0.9.0 @@ -35,14 +35,9 @@ export function getImportTslibTransformer(): ts.TransformerFactory { return (context: ts.TransformationContext): ts.Transformer => { @@ -77,7 +77,7 @@ export function findTopLevelFunctions(parentNode: ts.Node): Set { } else if (ts.isCallExpression(innerNode)) { let expression: ts.Expression = innerNode.expression; - if (ts.isIdentifier(expression) && isHelperName(expression.text)) { + if (ts.isIdentifier(expression) && getCleanHelperName(expression.text)) { return; }