refactor(compiler-cli): improve error for imports in non-standalone cmp (#45851)

This commit improves the error message for using `imports` on a component
that isn't set to `standalone: true`. Two concrete improvements are made:

* A related information message is added to the diagnostic which suggests
  the fix of adding `standalone: true`.
* The component is marked as poisoned, preventing other errors which might
  be caused by an incorrectly configured template scope from being generated
  and thus masking the original problem.

Fixes #45850

PR Close #45851
This commit is contained in:
Alex Rickabaugh
2022-05-03 09:11:58 -07:00
committed by Dylan Hunn
parent 9cf14ff03d
commit 8ba4ddcb69
2 changed files with 33 additions and 2 deletions
@@ -10,7 +10,7 @@ import {AnimationTriggerNames, compileClassMetadata, compileComponentFromMetadat
import ts from 'typescript';
import {Cycle, CycleAnalyzer, CycleHandlingStrategy} from '../../../cycles';
import {ErrorCode, FatalDiagnosticError, makeDiagnostic} from '../../../diagnostics';
import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../../diagnostics';
import {absoluteFrom, relative} from '../../../file_system';
import {assertSuccessfulReferenceEmit, ImportedFile, ModuleResolver, Reference, ReferenceEmitter} from '../../../imports';
import {DependencyTracker} from '../../../incremental/api';
@@ -260,7 +260,12 @@ export class ComponentDecoratorHandler implements
}
diagnostics.push(makeDiagnostic(
ErrorCode.COMPONENT_NOT_STANDALONE, component.get('imports')!,
`'imports' is only valid on a component that is standalone.`));
`'imports' is only valid on a component that is standalone.`,
[makeRelatedInformation(
node.name, `Did you forget to add 'standalone: true' to this @Component?`)]));
// Poison the component so that we don't spam further template type-checking errors that
// result from misconfigured imports.
isPoisoned = true;
} else if (component.has('imports')) {
const expr = component.get('imports')!;
const imported = this.evaluator.evaluate(expr);
@@ -353,6 +353,32 @@ runInEachFileSystem(() => {
expect(diags).toContain(`Type 'number' is not assignable to type 'string'.`);
expect(diags).toContain(`Type 'boolean' is not assignable to type 'string'.`);
});
it('should not spam errors if imports is misconfigured', () => {
env.write('test.ts', `
import {Component, Input} from '@angular/core';
@Component({
standalone: true,
selector: 'dep-cmp',
template: '',
})
export class DepCmp {}
@Component({
// missing standalone: true, would ordinarily cause template type-checking errors
// as well as an error about imports on a non-standalone component.
imports: [DepCmp],
selector: 'test-cmp',
template: '<dep-cmp></dep-cmp>',
})
export class TestCmp {}
`);
const diags = env.driveDiagnostics();
expect(diags.length).toBe(1);
expect(diags[0].messageText).toContain('imports');
});
});
describe('NgModule-side', () => {