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)) {
|
for (const statement of this.getModuleStatements(sourceFile)) {
|
||||||
if (isUmdExportStatement(statement)) {
|
if (isUmdExportStatement(statement)) {
|
||||||
const declaration = this.extractUmdExportDeclaration(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)) {
|
} else if (isReexportStatement(statement)) {
|
||||||
const reexports = this.extractUmdReexports(statement, sourceFile);
|
const reexports = this.extractUmdReexports(statement, sourceFile);
|
||||||
for (const reexport of reexports) {
|
for (const reexport of reexports) {
|
||||||
|
@ -127,16 +125,22 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
||||||
return moduleMap;
|
return moduleMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private extractUmdExportDeclaration(statement: UmdExportStatement): UmdExportDeclaration|null {
|
private extractUmdExportDeclaration(statement: UmdExportStatement): UmdExportDeclaration {
|
||||||
const exportExpression = statement.expression.right;
|
const exportExpression = statement.expression.right;
|
||||||
const name = statement.expression.left.name.text;
|
|
||||||
|
|
||||||
const declaration = this.getDeclarationOfExpression(exportExpression);
|
const declaration = this.getDeclarationOfExpression(exportExpression);
|
||||||
if (declaration === null) {
|
const name = statement.expression.left.name.text;
|
||||||
return null;
|
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):
|
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 {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||||
import {TestFile, runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
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 {getDeclaration} from '../../../src/ngtsc/testing';
|
||||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||||
import {getIifeBody} from '../../src/host/esm5_host';
|
import {getIifeBody} from '../../src/host/esm5_host';
|
||||||
|
@ -30,6 +30,7 @@ runInEachFileSystem(() => {
|
||||||
let SIMPLE_ES2015_CLASS_FILE: TestFile;
|
let SIMPLE_ES2015_CLASS_FILE: TestFile;
|
||||||
let SIMPLE_CLASS_FILE: TestFile;
|
let SIMPLE_CLASS_FILE: TestFile;
|
||||||
let FOO_FUNCTION_FILE: TestFile;
|
let FOO_FUNCTION_FILE: TestFile;
|
||||||
|
let INLINE_EXPORT_FILE: TestFile;
|
||||||
let INVALID_DECORATORS_FILE: TestFile;
|
let INVALID_DECORATORS_FILE: TestFile;
|
||||||
let INVALID_DECORATOR_ARGS_FILE: TestFile;
|
let INVALID_DECORATOR_ARGS_FILE: TestFile;
|
||||||
let INVALID_PROP_DECORATORS_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 = {
|
INVALID_DECORATORS_FILE = {
|
||||||
name: _('/invalid_decorators.js'),
|
name: _('/invalid_decorators.js'),
|
||||||
contents: `
|
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';`
|
// Currently we do not support UMD versions of `export * from 'x';`
|
||||||
// because it gets compiled to something like:
|
// because it gets compiled to something like:
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue