From 58143555bc525a90615d5af48e0429f5b5432259 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Mon, 9 Apr 2018 13:52:50 -0700 Subject: [PATCH] fix(compiler-cli): strictMetadataEmit should not break on non-compliant libraries (#23275) rxjs 6.0.0 breaks strictMetadataEmit as they now publish a .d.ts file with a structure like: declare export class Subscription { static EMPTY: Subscription; } This generates metadata which contains an error, and fails the strictMetadataEmit validation. There is nothing a library author can do in this situation except to set strictMetadataEmit to false. The spirit of strictMetadataEmit is to validate that the author's library doesn't do anything that will break downstream users. This failure is a corner case which causes more harm than good, so this commit disables validation for metadata collected from .d.ts files. Fixes #22210 PR Close #23275 --- .../src/transformers/metadata_cache.ts | 6 +++-- packages/compiler-cli/test/ngc_spec.ts | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/compiler-cli/src/transformers/metadata_cache.ts b/packages/compiler-cli/src/transformers/metadata_cache.ts index fe6033050f..c8846c39bd 100644 --- a/packages/compiler-cli/src/transformers/metadata_cache.ts +++ b/packages/compiler-cli/src/transformers/metadata_cache.ts @@ -11,6 +11,7 @@ import * as ts from 'typescript'; import {MetadataCollector, MetadataValue, ModuleMetadata} from '../metadata/index'; import {MetadataProvider} from './compiler_host'; +import {TS} from './util'; export type ValueTransform = (value: MetadataValue, node: ts.Node) => MetadataValue; @@ -26,7 +27,7 @@ export class MetadataCache implements MetadataProvider { private metadataCache = new Map(); constructor( - private collector: MetadataCollector, private strict: boolean, + private collector: MetadataCollector, private readonly strict: boolean, private transformers: MetadataTransformer[]) { for (let transformer of transformers) { if (transformer.connect) { @@ -59,7 +60,8 @@ export class MetadataCache implements MetadataProvider { } } - const result = this.collector.getMetadata(sourceFile, this.strict, substitute); + const isTsFile = TS.test(sourceFile.fileName); + const result = this.collector.getMetadata(sourceFile, this.strict && isTsFile, substitute); this.metadataCache.set(sourceFile.fileName, result); return result; } diff --git a/packages/compiler-cli/test/ngc_spec.ts b/packages/compiler-cli/test/ngc_spec.ts index c9add65258..048548cb10 100644 --- a/packages/compiler-cli/test/ngc_spec.ts +++ b/packages/compiler-cli/test/ngc_spec.ts @@ -2420,4 +2420,31 @@ describe('ngc transformer command-line', () => { expect(moduleSource).toMatch(/inject\(i0\.INJECTOR/); }); }); + + it('libraries should not break strictMetadataEmit', () => { + // first only generate .d.ts / .js / .metadata.json files + writeConfig(`{ + "extends": "./tsconfig-base.json", + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true + }, + "compilerOptions": { + "outDir": "lib" + }, + "files": ["main.ts", "test.d.ts"] + }`); + write('main.ts', ` + import {Test} from './test'; + export const bar = Test.bar; + `); + write('test.d.ts', ` + declare export class Test { + static bar: string; + } + `); + let exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], errorSpy); + expect(exitCode).toEqual(0); + }); });