diff --git a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts index d6e344b5b2..a4f5323755 100644 --- a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts +++ b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts @@ -170,12 +170,13 @@ function getEntryPointPath(entryPoint: EntryPoint): AbsoluteFsPath { const property = properties[i] as EntryPointJsonProperty; const format = getEntryPointFormat(property); - if (format === 'esm2015' || format === 'esm5') { + if (format === 'esm2015' || format === 'esm5' || format === 'umd') { const formatPath = entryPoint.packageJson[property] !; return AbsoluteFsPath.resolve(entryPoint.path, formatPath); } } - throw new Error(`There is no format with import statements in '${entryPoint.path}' entry-point.`); + throw new Error( + `There is no appropriate source code format in '${entryPoint.path}' entry-point.`); } interface DependencyGraph extends DependencyDiagnostics { diff --git a/packages/compiler-cli/ngcc/src/main.ts b/packages/compiler-cli/ngcc/src/main.ts index 4a760b3e63..85d4adbf25 100644 --- a/packages/compiler-cli/ngcc/src/main.ts +++ b/packages/compiler-cli/ngcc/src/main.ts @@ -63,7 +63,7 @@ export interface NgccOptions { pathMappings?: PathMappings; } -const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015']; +const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015', 'umd']; /** * This is the main entry-point into ngcc (aNGular Compatibility Compiler). diff --git a/packages/compiler-cli/ngcc/src/packages/transformer.ts b/packages/compiler-cli/ngcc/src/packages/transformer.ts index 3abc7078a3..a17f017294 100644 --- a/packages/compiler-cli/ngcc/src/packages/transformer.ts +++ b/packages/compiler-cli/ngcc/src/packages/transformer.ts @@ -16,10 +16,12 @@ import {FileSystem} from '../file_system/file_system'; import {Esm2015ReflectionHost} from '../host/esm2015_host'; import {Esm5ReflectionHost} from '../host/esm5_host'; import {NgccReflectionHost} from '../host/ngcc_host'; +import {UmdReflectionHost} from '../host/umd_host'; import {Logger} from '../logging/logger'; import {Esm5Renderer} from '../rendering/esm5_renderer'; import {EsmRenderer} from '../rendering/esm_renderer'; import {FileInfo, Renderer} from '../rendering/renderer'; +import {UmdRenderer} from '../rendering/umd_renderer'; import {EntryPointBundle} from './entry_point_bundle'; @@ -78,6 +80,9 @@ export class Transformer { return new Esm2015ReflectionHost(this.logger, isCore, typeChecker, bundle.dts); case 'esm5': return new Esm5ReflectionHost(this.logger, isCore, typeChecker, bundle.dts); + case 'umd': + return new UmdReflectionHost( + this.logger, isCore, bundle.src.program, bundle.src.host, bundle.dts); default: throw new Error(`Reflection host for "${bundle.format}" not yet implemented.`); } @@ -89,6 +94,11 @@ export class Transformer { return new EsmRenderer(this.fs, this.logger, host, isCore, bundle); case 'esm5': return new Esm5Renderer(this.fs, this.logger, host, isCore, bundle); + case 'umd': + if (!(host instanceof UmdReflectionHost)) { + throw new Error('UmdRenderer requires a UmdReflectionHost'); + } + return new UmdRenderer(this.fs, this.logger, host, isCore, bundle); default: throw new Error(`Renderer for "${bundle.format}" not yet implemented.`); } diff --git a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts index 65e42dcb93..288793fe6c 100644 --- a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts +++ b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts @@ -106,10 +106,10 @@ describe('DependencyResolver', () => { ]); }); - it('should error if the entry point does not have either the esm5 nor esm2015 formats', () => { + it('should error if the entry point does not have a suitable format', () => { expect(() => resolver.sortEntryPointsByDependency([ { path: '/first', packageJson: {}, compiledByAngular: true } as EntryPoint - ])).toThrowError(`There is no format with import statements in '/first' entry-point.`); + ])).toThrowError(`There is no appropriate source code format in '/first' entry-point.`); }); it('should capture any dependencies that were ignored', () => { diff --git a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts index 95e33310f3..b92b7667d0 100644 --- a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts +++ b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts @@ -41,6 +41,7 @@ describe('ngcc main()', () => { describe('with targetEntryPointPath', () => { it('should only compile the given package entry-point (and its dependencies).', () => { const STANDARD_MARKERS = { + main: '0.0.0-PLACEHOLDER', module: '0.0.0-PLACEHOLDER', es2015: '0.0.0-PLACEHOLDER', esm5: '0.0.0-PLACEHOLDER', @@ -162,29 +163,31 @@ describe('ngcc main()', () => { }); - // * the `main` property is UMD, which is not yet supported. - // * none of the ES2015 formats are compiled as they are not on the `propertiesToConsider` - // list. + // The ES2015 formats are not compiled as they are not in `propertiesToConsider`. expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({ esm5: '0.0.0-PLACEHOLDER', + main: '0.0.0-PLACEHOLDER', module: '0.0.0-PLACEHOLDER', fesm5: '0.0.0-PLACEHOLDER', typings: '0.0.0-PLACEHOLDER', }); expect(loadPackage('@angular/common').__processed_by_ivy_ngcc__).toEqual({ esm5: '0.0.0-PLACEHOLDER', + main: '0.0.0-PLACEHOLDER', module: '0.0.0-PLACEHOLDER', fesm5: '0.0.0-PLACEHOLDER', typings: '0.0.0-PLACEHOLDER', }); expect(loadPackage('@angular/common/testing').__processed_by_ivy_ngcc__).toEqual({ esm5: '0.0.0-PLACEHOLDER', + main: '0.0.0-PLACEHOLDER', module: '0.0.0-PLACEHOLDER', fesm5: '0.0.0-PLACEHOLDER', typings: '0.0.0-PLACEHOLDER', }); expect(loadPackage('@angular/common/http').__processed_by_ivy_ngcc__).toEqual({ esm5: '0.0.0-PLACEHOLDER', + main: '0.0.0-PLACEHOLDER', module: '0.0.0-PLACEHOLDER', fesm5: '0.0.0-PLACEHOLDER', typings: '0.0.0-PLACEHOLDER', @@ -196,12 +199,11 @@ describe('ngcc main()', () => { it('should only compile the first matching format', () => { mainNgcc({ basePath: '/node_modules', - propertiesToConsider: ['main', 'module', 'fesm5', 'esm5'], + propertiesToConsider: ['module', 'fesm5', 'esm5'], compileAllFormats: false, logger: new MockLogger(), }); - // * The `main` is UMD, which is not yet supported, and so is not compiled. // * In the Angular packages fesm5 and module have the same underlying format, // so both are marked as compiled. // * The `esm5` is not compiled because we stopped after the `fesm5` format.