fix(ngcc): correctly handle inline exports in UMD (#34512)
This fix was part of a broader `ngtsc`/`ngcc` fix in02bab8cf9
(see there for details). In02bab8cf9
, the fix was only applied to `CommonJsReflectionHost`, but it is equally applicable to `UmdReflectionHost`. Later in #34254, the fix was partially ported to `UmdReflectionHost` by fixing the `extractUmdReexports()` method. This commit fully fixes `ngcc`'s handling of inline exports for code in UMD format. PR Close #34512
This commit is contained in:
parent
02e4921ac9
commit
6654f82522
|
@ -114,9 +114,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
|||
for (const statement of this.getModuleStatements(sourceFile)) {
|
||||
if (isUmdExportStatement(statement)) {
|
||||
const declaration = this.extractUmdExportDeclaration(statement);
|
||||
if (declaration !== null) {
|
||||
moduleMap.set(declaration.name, declaration.declaration);
|
||||
}
|
||||
moduleMap.set(declaration.name, declaration.declaration);
|
||||
} else if (isReexportStatement(statement)) {
|
||||
const reexports = this.extractUmdReexports(statement, sourceFile);
|
||||
for (const reexport of reexports) {
|
||||
|
@ -127,16 +125,22 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
|||
return moduleMap;
|
||||
}
|
||||
|
||||
private extractUmdExportDeclaration(statement: UmdExportStatement): UmdExportDeclaration|null {
|
||||
private extractUmdExportDeclaration(statement: UmdExportStatement): UmdExportDeclaration {
|
||||
const exportExpression = statement.expression.right;
|
||||
const name = statement.expression.left.name.text;
|
||||
|
||||
const declaration = this.getDeclarationOfExpression(exportExpression);
|
||||
if (declaration === null) {
|
||||
return null;
|
||||
const name = statement.expression.left.name.text;
|
||||
if (declaration !== null) {
|
||||
return {name, declaration};
|
||||
} else {
|
||||
return {
|
||||
name,
|
||||
declaration: {
|
||||
node: null,
|
||||
expression: exportExpression,
|
||||
viaModule: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {name, declaration};
|
||||
}
|
||||
|
||||
private extractUmdReexports(statement: ReexportStatement, containingFile: ts.SourceFile):
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
|||
|
||||
import {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {TestFile, runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||
import {ClassMemberKind, CtorParameter, Import, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {ClassMemberKind, CtorParameter, Import, InlineDeclaration, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||
import {getIifeBody} from '../../src/host/esm5_host';
|
||||
|
@ -30,6 +30,7 @@ runInEachFileSystem(() => {
|
|||
let SIMPLE_ES2015_CLASS_FILE: TestFile;
|
||||
let SIMPLE_CLASS_FILE: TestFile;
|
||||
let FOO_FUNCTION_FILE: TestFile;
|
||||
let INLINE_EXPORT_FILE: TestFile;
|
||||
let INVALID_DECORATORS_FILE: TestFile;
|
||||
let INVALID_DECORATOR_ARGS_FILE: TestFile;
|
||||
let INVALID_PROP_DECORATORS_FILE: TestFile;
|
||||
|
@ -212,6 +213,23 @@ runInEachFileSystem(() => {
|
|||
})));`,
|
||||
};
|
||||
|
||||
INLINE_EXPORT_FILE = {
|
||||
name: _('/inline_export.js'),
|
||||
contents: `
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core')) :
|
||||
typeof define === 'function' && define.amd ? define('foo_function', ['exports', '@angular/core'], factory) :
|
||||
(factory(global.inline_export,global.ng.core));
|
||||
}(this, (function (exports,core) { 'use strict';
|
||||
function foo() {}
|
||||
foo.decorators = [
|
||||
{ type: core.Directive, args: [{ selector: '[ignored]' },] }
|
||||
];
|
||||
exports.directives = [foo];
|
||||
})));
|
||||
`,
|
||||
};
|
||||
|
||||
INVALID_DECORATORS_FILE = {
|
||||
name: _('/invalid_decorators.js'),
|
||||
contents: `
|
||||
|
@ -1874,6 +1892,20 @@ __export(xtra_module);
|
|||
]);
|
||||
});
|
||||
|
||||
it('should handle inline exports', () => {
|
||||
loadFakeCore(getFileSystem());
|
||||
loadTestFiles([INLINE_EXPORT_FILE]);
|
||||
const bundle = makeTestBundleProgram(INLINE_EXPORT_FILE.name);
|
||||
const host = new UmdReflectionHost(new MockLogger(), false, bundle);
|
||||
const file = getSourceFileOrError(bundle.program, INLINE_EXPORT_FILE.name);
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBe(null);
|
||||
const decl = exportDeclarations !.get('directives') as InlineDeclaration;
|
||||
expect(decl).not.toBeUndefined();
|
||||
expect(decl.node).toBeNull();
|
||||
expect(decl.expression).toBeDefined();
|
||||
});
|
||||
|
||||
// Currently we do not support UMD versions of `export * from 'x';`
|
||||
// because it gets compiled to something like:
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue