diff --git a/packages/compiler-cli/ngcc/src/rendering/umd_rendering_formatter.ts b/packages/compiler-cli/ngcc/src/rendering/umd_rendering_formatter.ts index f15e23b581..e34c1c70b8 100644 --- a/packages/compiler-cli/ngcc/src/rendering/umd_rendering_formatter.ts +++ b/packages/compiler-cli/ngcc/src/rendering/umd_rendering_formatter.ts @@ -204,15 +204,21 @@ function isAmdConditional(value: ts.Node): value is AmdConditional { */ function isGlobalFactoryCall(value: ts.Node): value is ts.CallExpression { if (ts.isCallExpression(value) && !!value.parent) { + // Be resilient to the value being part of a comma list + value = isCommaExpression(value.parent) ? value.parent : value; // Be resilient to the value being inside parentheses - const expression = ts.isParenthesizedExpression(value.parent) ? value.parent : value; - return !!expression.parent && ts.isConditionalExpression(expression.parent) && - expression.parent.whenFalse === expression; + value = ts.isParenthesizedExpression(value.parent) ? value.parent : value; + return !!value.parent && ts.isConditionalExpression(value.parent) && + value.parent.whenFalse === value; } else { return false; } } +function isCommaExpression(value: ts.Node): value is ts.BinaryExpression { + return ts.isBinaryExpression(value) && value.operatorToken.kind === ts.SyntaxKind.CommaToken; +} + function getGlobalIdentifier(i: Import) { return i.specifier.replace('@angular/', 'ng.').replace(/^\//, ''); } diff --git a/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts index 3031094985..c67c5d5d7f 100644 --- a/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts @@ -50,10 +50,21 @@ runInEachFileSystem(() => { let _: typeof absoluteFrom; let PROGRAM: TestFile; let PROGRAM_DECORATE_HELPER: TestFile; + let PROGRAM_WITH_GLOBAL_INITIALIZER: TestFile; beforeEach(() => { _ = absoluteFrom; + PROGRAM_WITH_GLOBAL_INITIALIZER = { + name: _('/node_modules/test-package/some/file.js'), + contents: ` + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports,require('some-side-effect'),require('/local-dep'),require('@angular/core')) : + typeof define === 'function' && define.amd ? define('file', ['exports','some-side-effect','/local-dep','@angular/core'], factory) : + (global = global || self, factory(global.file,global.someSideEffect,global.localDep,global.ng.core)); + }(this, (function (exports,someSideEffect,localDep,core) {'use strict'; })));` + }; + PROGRAM = { name: _('/node_modules/test-package/some/file.js'), contents: ` @@ -228,6 +239,22 @@ typeof define === 'function' && define.amd ? define('file', ['exports','/tslib', `(factory(global.file,global.someSideEffect,global.localDep,global.ng.core,global.ng.core,global.ng.common));`); }); + it('should append the given imports into the global initialization, if it has a global/self initializer', + () => { + const {renderer, program} = setup(PROGRAM_WITH_GLOBAL_INITIALIZER); + const file = getSourceFileOrError(program, _('/node_modules/test-package/some/file.js')); + const output = new MagicString(file.text); + renderer.addImports( + output, + [ + {specifier: '@angular/core', qualifier: 'i0'}, + {specifier: '@angular/common', qualifier: 'i1'} + ], + file); + expect(output.toString()) + .toContain( + `(global = global || self, factory(global.file,global.someSideEffect,global.localDep,global.ng.core,global.ng.core,global.ng.common));`); + }); it('should append the given imports as parameters into the factory function definition', () => { const {renderer, program} = setup(PROGRAM);