diff --git a/packages/compiler-cli/ngcc/src/main.ts b/packages/compiler-cli/ngcc/src/main.ts index 0eafd2d247..947dbb6b8b 100644 --- a/packages/compiler-cli/ngcc/src/main.ts +++ b/packages/compiler-cli/ngcc/src/main.ts @@ -12,6 +12,7 @@ import {DepGraph} from 'dependency-graph'; import * as os from 'os'; import * as ts from 'typescript'; +import {replaceTsWithNgInErrors} from '../../src/ngtsc/diagnostics'; import {AbsoluteFsPath, FileSystem, absoluteFrom, dirname, getFileSystem, resolve} from '../../src/ngtsc/file_system'; import {CommonJsDependencyHost} from './dependencies/commonjs_dependency_host'; @@ -262,11 +263,13 @@ export function mainNgcc( const result = transformer.transform(bundle); if (result.success) { if (result.diagnostics.length > 0) { - logger.warn(ts.formatDiagnostics(result.diagnostics, bundle.src.host)); + logger.warn(replaceTsWithNgInErrors( + ts.formatDiagnosticsWithColorAndContext(result.diagnostics, bundle.src.host))); } fileWriter.writeBundle(bundle, result.transformedFiles, formatPropertiesToMarkAsProcessed); } else { - const errors = ts.formatDiagnostics(result.diagnostics, bundle.src.host); + const errors = replaceTsWithNgInErrors( + ts.formatDiagnosticsWithColorAndContext(result.diagnostics, bundle.src.host)); throw new Error( `Failed to compile entry-point ${entryPoint.name} due to compilation errors:\n${errors}`); } diff --git a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts index 0f7496d273..f63bc646ac 100644 --- a/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts +++ b/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts @@ -116,13 +116,13 @@ runInEachFileSystem(() => { compileIntoFlatEs5Package('test-package', { '/index.ts': ` import {Directive, Input, NgModule} from '@angular/core'; - + @Directive({selector: '[foo]'}) export class FooDirective { @Input() get bar() { return 'bar'; } set bar(value: string) {} } - + @NgModule({ declarations: [FooDirective], }) @@ -149,14 +149,14 @@ runInEachFileSystem(() => { compileIntoFlatEs5Package('test-package', { '/index.ts': ` import {Directive, Input, NgModule} from '@angular/core'; - + @Directive({ selector: '[foo]', host: {bar: ''}, }) export class FooDirective { } - + @NgModule({ declarations: [FooDirective], }) @@ -210,7 +210,7 @@ runInEachFileSystem(() => { compileIntoFlatEs5Package('test-package', { '/index.ts': ` import {Injectable, Pipe, PipeTransform} from '@angular/core'; - + @Injectable() @Pipe({ name: 'myTestPipe' @@ -759,13 +759,20 @@ runInEachFileSystem(() => { `, }, ]); - expect(() => mainNgcc({ - basePath: '/node_modules', - targetEntryPointPath: 'fatal-error', - propertiesToConsider: ['es2015'] - })) - .toThrowError( - /^Failed to compile entry-point fatal-error due to compilation errors:\nnode_modules\/fatal-error\/index\.js\(5,17\): error TS-992001: component is missing a template\r?\n$/); + + try { + mainNgcc({ + basePath: '/node_modules', + targetEntryPointPath: 'fatal-error', + propertiesToConsider: ['es2015'] + }); + fail('should have thrown'); + } catch (e) { + expect(e.message).toContain( + 'Failed to compile entry-point fatal-error due to compilation errors:'); + expect(e.message).toContain('NG2001'); + expect(e.message).toContain('component is missing a template'); + } }); }); diff --git a/packages/compiler-cli/src/ngtsc/diagnostics/src/util.ts b/packages/compiler-cli/src/ngtsc/diagnostics/src/util.ts index 413fd4bc03..443ffb7362 100644 --- a/packages/compiler-cli/src/ngtsc/diagnostics/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/diagnostics/src/util.ts @@ -6,10 +6,17 @@ * found in the LICENSE file at https://angular.io/license */ -import * as ts from 'typescript'; - const ERROR_CODE_MATCHER = /(\u001b\[\d+m ?)TS-99(\d+: ?\u001b\[\d+m)/g; +/** + * During formatting of `ts.Diagnostic`s, the numeric code of each diagnostic is prefixed with the + * hard-coded "TS" prefix. For Angular's own error codes, a prefix of "NG" is desirable. To achieve + * this, all Angular error codes start with "-99" so that the sequence "TS-99" can be assumed to + * correspond with an Angular specific error code. This function replaces those occurrences with + * just "NG". + * + * @param errors The formatted diagnostics + */ export function replaceTsWithNgInErrors(errors: string): string { return errors.replace(ERROR_CODE_MATCHER, '$1NG$2'); }